blob: 508ce62c88d61f40b035e1396d69a5777347a9ed [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
Lang Hames1fa0e0e2016-04-25 21:21:20 +000013#include "llvm-c/OrcBindings.h"
Lang Hames130a7c42015-10-28 02:40:04 +000014#include "llvm/ADT/Triple.h"
15#include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h"
16#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
17#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
18#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
19#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
20#include "llvm/IR/LLVMContext.h"
Lang Hamesef5a0ee2016-04-25 19:56:45 +000021#include "llvm/Support/Error.h"
Lang Hames130a7c42015-10-28 02:40:04 +000022
23namespace llvm {
24
Lang Hamesfd6e8dc2015-10-30 03:20:21 +000025class OrcCBindingsStack;
26
27DEFINE_SIMPLE_CONVERSION_FUNCTIONS(OrcCBindingsStack, LLVMOrcJITStackRef)
28DEFINE_SIMPLE_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef)
29
Lang Hames130a7c42015-10-28 02:40:04 +000030class OrcCBindingsStack {
Lang Hames130a7c42015-10-28 02:40:04 +000031public:
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;
Lang Hames1fa0e0e2016-04-25 21:21:20 +000035 typedef orc::CompileOnDemandLayer<CompileLayerT, CompileCallbackMgr>
36 CODLayerT;
Lang Hames130a7c42015-10-28 02:40:04 +000037
Rafael Espindolae63e0182015-11-03 16:40:37 +000038 typedef std::function<std::unique_ptr<CompileCallbackMgr>()>
Lang Hames1fa0e0e2016-04-25 21:21:20 +000039 CallbackManagerBuilder;
Lang Hames130a7c42015-10-28 02:40:04 +000040
41 typedef CODLayerT::IndirectStubsManagerBuilderT IndirectStubsManagerBuilder;
42
43private:
Lang Hames130a7c42015-10-28 02:40:04 +000044 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
Lang Hames1fa0e0e2016-04-25 21:21:20 +000052 template <typename LayerT> class GenericHandleImpl : public GenericHandle {
Lang Hames130a7c42015-10-28 02:40:04 +000053 public:
54 GenericHandleImpl(LayerT &Layer, typename LayerT::ModuleSetHandleT Handle)
Lang Hames1fa0e0e2016-04-25 21:21:20 +000055 : Layer(Layer), Handle(std::move(Handle)) {}
Lang Hames130a7c42015-10-28 02:40:04 +000056
57 orc::JITSymbol findSymbolIn(const std::string &Name,
58 bool ExportedSymbolsOnly) override {
59 return Layer.findSymbolIn(Handle, Name, ExportedSymbolsOnly);
60 }
61
Lang Hames1fa0e0e2016-04-25 21:21:20 +000062 void removeModule() override { return Layer.removeModuleSet(Handle); }
Lang Hames130a7c42015-10-28 02:40:04 +000063
64 private:
65 LayerT &Layer;
66 typename LayerT::ModuleSetHandleT Handle;
67 };
68
69 template <typename LayerT>
70 std::unique_ptr<GenericHandleImpl<LayerT>>
71 createGenericHandle(LayerT &Layer, typename LayerT::ModuleSetHandleT Handle) {
72 return llvm::make_unique<GenericHandleImpl<LayerT>>(Layer,
73 std::move(Handle));
74 }
75
76public:
Lang Hames130a7c42015-10-28 02:40:04 +000077 // We need a 'ModuleSetHandleT' to conform to the layer concept.
78 typedef unsigned ModuleSetHandleT;
79
80 typedef unsigned ModuleHandleT;
81
Rafael Espindolae63e0182015-11-03 16:40:37 +000082 static std::unique_ptr<CompileCallbackMgr> createCompileCallbackMgr(Triple T);
Lang Hames130a7c42015-10-28 02:40:04 +000083 static IndirectStubsManagerBuilder createIndirectStubsMgrBuilder(Triple T);
84
Rafael Espindolae63e0182015-11-03 16:40:37 +000085 OrcCBindingsStack(TargetMachine &TM,
David Blaikie8ecf9932016-01-20 22:24:26 +000086 std::unique_ptr<CompileCallbackMgr> CCMgr,
Lang Hames130a7c42015-10-28 02:40:04 +000087 IndirectStubsManagerBuilder IndirectStubsMgrBuilder)
David Blaikie8ecf9932016-01-20 22:24:26 +000088 : DL(TM.createDataLayout()), IndirectStubsMgr(IndirectStubsMgrBuilder()),
89 CCMgr(std::move(CCMgr)), ObjectLayer(),
90 CompileLayer(ObjectLayer, orc::SimpleCompiler(TM)),
91 CODLayer(CompileLayer,
92 [](Function &F) { return std::set<Function *>({&F}); },
93 *this->CCMgr, std::move(IndirectStubsMgrBuilder), false),
94 CXXRuntimeOverrides(
95 [this](const std::string &S) { return mangle(S); }) {}
Lang Hames130a7c42015-10-28 02:40:04 +000096
97 ~OrcCBindingsStack() {
98 // Run any destructors registered with __cxa_atexit.
99 CXXRuntimeOverrides.runDestructors();
100 // Run any IR destructors.
101 for (auto &DtorRunner : IRStaticDestructorRunners)
102 DtorRunner.runViaLayer(*this);
103 }
104
105 std::string mangle(StringRef Name) {
106 std::string MangledName;
107 {
108 raw_string_ostream MangledNameStream(MangledName);
109 Mangler::getNameWithPrefix(MangledNameStream, Name, DL);
110 }
111 return MangledName;
112 }
113
114 template <typename PtrTy>
115 static PtrTy fromTargetAddress(orc::TargetAddress Addr) {
116 return reinterpret_cast<PtrTy>(static_cast<uintptr_t>(Addr));
117 }
118
Lang Hamesfd6e8dc2015-10-30 03:20:21 +0000119 orc::TargetAddress
120 createLazyCompileCallback(LLVMOrcLazyCompileCallbackFn Callback,
121 void *CallbackCtx) {
Rafael Espindolae63e0182015-11-03 16:40:37 +0000122 auto CCInfo = CCMgr->getCompileCallback();
Lang Hames1fa0e0e2016-04-25 21:21:20 +0000123 CCInfo.setCompileAction([=]() -> orc::TargetAddress {
124 return Callback(wrap(this), CallbackCtx);
125 });
Lang Hamesfd6e8dc2015-10-30 03:20:21 +0000126 return CCInfo.getAddress();
127 }
128
Lang Hames1fa0e0e2016-04-25 21:21:20 +0000129 LLVMOrcErrorCode createIndirectStub(StringRef StubName,
130 orc::TargetAddress Addr) {
Lang Hamesef5a0ee2016-04-25 19:56:45 +0000131 return mapError(
Lang Hames1fa0e0e2016-04-25 21:21:20 +0000132 IndirectStubsMgr->createStub(StubName, Addr, JITSymbolFlags::Exported));
Lang Hamesfd6e8dc2015-10-30 03:20:21 +0000133 }
134
Lang Hames1fa0e0e2016-04-25 21:21:20 +0000135 LLVMOrcErrorCode setIndirectStubPointer(StringRef Name,
136 orc::TargetAddress Addr) {
Lang Hamesef5a0ee2016-04-25 19:56:45 +0000137 return mapError(IndirectStubsMgr->updatePointer(Name, Addr));
Lang Hamesfd6e8dc2015-10-30 03:20:21 +0000138 }
139
Lang Hames130a7c42015-10-28 02:40:04 +0000140 std::shared_ptr<RuntimeDyld::SymbolResolver>
Lang Hamesfd6e8dc2015-10-30 03:20:21 +0000141 createResolver(LLVMOrcSymbolResolverFn ExternalResolver,
Lang Hames130a7c42015-10-28 02:40:04 +0000142 void *ExternalResolverCtx) {
143 auto Resolver = orc::createLambdaResolver(
Lang Hames1fa0e0e2016-04-25 21:21:20 +0000144 [this, ExternalResolver, ExternalResolverCtx](const std::string &Name) {
145 // Search order:
146 // 1. JIT'd symbols.
147 // 2. Runtime overrides.
148 // 3. External resolver (if present).
Lang Hames130a7c42015-10-28 02:40:04 +0000149
Lang Hames1fa0e0e2016-04-25 21:21:20 +0000150 if (auto Sym = CODLayer.findSymbol(Name, true))
151 return RuntimeDyld::SymbolInfo(Sym.getAddress(), Sym.getFlags());
152 if (auto Sym = CXXRuntimeOverrides.searchOverrides(Name))
153 return Sym;
Lang Hames130a7c42015-10-28 02:40:04 +0000154
Lang Hames1fa0e0e2016-04-25 21:21:20 +0000155 if (ExternalResolver)
156 return RuntimeDyld::SymbolInfo(
157 ExternalResolver(Name.c_str(), ExternalResolverCtx),
158 llvm::JITSymbolFlags::Exported);
Lang Hames130a7c42015-10-28 02:40:04 +0000159
Lang Hames1fa0e0e2016-04-25 21:21:20 +0000160 return RuntimeDyld::SymbolInfo(nullptr);
161 },
162 [](const std::string &Name) {
163 return RuntimeDyld::SymbolInfo(nullptr);
164 });
Lang Hames130a7c42015-10-28 02:40:04 +0000165
166 return std::shared_ptr<RuntimeDyld::SymbolResolver>(std::move(Resolver));
167 }
168
169 template <typename LayerT>
Lang Hames1fa0e0e2016-04-25 21:21:20 +0000170 ModuleHandleT addIRModule(LayerT &Layer, Module *M,
Lang Hames130a7c42015-10-28 02:40:04 +0000171 std::unique_ptr<RuntimeDyld::MemoryManager> MemMgr,
Lang Hamesfd6e8dc2015-10-30 03:20:21 +0000172 LLVMOrcSymbolResolverFn ExternalResolver,
Lang Hames130a7c42015-10-28 02:40:04 +0000173 void *ExternalResolverCtx) {
174
175 // Attach a data-layout if one isn't already present.
176 if (M->getDataLayout().isDefault())
177 M->setDataLayout(DL);
178
179 // Record the static constructors and destructors. We have to do this before
180 // we hand over ownership of the module to the JIT.
181 std::vector<std::string> CtorNames, DtorNames;
182 for (auto Ctor : orc::getConstructors(*M))
183 CtorNames.push_back(mangle(Ctor.Func->getName()));
184 for (auto Dtor : orc::getDestructors(*M))
185 DtorNames.push_back(mangle(Dtor.Func->getName()));
186
187 // Create the resolver.
188 auto Resolver = createResolver(ExternalResolver, ExternalResolverCtx);
189
190 // Add the module to the JIT.
Lang Hames1fa0e0e2016-04-25 21:21:20 +0000191 std::vector<Module *> S;
Lang Hames130a7c42015-10-28 02:40:04 +0000192 S.push_back(std::move(M));
193
194 auto LH = Layer.addModuleSet(std::move(S), std::move(MemMgr),
195 std::move(Resolver));
196 ModuleHandleT H = createHandle(Layer, LH);
197
198 // Run the static constructors, and save the static destructor runner for
199 // execution when the JIT is torn down.
200 orc::CtorDtorRunner<OrcCBindingsStack> CtorRunner(std::move(CtorNames), H);
201 CtorRunner.runViaLayer(*this);
202
203 IRStaticDestructorRunners.emplace_back(std::move(DtorNames), H);
204
205 return H;
206 }
207
Lang Hames1fa0e0e2016-04-25 21:21:20 +0000208 ModuleHandleT addIRModuleEager(Module *M,
Lang Hamesfd6e8dc2015-10-30 03:20:21 +0000209 LLVMOrcSymbolResolverFn ExternalResolver,
Lang Hames130a7c42015-10-28 02:40:04 +0000210 void *ExternalResolverCtx) {
211 return addIRModule(CompileLayer, std::move(M),
212 llvm::make_unique<SectionMemoryManager>(),
213 std::move(ExternalResolver), ExternalResolverCtx);
214 }
215
Lang Hames1fa0e0e2016-04-25 21:21:20 +0000216 ModuleHandleT addIRModuleLazy(Module *M,
Lang Hamesfd6e8dc2015-10-30 03:20:21 +0000217 LLVMOrcSymbolResolverFn ExternalResolver,
Lang Hames130a7c42015-10-28 02:40:04 +0000218 void *ExternalResolverCtx) {
Lang Hames829826b2016-01-09 20:55:18 +0000219 return addIRModule(CODLayer, std::move(M),
Lang Hames1fa0e0e2016-04-25 21:21:20 +0000220 llvm::make_unique<SectionMemoryManager>(),
Lang Hames130a7c42015-10-28 02:40:04 +0000221 std::move(ExternalResolver), ExternalResolverCtx);
222 }
223
224 void removeModule(ModuleHandleT H) {
225 GenericHandles[H]->removeModule();
226 GenericHandles[H] = nullptr;
227 FreeHandleIndexes.push_back(H);
228 }
229
230 orc::JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) {
Lang Hamesfd6e8dc2015-10-30 03:20:21 +0000231 if (auto Sym = IndirectStubsMgr->findStub(Name, ExportedSymbolsOnly))
232 return Sym;
Lang Hames130a7c42015-10-28 02:40:04 +0000233 return CODLayer.findSymbol(mangle(Name), ExportedSymbolsOnly);
234 }
235
236 orc::JITSymbol findSymbolIn(ModuleHandleT H, const std::string &Name,
237 bool ExportedSymbolsOnly) {
238 return GenericHandles[H]->findSymbolIn(Name, ExportedSymbolsOnly);
239 }
240
Lang Hames1fa0e0e2016-04-25 21:21:20 +0000241 const std::string &getErrorMessage() const { return ErrMsg; }
Lang Hamesef5a0ee2016-04-25 19:56:45 +0000242
Lang Hames130a7c42015-10-28 02:40:04 +0000243private:
Lang Hames130a7c42015-10-28 02:40:04 +0000244 template <typename LayerT>
245 unsigned createHandle(LayerT &Layer,
246 typename LayerT::ModuleSetHandleT Handle) {
247 unsigned NewHandle;
248 if (!FreeHandleIndexes.empty()) {
249 NewHandle = FreeHandleIndexes.back();
250 FreeHandleIndexes.pop_back();
251 GenericHandles[NewHandle] = createGenericHandle(Layer, std::move(Handle));
252 return NewHandle;
253 } else {
254 NewHandle = GenericHandles.size();
255 GenericHandles.push_back(createGenericHandle(Layer, std::move(Handle)));
256 }
257 return NewHandle;
258 }
259
Lang Hamesef5a0ee2016-04-25 19:56:45 +0000260 LLVMOrcErrorCode mapError(Error Err) {
261 LLVMOrcErrorCode Result = LLVMOrcErrSuccess;
Lang Hames1fa0e0e2016-04-25 21:21:20 +0000262 handleAllErrors(std::move(Err), [&](ErrorInfoBase &EIB) {
263 // Handler of last resort.
264 Result = LLVMOrcErrGeneric;
265 ErrMsg = "";
266 raw_string_ostream ErrStream(ErrMsg);
267 EIB.log(ErrStream);
268 });
Lang Hamesef5a0ee2016-04-25 19:56:45 +0000269 return Result;
270 }
271
Lang Hames130a7c42015-10-28 02:40:04 +0000272 DataLayout DL;
273 SectionMemoryManager CCMgrMemMgr;
274
Lang Hames6c3e7902016-01-20 17:39:52 +0000275 std::unique_ptr<orc::IndirectStubsManager> IndirectStubsMgr;
276
Rafael Espindolae63e0182015-11-03 16:40:37 +0000277 std::unique_ptr<CompileCallbackMgr> CCMgr;
Lang Hames130a7c42015-10-28 02:40:04 +0000278 ObjLayerT ObjectLayer;
279 CompileLayerT CompileLayer;
Lang Hames130a7c42015-10-28 02:40:04 +0000280 CODLayerT CODLayer;
281
Lang Hames130a7c42015-10-28 02:40:04 +0000282 std::vector<std::unique_ptr<GenericHandle>> GenericHandles;
283 std::vector<unsigned> FreeHandleIndexes;
284
285 orc::LocalCXXRuntimeOverrides CXXRuntimeOverrides;
286 std::vector<orc::CtorDtorRunner<OrcCBindingsStack>> IRStaticDestructorRunners;
Lang Hamesef5a0ee2016-04-25 19:56:45 +0000287 std::string ErrMsg;
Lang Hames130a7c42015-10-28 02:40:04 +0000288};
289
290} // end namespace llvm
291
292#endif // LLVM_LIB_EXECUTIONENGINE_ORC_ORCCBINDINGSSTACK_H