1 //===--- OrcCBindingsStack.h - Orc JIT stack for C bindings ---*- C++ -*---===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #ifndef LLVM_LIB_EXECUTIONENGINE_ORC_ORCCBINDINGSSTACK_H
11 #define LLVM_LIB_EXECUTIONENGINE_ORC_ORCCBINDINGSSTACK_H
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"
24 class OrcCBindingsStack;
26 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(OrcCBindingsStack, LLVMOrcJITStackRef)
27 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef)
29 class OrcCBindingsStack {
32 typedef orc::JITCompileCallbackManagerBase CompileCallbackMgr;
33 typedef orc::ObjectLinkingLayer<> ObjLayerT;
34 typedef orc::IRCompileLayer<ObjLayerT> CompileLayerT;
35 typedef orc::CompileOnDemandLayer<CompileLayerT, CompileCallbackMgr> CODLayerT;
37 typedef std::function<
38 std::unique_ptr<CompileCallbackMgr>(CompileLayerT&,
39 RuntimeDyld::MemoryManager&,
41 CallbackManagerBuilder;
43 typedef CODLayerT::IndirectStubsManagerBuilderT IndirectStubsManagerBuilder;
49 virtual ~GenericHandle() {}
50 virtual orc::JITSymbol findSymbolIn(const std::string &Name,
51 bool ExportedSymbolsOnly) = 0;
52 virtual void removeModule() = 0;
55 template <typename LayerT>
56 class GenericHandleImpl : public GenericHandle {
58 GenericHandleImpl(LayerT &Layer, typename LayerT::ModuleSetHandleT Handle)
59 : Layer(Layer), Handle(std::move(Handle)) {}
61 orc::JITSymbol findSymbolIn(const std::string &Name,
62 bool ExportedSymbolsOnly) override {
63 return Layer.findSymbolIn(Handle, Name, ExportedSymbolsOnly);
66 void removeModule() override {
67 return Layer.removeModuleSet(Handle);
72 typename LayerT::ModuleSetHandleT Handle;
75 template <typename LayerT>
76 std::unique_ptr<GenericHandleImpl<LayerT>>
77 createGenericHandle(LayerT &Layer, typename LayerT::ModuleSetHandleT Handle) {
78 return llvm::make_unique<GenericHandleImpl<LayerT>>(Layer,
84 // We need a 'ModuleSetHandleT' to conform to the layer concept.
85 typedef unsigned ModuleSetHandleT;
87 typedef unsigned ModuleHandleT;
89 static CallbackManagerBuilder createCallbackManagerBuilder(Triple T);
90 static IndirectStubsManagerBuilder createIndirectStubsMgrBuilder(Triple T);
92 OrcCBindingsStack(TargetMachine &TM, LLVMContext &Context,
93 CallbackManagerBuilder &BuildCallbackMgr,
94 IndirectStubsManagerBuilder IndirectStubsMgrBuilder)
95 : Context(Context), DL(TM.createDataLayout()),
97 CompileLayer(ObjectLayer, orc::SimpleCompiler(TM)),
98 CCMgr(BuildCallbackMgr(CompileLayer, CCMgrMemMgr, Context)),
99 CODLayer(CompileLayer,
100 [](Function &F) { std::set<Function*> S; S.insert(&F); return S; },
101 *CCMgr, std::move(IndirectStubsMgrBuilder), false),
102 IndirectStubsMgr(IndirectStubsMgrBuilder()),
103 CXXRuntimeOverrides([this](const std::string &S) { return mangle(S); }) {}
105 ~OrcCBindingsStack() {
106 // Run any destructors registered with __cxa_atexit.
107 CXXRuntimeOverrides.runDestructors();
108 // Run any IR destructors.
109 for (auto &DtorRunner : IRStaticDestructorRunners)
110 DtorRunner.runViaLayer(*this);
113 std::string mangle(StringRef Name) {
114 std::string MangledName;
116 raw_string_ostream MangledNameStream(MangledName);
117 Mangler::getNameWithPrefix(MangledNameStream, Name, DL);
122 template <typename PtrTy>
123 static PtrTy fromTargetAddress(orc::TargetAddress Addr) {
124 return reinterpret_cast<PtrTy>(static_cast<uintptr_t>(Addr));
128 createLazyCompileCallback(LLVMOrcLazyCompileCallbackFn Callback,
130 auto CCInfo = CCMgr->getCompileCallback(Context);
131 CCInfo.setCompileAction(
132 [=]() -> orc::TargetAddress {
133 return Callback(wrap(this), CallbackCtx);
135 return CCInfo.getAddress();
138 void createIndirectStub(StringRef StubName, orc::TargetAddress Addr) {
139 IndirectStubsMgr->createStub(StubName, Addr, JITSymbolFlags::Exported);
142 void setIndirectStubPointer(StringRef Name, orc::TargetAddress Addr) {
143 IndirectStubsMgr->updatePointer(Name, Addr);
146 std::shared_ptr<RuntimeDyld::SymbolResolver>
147 createResolver(LLVMOrcSymbolResolverFn ExternalResolver,
148 void *ExternalResolverCtx) {
149 auto Resolver = orc::createLambdaResolver(
150 [this, ExternalResolver, ExternalResolverCtx](const std::string &Name) {
153 // 2. Runtime overrides.
154 // 3. External resolver (if present).
156 if (auto Sym = CODLayer.findSymbol(Name, true))
157 return RuntimeDyld::SymbolInfo(Sym.getAddress(),
159 if (auto Sym = CXXRuntimeOverrides.searchOverrides(Name))
162 if (ExternalResolver)
163 return RuntimeDyld::SymbolInfo(ExternalResolver(Name.c_str(),
164 ExternalResolverCtx),
165 llvm::JITSymbolFlags::Exported);
167 return RuntimeDyld::SymbolInfo(nullptr);
169 [](const std::string &Name) {
170 return RuntimeDyld::SymbolInfo(nullptr);
174 return std::shared_ptr<RuntimeDyld::SymbolResolver>(std::move(Resolver));
177 template <typename LayerT>
178 ModuleHandleT addIRModule(LayerT &Layer,
180 std::unique_ptr<RuntimeDyld::MemoryManager> MemMgr,
181 LLVMOrcSymbolResolverFn ExternalResolver,
182 void *ExternalResolverCtx) {
184 // Attach a data-layout if one isn't already present.
185 if (M->getDataLayout().isDefault())
186 M->setDataLayout(DL);
188 // Record the static constructors and destructors. We have to do this before
189 // we hand over ownership of the module to the JIT.
190 std::vector<std::string> CtorNames, DtorNames;
191 for (auto Ctor : orc::getConstructors(*M))
192 CtorNames.push_back(mangle(Ctor.Func->getName()));
193 for (auto Dtor : orc::getDestructors(*M))
194 DtorNames.push_back(mangle(Dtor.Func->getName()));
196 // Create the resolver.
197 auto Resolver = createResolver(ExternalResolver, ExternalResolverCtx);
199 // Add the module to the JIT.
200 std::vector<Module*> S;
201 S.push_back(std::move(M));
203 auto LH = Layer.addModuleSet(std::move(S), std::move(MemMgr),
204 std::move(Resolver));
205 ModuleHandleT H = createHandle(Layer, LH);
207 // Run the static constructors, and save the static destructor runner for
208 // execution when the JIT is torn down.
209 orc::CtorDtorRunner<OrcCBindingsStack> CtorRunner(std::move(CtorNames), H);
210 CtorRunner.runViaLayer(*this);
212 IRStaticDestructorRunners.emplace_back(std::move(DtorNames), H);
217 ModuleHandleT addIRModuleEager(Module* M,
218 LLVMOrcSymbolResolverFn ExternalResolver,
219 void *ExternalResolverCtx) {
220 return addIRModule(CompileLayer, std::move(M),
221 llvm::make_unique<SectionMemoryManager>(),
222 std::move(ExternalResolver), ExternalResolverCtx);
225 ModuleHandleT addIRModuleLazy(Module* M,
226 LLVMOrcSymbolResolverFn ExternalResolver,
227 void *ExternalResolverCtx) {
228 return addIRModule(CODLayer, std::move(M), nullptr,
229 std::move(ExternalResolver), ExternalResolverCtx);
232 void removeModule(ModuleHandleT H) {
233 GenericHandles[H]->removeModule();
234 GenericHandles[H] = nullptr;
235 FreeHandleIndexes.push_back(H);
238 orc::JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) {
239 if (auto Sym = IndirectStubsMgr->findStub(Name, ExportedSymbolsOnly))
241 return CODLayer.findSymbol(mangle(Name), ExportedSymbolsOnly);
244 orc::JITSymbol findSymbolIn(ModuleHandleT H, const std::string &Name,
245 bool ExportedSymbolsOnly) {
246 return GenericHandles[H]->findSymbolIn(Name, ExportedSymbolsOnly);
251 template <typename LayerT>
252 unsigned createHandle(LayerT &Layer,
253 typename LayerT::ModuleSetHandleT Handle) {
255 if (!FreeHandleIndexes.empty()) {
256 NewHandle = FreeHandleIndexes.back();
257 FreeHandleIndexes.pop_back();
258 GenericHandles[NewHandle] = createGenericHandle(Layer, std::move(Handle));
261 NewHandle = GenericHandles.size();
262 GenericHandles.push_back(createGenericHandle(Layer, std::move(Handle)));
267 LLVMContext &Context;
269 SectionMemoryManager CCMgrMemMgr;
271 ObjLayerT ObjectLayer;
272 CompileLayerT CompileLayer;
273 std::unique_ptr<CompileCallbackMgr> CCMgr;
276 std::unique_ptr<orc::IndirectStubsManagerBase> IndirectStubsMgr;
278 std::vector<std::unique_ptr<GenericHandle>> GenericHandles;
279 std::vector<unsigned> FreeHandleIndexes;
281 orc::LocalCXXRuntimeOverrides CXXRuntimeOverrides;
282 std::vector<orc::CtorDtorRunner<OrcCBindingsStack>> IRStaticDestructorRunners;
285 } // end namespace llvm
287 #endif // LLVM_LIB_EXECUTIONENGINE_ORC_ORCCBINDINGSSTACK_H