1 //===--- OrcCBindingsStack.h - Orc JIT stack for C bindings ---*- 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 #ifndef LLVM_LIB_EXECUTIONENGINE_ORC_ORCCBINDINGSSTACK_H 11 #define LLVM_LIB_EXECUTIONENGINE_ORC_ORCCBINDINGSSTACK_H 12 13 #include "llvm/ADT/Triple.h" 14 #include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h" 15 #include "llvm/ExecutionEngine/Orc/CompileUtils.h" 16 #include "llvm/ExecutionEngine/Orc/ExecutionUtils.h" 17 #include "llvm/ExecutionEngine/Orc/IRCompileLayer.h" 18 #include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h" 19 #include "llvm/IR/LLVMContext.h" 20 #include "llvm-c/OrcBindings.h" 21 22 namespace llvm { 23 24 class OrcCBindingsStack; 25 26 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(OrcCBindingsStack, LLVMOrcJITStackRef) 27 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef) 28 29 class OrcCBindingsStack { 30 public: 31 32 typedef orc::JITCompileCallbackManager CompileCallbackMgr; 33 typedef orc::ObjectLinkingLayer<> ObjLayerT; 34 typedef orc::IRCompileLayer<ObjLayerT> CompileLayerT; 35 typedef orc::CompileOnDemandLayer<CompileLayerT, CompileCallbackMgr> CODLayerT; 36 37 typedef std::function<std::unique_ptr<CompileCallbackMgr>()> 38 CallbackManagerBuilder; 39 40 typedef CODLayerT::IndirectStubsManagerBuilderT IndirectStubsManagerBuilder; 41 42 private: 43 44 class GenericHandle { 45 public: 46 virtual ~GenericHandle() {} 47 virtual orc::JITSymbol findSymbolIn(const std::string &Name, 48 bool ExportedSymbolsOnly) = 0; 49 virtual void removeModule() = 0; 50 }; 51 52 template <typename LayerT> 53 class GenericHandleImpl : public GenericHandle { 54 public: 55 GenericHandleImpl(LayerT &Layer, typename LayerT::ModuleSetHandleT Handle) 56 : Layer(Layer), Handle(std::move(Handle)) {} 57 58 orc::JITSymbol findSymbolIn(const std::string &Name, 59 bool ExportedSymbolsOnly) override { 60 return Layer.findSymbolIn(Handle, Name, ExportedSymbolsOnly); 61 } 62 63 void removeModule() override { 64 return Layer.removeModuleSet(Handle); 65 } 66 67 private: 68 LayerT &Layer; 69 typename LayerT::ModuleSetHandleT Handle; 70 }; 71 72 template <typename LayerT> 73 std::unique_ptr<GenericHandleImpl<LayerT>> 74 createGenericHandle(LayerT &Layer, typename LayerT::ModuleSetHandleT Handle) { 75 return llvm::make_unique<GenericHandleImpl<LayerT>>(Layer, 76 std::move(Handle)); 77 } 78 79 public: 80 81 // We need a 'ModuleSetHandleT' to conform to the layer concept. 82 typedef unsigned ModuleSetHandleT; 83 84 typedef unsigned ModuleHandleT; 85 86 static std::unique_ptr<CompileCallbackMgr> createCompileCallbackMgr(Triple T); 87 static IndirectStubsManagerBuilder createIndirectStubsMgrBuilder(Triple T); 88 89 OrcCBindingsStack(TargetMachine &TM, 90 std::unique_ptr<CompileCallbackMgr> CCMgr, 91 IndirectStubsManagerBuilder IndirectStubsMgrBuilder) 92 : DL(TM.createDataLayout()), CCMgr(std::move(CCMgr)), 93 ObjectLayer(), 94 CompileLayer(ObjectLayer, orc::SimpleCompiler(TM)), 95 CODLayer(CompileLayer, 96 [](Function &F) { std::set<Function*> S; S.insert(&F); return S; }, 97 *this->CCMgr, std::move(IndirectStubsMgrBuilder), false), 98 IndirectStubsMgr(IndirectStubsMgrBuilder()), 99 CXXRuntimeOverrides([this](const std::string &S) { return mangle(S); }) {} 100 101 ~OrcCBindingsStack() { 102 // Run any destructors registered with __cxa_atexit. 103 CXXRuntimeOverrides.runDestructors(); 104 // Run any IR destructors. 105 for (auto &DtorRunner : IRStaticDestructorRunners) 106 DtorRunner.runViaLayer(*this); 107 } 108 109 std::string mangle(StringRef Name) { 110 std::string MangledName; 111 { 112 raw_string_ostream MangledNameStream(MangledName); 113 Mangler::getNameWithPrefix(MangledNameStream, Name, DL); 114 } 115 return MangledName; 116 } 117 118 template <typename PtrTy> 119 static PtrTy fromTargetAddress(orc::TargetAddress Addr) { 120 return reinterpret_cast<PtrTy>(static_cast<uintptr_t>(Addr)); 121 } 122 123 orc::TargetAddress 124 createLazyCompileCallback(LLVMOrcLazyCompileCallbackFn Callback, 125 void *CallbackCtx) { 126 auto CCInfo = CCMgr->getCompileCallback(); 127 CCInfo.setCompileAction( 128 [=]() -> orc::TargetAddress { 129 return Callback(wrap(this), CallbackCtx); 130 }); 131 return CCInfo.getAddress(); 132 } 133 134 void createIndirectStub(StringRef StubName, orc::TargetAddress Addr) { 135 IndirectStubsMgr->createStub(StubName, Addr, JITSymbolFlags::Exported); 136 } 137 138 void setIndirectStubPointer(StringRef Name, orc::TargetAddress Addr) { 139 IndirectStubsMgr->updatePointer(Name, Addr); 140 } 141 142 std::shared_ptr<RuntimeDyld::SymbolResolver> 143 createResolver(LLVMOrcSymbolResolverFn ExternalResolver, 144 void *ExternalResolverCtx) { 145 auto Resolver = orc::createLambdaResolver( 146 [this, ExternalResolver, ExternalResolverCtx](const std::string &Name) { 147 // Search order: 148 // 1. JIT'd symbols. 149 // 2. Runtime overrides. 150 // 3. External resolver (if present). 151 152 if (auto Sym = CODLayer.findSymbol(Name, true)) 153 return RuntimeDyld::SymbolInfo(Sym.getAddress(), 154 Sym.getFlags()); 155 if (auto Sym = CXXRuntimeOverrides.searchOverrides(Name)) 156 return Sym; 157 158 if (ExternalResolver) 159 return RuntimeDyld::SymbolInfo(ExternalResolver(Name.c_str(), 160 ExternalResolverCtx), 161 llvm::JITSymbolFlags::Exported); 162 163 return RuntimeDyld::SymbolInfo(nullptr); 164 }, 165 [](const std::string &Name) { 166 return RuntimeDyld::SymbolInfo(nullptr); 167 } 168 ); 169 170 return std::shared_ptr<RuntimeDyld::SymbolResolver>(std::move(Resolver)); 171 } 172 173 template <typename LayerT> 174 ModuleHandleT addIRModule(LayerT &Layer, 175 Module *M, 176 std::unique_ptr<RuntimeDyld::MemoryManager> MemMgr, 177 LLVMOrcSymbolResolverFn ExternalResolver, 178 void *ExternalResolverCtx) { 179 180 // Attach a data-layout if one isn't already present. 181 if (M->getDataLayout().isDefault()) 182 M->setDataLayout(DL); 183 184 // Record the static constructors and destructors. We have to do this before 185 // we hand over ownership of the module to the JIT. 186 std::vector<std::string> CtorNames, DtorNames; 187 for (auto Ctor : orc::getConstructors(*M)) 188 CtorNames.push_back(mangle(Ctor.Func->getName())); 189 for (auto Dtor : orc::getDestructors(*M)) 190 DtorNames.push_back(mangle(Dtor.Func->getName())); 191 192 // Create the resolver. 193 auto Resolver = createResolver(ExternalResolver, ExternalResolverCtx); 194 195 // Add the module to the JIT. 196 std::vector<Module*> S; 197 S.push_back(std::move(M)); 198 199 auto LH = Layer.addModuleSet(std::move(S), std::move(MemMgr), 200 std::move(Resolver)); 201 ModuleHandleT H = createHandle(Layer, LH); 202 203 // Run the static constructors, and save the static destructor runner for 204 // execution when the JIT is torn down. 205 orc::CtorDtorRunner<OrcCBindingsStack> CtorRunner(std::move(CtorNames), H); 206 CtorRunner.runViaLayer(*this); 207 208 IRStaticDestructorRunners.emplace_back(std::move(DtorNames), H); 209 210 return H; 211 } 212 213 ModuleHandleT addIRModuleEager(Module* M, 214 LLVMOrcSymbolResolverFn ExternalResolver, 215 void *ExternalResolverCtx) { 216 return addIRModule(CompileLayer, std::move(M), 217 llvm::make_unique<SectionMemoryManager>(), 218 std::move(ExternalResolver), ExternalResolverCtx); 219 } 220 221 ModuleHandleT addIRModuleLazy(Module* M, 222 LLVMOrcSymbolResolverFn ExternalResolver, 223 void *ExternalResolverCtx) { 224 return addIRModule(CODLayer, std::move(M), nullptr, 225 std::move(ExternalResolver), ExternalResolverCtx); 226 } 227 228 void removeModule(ModuleHandleT H) { 229 GenericHandles[H]->removeModule(); 230 GenericHandles[H] = nullptr; 231 FreeHandleIndexes.push_back(H); 232 } 233 234 orc::JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) { 235 if (auto Sym = IndirectStubsMgr->findStub(Name, ExportedSymbolsOnly)) 236 return Sym; 237 return CODLayer.findSymbol(mangle(Name), ExportedSymbolsOnly); 238 } 239 240 orc::JITSymbol findSymbolIn(ModuleHandleT H, const std::string &Name, 241 bool ExportedSymbolsOnly) { 242 return GenericHandles[H]->findSymbolIn(Name, ExportedSymbolsOnly); 243 } 244 245 private: 246 247 template <typename LayerT> 248 unsigned createHandle(LayerT &Layer, 249 typename LayerT::ModuleSetHandleT Handle) { 250 unsigned NewHandle; 251 if (!FreeHandleIndexes.empty()) { 252 NewHandle = FreeHandleIndexes.back(); 253 FreeHandleIndexes.pop_back(); 254 GenericHandles[NewHandle] = createGenericHandle(Layer, std::move(Handle)); 255 return NewHandle; 256 } else { 257 NewHandle = GenericHandles.size(); 258 GenericHandles.push_back(createGenericHandle(Layer, std::move(Handle))); 259 } 260 return NewHandle; 261 } 262 263 DataLayout DL; 264 SectionMemoryManager CCMgrMemMgr; 265 266 std::unique_ptr<CompileCallbackMgr> CCMgr; 267 ObjLayerT ObjectLayer; 268 CompileLayerT CompileLayer; 269 CODLayerT CODLayer; 270 271 std::unique_ptr<orc::IndirectStubsManager> IndirectStubsMgr; 272 273 std::vector<std::unique_ptr<GenericHandle>> GenericHandles; 274 std::vector<unsigned> FreeHandleIndexes; 275 276 orc::LocalCXXRuntimeOverrides CXXRuntimeOverrides; 277 std::vector<orc::CtorDtorRunner<OrcCBindingsStack>> IRStaticDestructorRunners; 278 }; 279 280 } // end namespace llvm 281 282 #endif // LLVM_LIB_EXECUTIONENGINE_ORC_ORCCBINDINGSSTACK_H 283