Esempio n. 1
0
static LLVMBool LLVMTargetMachineEmit(LLVMTargetMachineRef T, LLVMModuleRef M,
                                      raw_pwrite_stream &OS,
                                      LLVMCodeGenFileType codegen,
                                      char **ErrorMessage) {
  TargetMachine* TM = unwrap(T);
  Module* Mod = unwrap(M);

  legacy::PassManager pass;

  std::string error;

  Mod->setDataLayout(TM->createDataLayout());

  TargetMachine::CodeGenFileType ft;
  switch (codegen) {
    case LLVMAssemblyFile:
      ft = TargetMachine::CGFT_AssemblyFile;
      break;
    default:
      ft = TargetMachine::CGFT_ObjectFile;
      break;
  }
  if (TM->addPassesToEmitFile(pass, OS, ft)) {
    error = "TargetMachine can't emit a file of this type";
    *ErrorMessage = strdup(error.c_str());
    return true;
  }

  pass.run(*Mod);

  OS.flush();
  return false;
}
Esempio n. 2
0
JuliaOJIT::JuliaOJIT(TargetMachine &TM)
  : TM(TM),
    DL(TM.createDataLayout()),
    ObjStream(ObjBufferSV),
    MemMgr(createRTDyldMemoryManager()),
    registrar(*this),
    ObjectLayer(
#if JL_LLVM_VERSION >= 50000
        [&] { return MemMgr; },
#endif
        std::ref(registrar)
        ),
    CompileLayer(
            ObjectLayer,
            CompilerT(this)
        )
{
    addTargetPasses(&PM, &TM);
    addOptimizationPasses(&PM, jl_generating_output() ? 0 : jl_options.opt_level);
    if (TM.addPassesToEmitMC(PM, Ctx, ObjStream))
        llvm_unreachable("Target does not support MC emission.");

    // Make sure SectionMemoryManager::getSymbolAddressInProcess can resolve
    // symbols in the program as well. The nullptr argument to the function
    // tells DynamicLibrary to load the program, not a library.
    std::string *ErrorStr = nullptr;
    if (sys::DynamicLibrary::LoadLibraryPermanently(nullptr, ErrorStr))
        report_fatal_error("FATAL: unable to dlopen self\n" + *ErrorStr);
}
Esempio n. 3
0
    JuliaOJIT(TargetMachine &TM)
      : TM(TM),
        DL(TM.createDataLayout()),
        ObjStream(ObjBufferSV),
        MemMgr(CUSTOM_MEMORY_MANAGER()),
        ObjectLayer(DebugObjectRegistrar(*this)),
        CompileLayer(
                ObjectLayer,
                [this](Module &M) {
                    PM.run(M);
                    std::unique_ptr<MemoryBuffer> ObjBuffer(
                        new ObjectMemoryBuffer(std::move(ObjBufferSV)));
                    auto Obj = object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef());

                    if (!Obj) {
                        M.dump();
                        llvm::report_fatal_error("FATAL: Unable to compile LLVM Module.\n"
                            "The module's content was printed above. Please file a bug report");
                    }

                    return OwningObj(std::move(*Obj), std::move(ObjBuffer));
                }
            )
        {
            addOptimizationPasses(&PM);
            if (TM.addPassesToEmitMC(PM, Ctx, ObjStream))
                llvm_unreachable("Target does not support MC emission.");

            // Make sure SectionMemoryManager::getSymbolAddressInProcess can resolve
            // symbols in the program as well. The nullptr argument to the function
            // tells DynamicLibrary to load the program, not a library.
            std::string *ErrorStr = nullptr;
            if (sys::DynamicLibrary::LoadLibraryPermanently(nullptr, ErrorStr))
                report_fatal_error("FATAL: unable to dlopen self\n" + *ErrorStr);
        }
