OrcLazyJIT.h 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. //===--- OrcLazyJIT.h - Basic Orc-based JIT for lazy execution --*- C++ -*-===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // Simple Orc-based JIT. Uses the compile-on-demand layer to break up and
  11. // lazily compile modules.
  12. //
  13. //===----------------------------------------------------------------------===//
  14. #ifndef LLVM_TOOLS_LLI_ORCLAZYJIT_H
  15. #define LLVM_TOOLS_LLI_ORCLAZYJIT_H
  16. #include "llvm/ADT/Triple.h"
  17. #include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h"
  18. #include "llvm/ExecutionEngine/Orc/CompileUtils.h"
  19. #include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
  20. #include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
  21. #include "llvm/ExecutionEngine/Orc/IRTransformLayer.h"
  22. #include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
  23. #include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
  24. #include "llvm/IR/LLVMContext.h"
  25. namespace llvm {
  26. class OrcLazyJIT {
  27. public:
  28. typedef orc::JITCompileCallbackManagerBase CompileCallbackMgr;
  29. typedef orc::ObjectLinkingLayer<> ObjLayerT;
  30. typedef orc::IRCompileLayer<ObjLayerT> CompileLayerT;
  31. typedef std::function<std::unique_ptr<Module>(std::unique_ptr<Module>)>
  32. TransformFtor;
  33. typedef orc::IRTransformLayer<CompileLayerT, TransformFtor> IRDumpLayerT;
  34. typedef orc::CompileOnDemandLayer<IRDumpLayerT, CompileCallbackMgr> CODLayerT;
  35. typedef CODLayerT::ModuleSetHandleT ModuleHandleT;
  36. typedef std::function<
  37. std::unique_ptr<CompileCallbackMgr>(IRDumpLayerT&,
  38. RuntimeDyld::MemoryManager&,
  39. LLVMContext&)>
  40. CallbackManagerBuilder;
  41. static CallbackManagerBuilder createCallbackManagerBuilder(Triple T);
  42. OrcLazyJIT(std::unique_ptr<TargetMachine> TM, LLVMContext &Context,
  43. CallbackManagerBuilder &BuildCallbackMgr)
  44. : TM(std::move(TM)),
  45. ObjectLayer(),
  46. CompileLayer(ObjectLayer, orc::SimpleCompiler(*this->TM)),
  47. IRDumpLayer(CompileLayer, createDebugDumper()),
  48. CCMgr(BuildCallbackMgr(IRDumpLayer, CCMgrMemMgr, Context)),
  49. CODLayer(IRDumpLayer, *CCMgr, false),
  50. CXXRuntimeOverrides([this](const std::string &S) { return mangle(S); }) {}
  51. ~OrcLazyJIT() {
  52. // Run any destructors registered with __cxa_atexit.
  53. CXXRuntimeOverrides.runDestructors();
  54. // Run any IR destructors.
  55. for (auto &DtorRunner : IRStaticDestructorRunners)
  56. DtorRunner.runViaLayer(CODLayer);
  57. }
  58. template <typename PtrTy>
  59. static PtrTy fromTargetAddress(orc::TargetAddress Addr) {
  60. return reinterpret_cast<PtrTy>(static_cast<uintptr_t>(Addr));
  61. }
  62. ModuleHandleT addModule(std::unique_ptr<Module> M) {
  63. // Attach a data-layout if one isn't already present.
  64. if (M->getDataLayout().isDefault())
  65. M->setDataLayout(*TM->getDataLayout());
  66. // Record the static constructors and destructors. We have to do this before
  67. // we hand over ownership of the module to the JIT.
  68. std::vector<std::string> CtorNames, DtorNames;
  69. for (auto Ctor : orc::getConstructors(*M))
  70. CtorNames.push_back(mangle(Ctor.Func->getName()));
  71. for (auto Dtor : orc::getDestructors(*M))
  72. DtorNames.push_back(mangle(Dtor.Func->getName()));
  73. // Symbol resolution order:
  74. // 1) Search the JIT symbols.
  75. // 2) Check for C++ runtime overrides.
  76. // 3) Search the host process (LLI)'s symbol table.
  77. std::shared_ptr<RuntimeDyld::SymbolResolver> Resolver =
  78. orc::createLambdaResolver(
  79. [this](const std::string &Name) {
  80. if (auto Sym = CODLayer.findSymbol(Name, true))
  81. return RuntimeDyld::SymbolInfo(Sym.getAddress(),
  82. Sym.getFlags());
  83. if (auto Sym = CXXRuntimeOverrides.searchOverrides(Name))
  84. return Sym;
  85. if (auto Addr =
  86. RTDyldMemoryManager::getSymbolAddressInProcess(Name))
  87. return RuntimeDyld::SymbolInfo(Addr, JITSymbolFlags::Exported);
  88. return RuntimeDyld::SymbolInfo(nullptr);
  89. },
  90. [](const std::string &Name) {
  91. return RuntimeDyld::SymbolInfo(nullptr);
  92. }
  93. );
  94. // Add the module to the JIT.
  95. std::vector<std::unique_ptr<Module>> S;
  96. S.push_back(std::move(M));
  97. auto H = CODLayer.addModuleSet(std::move(S), nullptr, std::move(Resolver));
  98. // Run the static constructors, and save the static destructor runner for
  99. // execution when the JIT is torn down.
  100. orc::CtorDtorRunner<CODLayerT> CtorRunner(std::move(CtorNames), H);
  101. CtorRunner.runViaLayer(CODLayer);
  102. IRStaticDestructorRunners.emplace_back(std::move(DtorNames), H);
  103. return H;
  104. }
  105. orc::JITSymbol findSymbol(const std::string &Name) {
  106. return CODLayer.findSymbol(mangle(Name), true);
  107. }
  108. orc::JITSymbol findSymbolIn(ModuleHandleT H, const std::string &Name) {
  109. return CODLayer.findSymbolIn(H, mangle(Name), true);
  110. }
  111. private:
  112. std::string mangle(const std::string &Name) {
  113. std::string MangledName;
  114. {
  115. raw_string_ostream MangledNameStream(MangledName);
  116. Mangler::getNameWithPrefix(MangledNameStream, Name, *TM->getDataLayout());
  117. }
  118. return MangledName;
  119. }
  120. static TransformFtor createDebugDumper();
  121. std::unique_ptr<TargetMachine> TM;
  122. SectionMemoryManager CCMgrMemMgr;
  123. ObjLayerT ObjectLayer;
  124. CompileLayerT CompileLayer;
  125. IRDumpLayerT IRDumpLayer;
  126. std::unique_ptr<CompileCallbackMgr> CCMgr;
  127. CODLayerT CODLayer;
  128. orc::LocalCXXRuntimeOverrides CXXRuntimeOverrides;
  129. std::vector<orc::CtorDtorRunner<CODLayerT>> IRStaticDestructorRunners;
  130. };
  131. int runOrcLazyJIT(std::unique_ptr<Module> M, int ArgC, char* ArgV[]);
  132. } // end namespace llvm
  133. #endif