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 15 #ifndef LLVM_TOOLS_LLI_ORCLAZYJIT_H 16 #define LLVM_TOOLS_LLI_ORCLAZYJIT_H 17 18 #include "llvm/ADT/Triple.h" 19 #include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h" 20 #include "llvm/ExecutionEngine/Orc/CompileUtils.h" 21 #include "llvm/ExecutionEngine/Orc/ExecutionUtils.h" 22 #include "llvm/ExecutionEngine/Orc/IRCompileLayer.h" 23 #include "llvm/ExecutionEngine/Orc/IRTransformLayer.h" 24 #include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h" 25 #include "llvm/ExecutionEngine/RTDyldMemoryManager.h" 26 27 namespace llvm { 28 29 class OrcLazyJIT { 30 public: 31 32 typedef orc::JITCompileCallbackManager CompileCallbackMgr; 33 typedef orc::ObjectLinkingLayer<> ObjLayerT; 34 typedef orc::IRCompileLayer<ObjLayerT> CompileLayerT; 35 typedef std::function<std::unique_ptr<Module>(std::unique_ptr<Module>)> 36 TransformFtor; 37 typedef orc::IRTransformLayer<CompileLayerT, TransformFtor> IRDumpLayerT; 38 typedef orc::CompileOnDemandLayer<IRDumpLayerT, CompileCallbackMgr> CODLayerT; 39 typedef CODLayerT::IndirectStubsManagerBuilderT 40 IndirectStubsManagerBuilder; 41 typedef CODLayerT::ModuleSetHandleT ModuleHandleT; 42 OrcLazyJIT(std::unique_ptr<TargetMachine> TM,std::unique_ptr<CompileCallbackMgr> CCMgr,IndirectStubsManagerBuilder IndirectStubsMgrBuilder,bool InlineStubs)43 OrcLazyJIT(std::unique_ptr<TargetMachine> TM, 44 std::unique_ptr<CompileCallbackMgr> CCMgr, 45 IndirectStubsManagerBuilder IndirectStubsMgrBuilder, 46 bool InlineStubs) 47 : TM(std::move(TM)), DL(this->TM->createDataLayout()), 48 CCMgr(std::move(CCMgr)), 49 ObjectLayer(), 50 CompileLayer(ObjectLayer, orc::SimpleCompiler(*this->TM)), 51 IRDumpLayer(CompileLayer, createDebugDumper()), 52 CODLayer(IRDumpLayer, extractSingleFunction, *this->CCMgr, 53 std::move(IndirectStubsMgrBuilder), InlineStubs), 54 CXXRuntimeOverrides( 55 [this](const std::string &S) { return mangle(S); }) {} 56 ~OrcLazyJIT()57 ~OrcLazyJIT() { 58 // Run any destructors registered with __cxa_atexit. 59 CXXRuntimeOverrides.runDestructors(); 60 // Run any IR destructors. 61 for (auto &DtorRunner : IRStaticDestructorRunners) 62 DtorRunner.runViaLayer(CODLayer); 63 } 64 65 static std::unique_ptr<CompileCallbackMgr> createCompileCallbackMgr(Triple T); 66 static IndirectStubsManagerBuilder createIndirectStubsMgrBuilder(Triple T); 67 addModule(std::unique_ptr<Module> M)68 ModuleHandleT addModule(std::unique_ptr<Module> M) { 69 // Attach a data-layout if one isn't already present. 70 if (M->getDataLayout().isDefault()) 71 M->setDataLayout(DL); 72 73 // Record the static constructors and destructors. We have to do this before 74 // we hand over ownership of the module to the JIT. 75 std::vector<std::string> CtorNames, DtorNames; 76 for (auto Ctor : orc::getConstructors(*M)) 77 CtorNames.push_back(mangle(Ctor.Func->getName())); 78 for (auto Dtor : orc::getDestructors(*M)) 79 DtorNames.push_back(mangle(Dtor.Func->getName())); 80 81 // Symbol resolution order: 82 // 1) Search the JIT symbols. 83 // 2) Check for C++ runtime overrides. 84 // 3) Search the host process (LLI)'s symbol table. 85 std::shared_ptr<RuntimeDyld::SymbolResolver> Resolver = 86 orc::createLambdaResolver( 87 [this](const std::string &Name) { 88 if (auto Sym = CODLayer.findSymbol(Name, true)) 89 return RuntimeDyld::SymbolInfo(Sym.getAddress(), 90 Sym.getFlags()); 91 if (auto Sym = CXXRuntimeOverrides.searchOverrides(Name)) 92 return Sym; 93 94 if (auto Addr = 95 RTDyldMemoryManager::getSymbolAddressInProcess(Name)) 96 return RuntimeDyld::SymbolInfo(Addr, JITSymbolFlags::Exported); 97 98 return RuntimeDyld::SymbolInfo(nullptr); 99 }, 100 [](const std::string &Name) { 101 return RuntimeDyld::SymbolInfo(nullptr); 102 } 103 ); 104 105 // Add the module to the JIT. 106 std::vector<std::unique_ptr<Module>> S; 107 S.push_back(std::move(M)); 108 auto H = CODLayer.addModuleSet(std::move(S), nullptr, std::move(Resolver)); 109 110 // Run the static constructors, and save the static destructor runner for 111 // execution when the JIT is torn down. 112 orc::CtorDtorRunner<CODLayerT> CtorRunner(std::move(CtorNames), H); 113 CtorRunner.runViaLayer(CODLayer); 114 115 IRStaticDestructorRunners.emplace_back(std::move(DtorNames), H); 116 117 return H; 118 } 119 findSymbol(const std::string & Name)120 orc::JITSymbol findSymbol(const std::string &Name) { 121 return CODLayer.findSymbol(mangle(Name), true); 122 } 123 findSymbolIn(ModuleHandleT H,const std::string & Name)124 orc::JITSymbol findSymbolIn(ModuleHandleT H, const std::string &Name) { 125 return CODLayer.findSymbolIn(H, mangle(Name), true); 126 } 127 128 private: 129 mangle(const std::string & Name)130 std::string mangle(const std::string &Name) { 131 std::string MangledName; 132 { 133 raw_string_ostream MangledNameStream(MangledName); 134 Mangler::getNameWithPrefix(MangledNameStream, Name, DL); 135 } 136 return MangledName; 137 } 138 extractSingleFunction(Function & F)139 static std::set<Function*> extractSingleFunction(Function &F) { 140 std::set<Function*> Partition; 141 Partition.insert(&F); 142 return Partition; 143 } 144 145 static TransformFtor createDebugDumper(); 146 147 std::unique_ptr<TargetMachine> TM; 148 DataLayout DL; 149 SectionMemoryManager CCMgrMemMgr; 150 151 std::unique_ptr<CompileCallbackMgr> CCMgr; 152 ObjLayerT ObjectLayer; 153 CompileLayerT CompileLayer; 154 IRDumpLayerT IRDumpLayer; 155 CODLayerT CODLayer; 156 157 orc::LocalCXXRuntimeOverrides CXXRuntimeOverrides; 158 std::vector<orc::CtorDtorRunner<CODLayerT>> IRStaticDestructorRunners; 159 }; 160 161 int runOrcLazyJIT(std::unique_ptr<Module> M, int ArgC, char* ArgV[]); 162 163 } // end namespace llvm 164 165 #endif 166