blob: 5978b95e06808c02db68f9452de09da8be9d1c82 [file] [log] [blame]
Lang Hames130a7c42015-10-28 02:40:04 +00001//===--- 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"
Lang Hamesfd6e8dc2015-10-30 03:20:21 +000020#include "llvm-c/OrcBindings.h"
Lang Hames130a7c42015-10-28 02:40:04 +000021
22namespace llvm {
23
Lang Hamesfd6e8dc2015-10-30 03:20:21 +000024class OrcCBindingsStack;
25
26DEFINE_SIMPLE_CONVERSION_FUNCTIONS(OrcCBindingsStack, LLVMOrcJITStackRef)
27DEFINE_SIMPLE_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef)
28
Lang Hames130a7c42015-10-28 02:40:04 +000029class OrcCBindingsStack {
Lang Hames130a7c42015-10-28 02:40:04 +000030public:
31
Lang Hamesf0f4b4c2015-12-04 02:15:39 +000032 typedef orc::JITCompileCallbackManager CompileCallbackMgr;
Lang Hames130a7c42015-10-28 02:40:04 +000033 typedef orc::ObjectLinkingLayer<> ObjLayerT;
34 typedef orc::IRCompileLayer<ObjLayerT> CompileLayerT;
35 typedef orc::CompileOnDemandLayer<CompileLayerT, CompileCallbackMgr> CODLayerT;
36
Rafael Espindolae63e0182015-11-03 16:40:37 +000037 typedef std::function<std::unique_ptr<CompileCallbackMgr>()>
Lang Hames130a7c42015-10-28 02:40:04 +000038 CallbackManagerBuilder;
39
40 typedef CODLayerT::IndirectStubsManagerBuilderT IndirectStubsManagerBuilder;
41
42private:
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
79public:
80
81 // We need a 'ModuleSetHandleT' to conform to the layer concept.
82 typedef unsigned ModuleSetHandleT;
83
84 typedef unsigned ModuleHandleT;
85
Rafael Espindolae63e0182015-11-03 16:40:37 +000086 static std::unique_ptr<CompileCallbackMgr> createCompileCallbackMgr(Triple T);
Lang Hames130a7c42015-10-28 02:40:04 +000087 static IndirectStubsManagerBuilder createIndirectStubsMgrBuilder(Triple T);
88
Rafael Espindolae63e0182015-11-03 16:40:37 +000089 OrcCBindingsStack(TargetMachine &TM,
90 std::unique_ptr<CompileCallbackMgr> CCMgr,
Lang Hames130a7c42015-10-28 02:40:04 +000091 IndirectStubsManagerBuilder IndirectStubsMgrBuilder)
Evgeniy Stepanovb6404152016-01-20 22:02:07 +000092 : DL(TM.createDataLayout()),
Lang Hames6c3e7902016-01-20 17:39:52 +000093 IndirectStubsMgr(IndirectStubsMgrBuilder()),
Evgeniy Stepanovb6404152016-01-20 22:02:07 +000094 CCMgr(std::move(CCMgr)),
Lang Hames130a7c42015-10-28 02:40:04 +000095 ObjectLayer(),
96 CompileLayer(ObjectLayer, orc::SimpleCompiler(TM)),
Lang Hames130a7c42015-10-28 02:40:04 +000097 CODLayer(CompileLayer,
98 [](Function &F) { std::set<Function*> S; S.insert(&F); return S; },
Rafael Espindolae63e0182015-11-03 16:40:37 +000099 *this->CCMgr, std::move(IndirectStubsMgrBuilder), false),
Lang Hames130a7c42015-10-28 02:40:04 +0000100 CXXRuntimeOverrides([this](const std::string &S) { return mangle(S); }) {}
101
102 ~OrcCBindingsStack() {
103 // Run any destructors registered with __cxa_atexit.
104 CXXRuntimeOverrides.runDestructors();
105 // Run any IR destructors.
106 for (auto &DtorRunner : IRStaticDestructorRunners)
107 DtorRunner.runViaLayer(*this);
108 }
109
110 std::string mangle(StringRef Name) {
111 std::string MangledName;
112 {
113 raw_string_ostream MangledNameStream(MangledName);
114 Mangler::getNameWithPrefix(MangledNameStream, Name, DL);
115 }
116 return MangledName;
117 }
118
119 template <typename PtrTy>
120 static PtrTy fromTargetAddress(orc::TargetAddress Addr) {
121 return reinterpret_cast<PtrTy>(static_cast<uintptr_t>(Addr));
122 }
123
Lang Hamesfd6e8dc2015-10-30 03:20:21 +0000124 orc::TargetAddress
125 createLazyCompileCallback(LLVMOrcLazyCompileCallbackFn Callback,
126 void *CallbackCtx) {
Rafael Espindolae63e0182015-11-03 16:40:37 +0000127 auto CCInfo = CCMgr->getCompileCallback();
Lang Hamesfd6e8dc2015-10-30 03:20:21 +0000128 CCInfo.setCompileAction(
129 [=]() -> orc::TargetAddress {
130 return Callback(wrap(this), CallbackCtx);
131 });
132 return CCInfo.getAddress();
133 }
134
135 void createIndirectStub(StringRef StubName, orc::TargetAddress Addr) {
136 IndirectStubsMgr->createStub(StubName, Addr, JITSymbolFlags::Exported);
137 }
138
139 void setIndirectStubPointer(StringRef Name, orc::TargetAddress Addr) {
140 IndirectStubsMgr->updatePointer(Name, Addr);
141 }
142
Lang Hames130a7c42015-10-28 02:40:04 +0000143 std::shared_ptr<RuntimeDyld::SymbolResolver>
Lang Hamesfd6e8dc2015-10-30 03:20:21 +0000144 createResolver(LLVMOrcSymbolResolverFn ExternalResolver,
Lang Hames130a7c42015-10-28 02:40:04 +0000145 void *ExternalResolverCtx) {
146 auto Resolver = orc::createLambdaResolver(
147 [this, ExternalResolver, ExternalResolverCtx](const std::string &Name) {
148 // Search order:
149 // 1. JIT'd symbols.
150 // 2. Runtime overrides.
151 // 3. External resolver (if present).
152
153 if (auto Sym = CODLayer.findSymbol(Name, true))
154 return RuntimeDyld::SymbolInfo(Sym.getAddress(),
155 Sym.getFlags());
156 if (auto Sym = CXXRuntimeOverrides.searchOverrides(Name))
157 return Sym;
158
159 if (ExternalResolver)
160 return RuntimeDyld::SymbolInfo(ExternalResolver(Name.c_str(),
161 ExternalResolverCtx),
162 llvm::JITSymbolFlags::Exported);
163
164 return RuntimeDyld::SymbolInfo(nullptr);
165 },
166 [](const std::string &Name) {
167 return RuntimeDyld::SymbolInfo(nullptr);
168 }
169 );
170
171 return std::shared_ptr<RuntimeDyld::SymbolResolver>(std::move(Resolver));
172 }
173
174 template <typename LayerT>
175 ModuleHandleT addIRModule(LayerT &Layer,
176 Module *M,
177 std::unique_ptr<RuntimeDyld::MemoryManager> MemMgr,
Lang Hamesfd6e8dc2015-10-30 03:20:21 +0000178 LLVMOrcSymbolResolverFn ExternalResolver,
Lang Hames130a7c42015-10-28 02:40:04 +0000179 void *ExternalResolverCtx) {
180
181 // Attach a data-layout if one isn't already present.
182 if (M->getDataLayout().isDefault())
183 M->setDataLayout(DL);
184
185 // Record the static constructors and destructors. We have to do this before
186 // we hand over ownership of the module to the JIT.
187 std::vector<std::string> CtorNames, DtorNames;
188 for (auto Ctor : orc::getConstructors(*M))
189 CtorNames.push_back(mangle(Ctor.Func->getName()));
190 for (auto Dtor : orc::getDestructors(*M))
191 DtorNames.push_back(mangle(Dtor.Func->getName()));
192
193 // Create the resolver.
194 auto Resolver = createResolver(ExternalResolver, ExternalResolverCtx);
195
196 // Add the module to the JIT.
197 std::vector<Module*> S;
198 S.push_back(std::move(M));
199
200 auto LH = Layer.addModuleSet(std::move(S), std::move(MemMgr),
201 std::move(Resolver));
202 ModuleHandleT H = createHandle(Layer, LH);
203
204 // Run the static constructors, and save the static destructor runner for
205 // execution when the JIT is torn down.
206 orc::CtorDtorRunner<OrcCBindingsStack> CtorRunner(std::move(CtorNames), H);
207 CtorRunner.runViaLayer(*this);
208
209 IRStaticDestructorRunners.emplace_back(std::move(DtorNames), H);
210
211 return H;
212 }
213
214 ModuleHandleT addIRModuleEager(Module* M,
Lang Hamesfd6e8dc2015-10-30 03:20:21 +0000215 LLVMOrcSymbolResolverFn ExternalResolver,
Lang Hames130a7c42015-10-28 02:40:04 +0000216 void *ExternalResolverCtx) {
217 return addIRModule(CompileLayer, std::move(M),
218 llvm::make_unique<SectionMemoryManager>(),
219 std::move(ExternalResolver), ExternalResolverCtx);
220 }
221
222 ModuleHandleT addIRModuleLazy(Module* M,
Lang Hamesfd6e8dc2015-10-30 03:20:21 +0000223 LLVMOrcSymbolResolverFn ExternalResolver,
Lang Hames130a7c42015-10-28 02:40:04 +0000224 void *ExternalResolverCtx) {
Lang Hames829826b2016-01-09 20:55:18 +0000225 return addIRModule(CODLayer, std::move(M),
226 llvm::make_unique<SectionMemoryManager>(),
Lang Hames130a7c42015-10-28 02:40:04 +0000227 std::move(ExternalResolver), ExternalResolverCtx);
228 }
229
230 void removeModule(ModuleHandleT H) {
231 GenericHandles[H]->removeModule();
232 GenericHandles[H] = nullptr;
233 FreeHandleIndexes.push_back(H);
234 }
235
236 orc::JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) {
Lang Hamesfd6e8dc2015-10-30 03:20:21 +0000237 if (auto Sym = IndirectStubsMgr->findStub(Name, ExportedSymbolsOnly))
238 return Sym;
Lang Hames130a7c42015-10-28 02:40:04 +0000239 return CODLayer.findSymbol(mangle(Name), ExportedSymbolsOnly);
240 }
241
242 orc::JITSymbol findSymbolIn(ModuleHandleT H, const std::string &Name,
243 bool ExportedSymbolsOnly) {
244 return GenericHandles[H]->findSymbolIn(Name, ExportedSymbolsOnly);
245 }
246
247private:
248
249 template <typename LayerT>
250 unsigned createHandle(LayerT &Layer,
251 typename LayerT::ModuleSetHandleT Handle) {
252 unsigned NewHandle;
253 if (!FreeHandleIndexes.empty()) {
254 NewHandle = FreeHandleIndexes.back();
255 FreeHandleIndexes.pop_back();
256 GenericHandles[NewHandle] = createGenericHandle(Layer, std::move(Handle));
257 return NewHandle;
258 } else {
259 NewHandle = GenericHandles.size();
260 GenericHandles.push_back(createGenericHandle(Layer, std::move(Handle)));
261 }
262 return NewHandle;
263 }
264
265 DataLayout DL;
266 SectionMemoryManager CCMgrMemMgr;
267
Lang Hames6c3e7902016-01-20 17:39:52 +0000268 std::unique_ptr<orc::IndirectStubsManager> IndirectStubsMgr;
269
Rafael Espindolae63e0182015-11-03 16:40:37 +0000270 std::unique_ptr<CompileCallbackMgr> CCMgr;
Lang Hames130a7c42015-10-28 02:40:04 +0000271 ObjLayerT ObjectLayer;
272 CompileLayerT CompileLayer;
Lang Hames130a7c42015-10-28 02:40:04 +0000273 CODLayerT CODLayer;
274
Lang Hames130a7c42015-10-28 02:40:04 +0000275 std::vector<std::unique_ptr<GenericHandle>> GenericHandles;
276 std::vector<unsigned> FreeHandleIndexes;
277
278 orc::LocalCXXRuntimeOverrides CXXRuntimeOverrides;
279 std::vector<orc::CtorDtorRunner<OrcCBindingsStack>> IRStaticDestructorRunners;
280};
281
282} // end namespace llvm
283
284#endif // LLVM_LIB_EXECUTIONENGINE_ORC_ORCCBINDINGSSTACK_H