Esempio n. 4
0
JuliaOJIT::JuliaOJIT(TargetMachine &TM)
  : TM(TM),
    DL(TM.createDataLayout()),
    ObjStream(ObjBufferSV),
    MemMgr(createRTDyldMemoryManager()),
    ObjectLayer(DebugObjectRegistrar(*this)),
    CompileLayer(
            ObjectLayer,
            [this](Module &M) {
                JL_TIMING(LLVM_OPT);
                PM.run(M);
                std::unique_ptr<MemoryBuffer> ObjBuffer(
                    new ObjectMemoryBuffer(std::move(ObjBufferSV)));
                auto Obj = object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef());

                if (!Obj) {
#if JL_LLVM_VERSION >= 50000
                    M.print(llvm::dbgs(), nullptr, false, true);
#else
                    M.dump();
#endif
#if JL_LLVM_VERSION >= 30900
                    std::string Buf;
                    raw_string_ostream OS(Buf);
                    logAllUnhandledErrors(Obj.takeError(), OS, "");
                    OS.flush();
                    llvm::report_fatal_error("FATAL: Unable to compile LLVM Module: '" + Buf + "'\n"
                        "The module's content was printed above. Please file a bug report");
#else
                    llvm::report_fatal_error("FATAL: Unable to compile LLVM Module.\n"
                        "The module's content was printed above. Please file a bug report");
#endif
                }

                return OwningObj(std::move(*Obj), std::move(ObjBuffer));
            }
        )
{
    if (!jl_generating_output()) {
        addOptimizationPasses(&PM);
    }
    else {
        PM.add(createLowerGCFramePass());
        PM.add(createLowerPTLSPass(imaging_mode));
    }
    if (TM.addPassesToEmitMC(PM, Ctx, ObjStream))
        llvm_unreachable("Target does not support MC emission.");

    // Make sure SectionMemoryManager::getSymbolAddressInProcess can resolve
    // symbols in the program as well. The nullptr argument to the function
    // tells DynamicLibrary to load the program, not a library.
    std::string *ErrorStr = nullptr;
    if (sys::DynamicLibrary::LoadLibraryPermanently(nullptr, ErrorStr))
        report_fatal_error("FATAL: unable to dlopen self\n" + *ErrorStr);
}
Esempio n. 5
0
extern "C" void
LLVMRustSetDataLayoutFromTargetMachine(LLVMModuleRef Module,
                                       LLVMTargetMachineRef TMR) {
    TargetMachine *Target = unwrap(TMR);
#if LLVM_VERSION_MINOR >= 7
    unwrap(Module)->setDataLayout(Target->createDataLayout());
#elif LLVM_VERSION_MINOR >= 6
    if (const DataLayout *DL = Target->getSubtargetImpl()->getDataLayout())
        unwrap(Module)->setDataLayout(DL);
#else
    if (const DataLayout *DL = Target->getDataLayout())
        unwrap(Module)->setDataLayout(DL);
#endif
}
Esempio n. 6
0
ErrorOr<std::unique_ptr<LTOModule>>
LTOModule::makeLTOModule(MemoryBufferRef Buffer, const TargetOptions &options,
                         LLVMContext &Context, bool ShouldBeLazy) {
  ErrorOr<std::unique_ptr<Module>> MOrErr =
      parseBitcodeFileImpl(Buffer, Context, ShouldBeLazy);
  if (std::error_code EC = MOrErr.getError())
    return EC;
  std::unique_ptr<Module> &M = *MOrErr;

  std::string TripleStr = M->getTargetTriple();
  if (TripleStr.empty())
    TripleStr = sys::getDefaultTargetTriple();
  llvm::Triple Triple(TripleStr);

  // find machine architecture for this module
  std::string errMsg;
  const Target *march = TargetRegistry::lookupTarget(TripleStr, errMsg);
  if (!march)
    return std::unique_ptr<LTOModule>(nullptr);

  // construct LTOModule, hand over ownership of module and target
  SubtargetFeatures Features;
  Features.getDefaultSubtargetFeatures(Triple);
  std::string FeatureStr = Features.getString();
  // Set a default CPU for Darwin triples.
  std::string CPU;
  if (Triple.isOSDarwin()) {
    if (Triple.getArch() == llvm::Triple::x86_64)
      CPU = "core2";
    else if (Triple.getArch() == llvm::Triple::x86)
      CPU = "yonah";
    else if (Triple.getArch() == llvm::Triple::aarch64)
      CPU = "cyclone";
  }

  TargetMachine *target =
      march->createTargetMachine(TripleStr, CPU, FeatureStr, options, None);
  M->setDataLayout(target->createDataLayout());

  std::unique_ptr<LTOModule> Ret(new LTOModule(std::move(M), Buffer, target));
  Ret->parseSymbols();
  Ret->parseMetadata();

  return std::move(Ret);
}
Esempio n. 7
0
static void runLTOPasses(Module &M, TargetMachine &TM) {
  M.setDataLayout(TM.createDataLayout());

  legacy::PassManager passes;
  passes.add(createTargetTransformInfoWrapperPass(TM.getTargetIRAnalysis()));

  PassManagerBuilder PMB;
  PMB.LibraryInfo = new TargetLibraryInfoImpl(Triple(TM.getTargetTriple()));
  PMB.Inliner = createFunctionInliningPass();
  // Unconditionally verify input since it is not verified before this
  // point and has unknown origin.
  PMB.VerifyInput = true;
  PMB.VerifyOutput = !options::DisableVerify;
  PMB.LoopVectorize = true;
  PMB.SLPVectorize = true;
  PMB.OptLevel = options::OptLevel;
  PMB.populateLTOPassManager(passes);
  passes.run(M);
}
Esempio n. 8
0
std::unique_ptr<llvm::SmallVectorImpl<char>>
getBPFObjectFromModule(llvm::Module *Module)
{
	using namespace llvm;

	std::string TargetTriple("bpf-pc-linux");
	std::string Error;
	const Target* Target = TargetRegistry::lookupTarget(TargetTriple, Error);
	if (!Target) {
		llvm::errs() << Error;
		return std::unique_ptr<llvm::SmallVectorImpl<char>>(nullptr);
	}

	llvm::TargetOptions Opt;
	TargetMachine *TargetMachine =
		Target->createTargetMachine(TargetTriple,
					    "generic", "",
					    Opt, Reloc::Static);

	Module->setDataLayout(TargetMachine->createDataLayout());
	Module->setTargetTriple(TargetTriple);

	std::unique_ptr<SmallVectorImpl<char>> Buffer(new SmallVector<char, 0>());
	raw_svector_ostream ostream(*Buffer);

	legacy::PassManager PM;
	bool NotAdded;
#if CLANG_VERSION_MAJOR < 7
	NotAdded = TargetMachine->addPassesToEmitFile(PM, ostream,
						      TargetMachine::CGFT_ObjectFile);
#else
	NotAdded = TargetMachine->addPassesToEmitFile(PM, ostream, nullptr,
						      TargetMachine::CGFT_ObjectFile);
#endif
	if (NotAdded) {
		llvm::errs() << "TargetMachine can't emit a file of this type\n";
		return std::unique_ptr<llvm::SmallVectorImpl<char>>(nullptr);
	}
	PM.run(*Module);

	return Buffer;
}
void llvm::computeSignatureVTs(const FunctionType *Ty, const Function &F,
                               const TargetMachine &TM,
                               SmallVectorImpl<MVT> &Params,
                               SmallVectorImpl<MVT> &Results) {
  computeLegalValueVTs(F, TM, Ty->getReturnType(), Results);

  MVT PtrVT = MVT::getIntegerVT(TM.createDataLayout().getPointerSizeInBits());
  if (Results.size() > 1) {
    // WebAssembly currently can't lower returns of multiple values without
    // demoting to sret (see WebAssemblyTargetLowering::CanLowerReturn). So
    // replace multiple return values with a pointer parameter.
    Results.clear();
    Params.push_back(PtrVT);
  }

  for (auto *Param : Ty->params())
    computeLegalValueVTs(F, TM, Param, Params);
  if (Ty->isVarArg())
    Params.push_back(PtrVT);
}
Esempio n. 10
0
// This is the method invoked by the EE to Jit code.
CorJitResult LLILCJit::compileMethod(ICorJitInfo *JitInfo,
                                     CORINFO_METHOD_INFO *MethodInfo,
                                     UINT Flags, BYTE **NativeEntry,
                                     ULONG *NativeSizeOfCode) {

  // Bail if input is malformed
  if (nullptr == JitInfo || nullptr == MethodInfo || nullptr == NativeEntry ||
      nullptr == NativeSizeOfCode) {
    return CORJIT_INTERNALERROR;
  }

  // Prep main outputs
  *NativeEntry = nullptr;
  *NativeSizeOfCode = 0;

  // Set up state for this thread (if necessary)
  LLILCJitPerThreadState *PerThreadState = State.get();
  if (PerThreadState == nullptr) {
    PerThreadState = new LLILCJitPerThreadState();
    State.set(PerThreadState);
  }

  // Set up context for this Jit request
  LLILCJitContext Context(PerThreadState);

  // Fill in context information from the CLR
  Context.JitInfo = JitInfo;
  Context.MethodInfo = MethodInfo;
  Context.Flags = Flags;
  JitInfo->getEEInfo(&Context.EEInfo);

  // Fill in context information from LLVM
  Context.LLVMContext = &PerThreadState->LLVMContext;
  std::unique_ptr<Module> M = Context.getModuleForMethod(MethodInfo);
  Context.CurrentModule = M.get();
  Context.CurrentModule->setTargetTriple(LLILC_TARGET_TRIPLE);
  Context.CurrentModule->addModuleFlag(Module::Warning, "Debug Info Version",
                                       DEBUG_METADATA_VERSION);
  Context.MethodName = Context.CurrentModule->getModuleIdentifier();
  Context.TheABIInfo = ABIInfo::get(*Context.CurrentModule);
  Context.GcInfo = new GcInfo();

  // Initialize per invocation JIT options. This should be done after the
  // rest of the Context is filled out as it has dependencies on JitInfo,
  // Flags and MethodInfo.
  JitOptions JitOptions(Context);

  if (JitOptions.IsBreakMethod) {
    dbgs() << "INFO:  Breaking for method " << Context.MethodName << "\n";
  }
  if (JitOptions.IsMSILDumpMethod) {
    dbgs() << "INFO:  Dumping MSIL for method " << Context.MethodName << "\n";
    ReaderBase::printMSIL(MethodInfo->ILCode, 0, MethodInfo->ILCodeSize);
  }
  CorJitResult Result = CORJIT_INTERNALERROR;
  if (JitOptions.IsAltJit && !JitOptions.IsExcludeMethod) {
    Context.Options = &JitOptions;

    // Construct the TargetMachine that we will emit code for
    std::string ErrStr;
    const llvm::Target *TheTarget =
        TargetRegistry::lookupTarget(LLILC_TARGET_TRIPLE, ErrStr);
    if (!TheTarget) {
      errs() << "Could not create Target: " << ErrStr << "\n";
      return CORJIT_INTERNALERROR;
    }
    TargetOptions Options;
    CodeGenOpt::Level OptLevel;
    bool IsNgen = Context.Flags & CORJIT_FLG_PREJIT;
    bool IsReadyToRun = Context.Flags & CORJIT_FLG_READYTORUN;

    // Optimal code for ReadyToRun should have all calls in call [rel32] form to
    // enable crossgen to use shared delay-load thunks. We can't guarantee that
    // LLVM will always generate this form so we currently don't take advantage
    // of that and use non-shared delay-load thunks. The plan is to have as many
    // calls as possible in that form and use shared delay-load thunks when
    // possible. Setting OptLevel to Default increases the chances of calls via
    // memory and setting CodeModel to Default enables rel32 relocations.
    if ((Context.Options->EnableOptimization) || IsNgen || IsReadyToRun) {
      OptLevel = CodeGenOpt::Level::Default;
    } else {
      OptLevel = CodeGenOpt::Level::None;
      // Options.NoFramePointerElim = true;
    }
    llvm::CodeModel::Model CodeModel =
        (IsNgen || IsReadyToRun) ? CodeModel::Default : CodeModel::JITDefault;
    TargetMachine *TM =
        TheTarget->createTargetMachine(LLILC_TARGET_TRIPLE, "", "", Options,
                                       Reloc::Default, CodeModel, OptLevel);
    Context.TM = TM;

    // Set target machine datalayout on the method module.
    Context.CurrentModule->setDataLayout(TM->createDataLayout());

    // Construct the jitting layers.
    EEMemoryManager MM(&Context);
    ObjectLoadListener Listener(&Context);
    orc::EEObjectLinkingLayer<decltype(Listener)> Loader(Listener);
    auto ReserveUnwindSpace = [&MM](std::unique_ptr<object::ObjectFile> Obj) {
      MM.reserveUnwindSpace(*Obj);
      return std::move(Obj);
    };
    orc::ObjectTransformLayer<decltype(Loader), decltype(ReserveUnwindSpace)>
        UnwindReserver(Loader, ReserveUnwindSpace);
    orc::IRCompileLayer<decltype(UnwindReserver)> Compiler(
        UnwindReserver, orc::LLILCCompiler(*TM));

    // Now jit the method.
    if (Context.Options->DumpLevel == DumpLevel::VERBOSE) {
      dbgs() << "INFO:  jitting method " << Context.MethodName
             << " using LLILCJit\n";
    }
    bool HasMethod = this->readMethod(&Context);

#ifndef FEATURE_VERIFICATION
    bool IsImportOnly = (Context.Flags & CORJIT_FLG_IMPORT_ONLY) != 0;
    // If asked to verify, report that it is verifiable.
    if (IsImportOnly) {
      Result = CORJIT_OK;

      CorInfoMethodRuntimeFlags verFlag;
      verFlag = CORINFO_FLG_VERIFIABLE;

      JitInfo->setMethodAttribs(MethodInfo->ftn, verFlag);

      return Result;
    }
#endif

    if (HasMethod) {
      if (JitOptions.IsLLVMDumpMethod) {
        dbgs() << "INFO:  Dumping LLVM for method " << Context.MethodName
               << "\n";
        Context.CurrentModule->dump();
      }
      if (Context.Options->DoInsertStatepoints) {
        // If using Precise GC, run the GC-Safepoint insertion
        // and lowering passes before generating code.
        legacy::PassManager Passes;
        Passes.add(createPlaceSafepointsPass());
        Passes.add(createRewriteStatepointsForGCPass());
        Passes.run(*M);
      }

      // Use a custom resolver that will tell the dynamic linker to skip
      // relocation processing for external symbols that we create. We will
      // report relocations for those symbols via Jit interface's
      // recordRelocation method.
      EESymbolResolver Resolver(&Context.NameToHandleMap);
      auto HandleSet =
          Compiler.addModuleSet<ArrayRef<Module *>>(M.get(), &MM, &Resolver);

      *NativeEntry =
          (BYTE *)Compiler.findSymbol(Context.MethodName, false).getAddress();

      // TODO: ColdCodeSize, or separated code, is not enabled or included.
      *NativeSizeOfCode = Context.HotCodeSize + Context.ReadOnlyDataSize;
      if (JitOptions.IsCodeRangeMethod) {
        errs() << "LLILC compiled: "
               << ", Entry = " << *NativeEntry
               << ", End = " << (*NativeEntry + *NativeSizeOfCode)
               << ", size = " << *NativeSizeOfCode
               << " method = " << Context.MethodName << '\n';
      }

      // The Method Jitted must begin at the start of the allocated
      // Code block. The EE's DebugInfoManager relies on this.
      // It allocates a CoreHeader block immediately before the
      // code block address returned, and expects to find it
      // at a fixed offset from *NativeEntry.
      assert(*NativeEntry == MM.getHotCodeBlock() &&
             "Expect the JITted method at the beginning of the code block");
      GcInfoAllocator GcInfoAllocator;
      GcInfoEmitter GcInfoEmitter(&Context, MM.getStackMapSection(),
                                  &GcInfoAllocator);
      GcInfoEmitter.emitGCInfo();

      // Dump out any enabled timing info.
      TimerGroup::printAll(errs());

      // Give the jit layers a chance to free resources.
      Compiler.removeModuleSet(HandleSet);

      // Tell the CLR that we've successfully generated code for this method.
      Result = CORJIT_OK;
    }

    // Clean up a bit
    delete Context.TM;
    Context.TM = nullptr;
  } else {
    // This method was not selected for jitting by LLILC.
    if (JitOptions.DumpLevel == DumpLevel::SUMMARY) {
      dbgs() << "INFO:  skipping jitting method " << Context.MethodName
             << " using LLILCJit\n";
    }
  }

  // Clean up a bit more
  delete Context.TheABIInfo;
  delete Context.GcInfo;
  Context.TheABIInfo = nullptr;
  Context.GcInfo = nullptr;

  return Result;
}
Esempio n. 11
0
extern "C" void
LLVMRustSetDataLayoutFromTargetMachine(LLVMModuleRef Module,
                                       LLVMTargetMachineRef TMR) {
    TargetMachine *Target = unwrap(TMR);
    unwrap(Module)->setDataLayout(Target->createDataLayout());
}
Esempio n. 12
0
ErrorOr<std::unique_ptr<LTOModule>>
LTOModule::makeLTOModule(MemoryBufferRef Buffer, TargetOptions options,
                         LLVMContext *Context) {
  std::unique_ptr<LLVMContext> OwnedContext;
  if (!Context) {
    OwnedContext = llvm::make_unique<LLVMContext>();
    Context = OwnedContext.get();
  }

  // If we own a context, we know this is being used only for symbol
  // extraction, not linking.  Be lazy in that case.
  ErrorOr<std::unique_ptr<Module>> MOrErr =
      parseBitcodeFileImpl(Buffer, *Context,
                           /* ShouldBeLazy */ static_cast<bool>(OwnedContext));
  if (std::error_code EC = MOrErr.getError())
    return EC;
  std::unique_ptr<Module> &M = *MOrErr;

  std::string TripleStr = M->getTargetTriple();
  if (TripleStr.empty())
    TripleStr = sys::getDefaultTargetTriple();
  llvm::Triple Triple(TripleStr);

  // find machine architecture for this module
  std::string errMsg;
  const Target *march = TargetRegistry::lookupTarget(TripleStr, errMsg);
  if (!march)
    return std::unique_ptr<LTOModule>(nullptr);

  // construct LTOModule, hand over ownership of module and target
  SubtargetFeatures Features;
  Features.getDefaultSubtargetFeatures(Triple);
  std::string FeatureStr = Features.getString();
  // Set a default CPU for Darwin triples.
  std::string CPU;
  if (Triple.isOSDarwin()) {
    if (Triple.getArch() == llvm::Triple::x86_64)
      CPU = "core2";
    else if (Triple.getArch() == llvm::Triple::x86)
      CPU = "yonah";
    else if (Triple.getArch() == llvm::Triple::aarch64)
      CPU = "cyclone";
  }

  TargetMachine *target = march->createTargetMachine(TripleStr, CPU, FeatureStr,
                                                     options);
  M->setDataLayout(target->createDataLayout());

  std::unique_ptr<object::IRObjectFile> IRObj(
      new object::IRObjectFile(Buffer, std::move(M)));

  std::unique_ptr<LTOModule> Ret;
  if (OwnedContext)
    Ret.reset(new LTOModule(std::move(IRObj), target, std::move(OwnedContext)));
  else
    Ret.reset(new LTOModule(std::move(IRObj), target));

  Ret->parseSymbols();
  Ret->parseMetadata();

  return std::move(Ret);
}