LLVM  4.0.0
OrcCBindingsStack.h
Go to the documentation of this file.
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-c/OrcBindings.h"
14 #include "llvm/ADT/Triple.h"
20 #include "llvm/IR/LLVMContext.h"
21 #include "llvm/Support/Error.h"
22 
23 namespace llvm {
24 
25 class OrcCBindingsStack;
26 
29 
31 public:
37 
38  typedef std::function<std::unique_ptr<CompileCallbackMgr>()>
40 
42 
43 private:
44  class GenericHandle {
45  public:
46  virtual ~GenericHandle() {}
47  virtual JITSymbol findSymbolIn(const std::string &Name,
48  bool ExportedSymbolsOnly) = 0;
49  virtual void removeModule() = 0;
50  };
51 
52  template <typename LayerT> class GenericHandleImpl : public GenericHandle {
53  public:
54  GenericHandleImpl(LayerT &Layer, typename LayerT::ModuleSetHandleT Handle)
55  : Layer(Layer), Handle(std::move(Handle)) {}
56 
57  JITSymbol findSymbolIn(const std::string &Name,
58  bool ExportedSymbolsOnly) override {
59  return Layer.findSymbolIn(Handle, Name, ExportedSymbolsOnly);
60  }
61 
62  void removeModule() override { return Layer.removeModuleSet(Handle); }
63 
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 
76 public:
77  // We need a 'ModuleSetHandleT' to conform to the layer concept.
78  typedef unsigned ModuleSetHandleT;
79 
80  typedef unsigned ModuleHandleT;
81 
82  OrcCBindingsStack(TargetMachine &TM,
83  std::unique_ptr<CompileCallbackMgr> CCMgr,
84  IndirectStubsManagerBuilder IndirectStubsMgrBuilder)
85  : DL(TM.createDataLayout()), IndirectStubsMgr(IndirectStubsMgrBuilder()),
86  CCMgr(std::move(CCMgr)), ObjectLayer(),
87  CompileLayer(ObjectLayer, orc::SimpleCompiler(TM)),
88  CODLayer(CompileLayer,
89  [](Function &F) { return std::set<Function *>({&F}); },
90  *this->CCMgr, std::move(IndirectStubsMgrBuilder), false),
92  [this](const std::string &S) { return mangle(S); }) {}
93 
95  // Run any destructors registered with __cxa_atexit.
96  CXXRuntimeOverrides.runDestructors();
97  // Run any IR destructors.
98  for (auto &DtorRunner : IRStaticDestructorRunners)
99  DtorRunner.runViaLayer(*this);
100  }
101 
102  std::string mangle(StringRef Name) {
103  std::string MangledName;
104  {
105  raw_string_ostream MangledNameStream(MangledName);
106  Mangler::getNameWithPrefix(MangledNameStream, Name, DL);
107  }
108  return MangledName;
109  }
110 
111  template <typename PtrTy>
112  static PtrTy fromTargetAddress(JITTargetAddress Addr) {
113  return reinterpret_cast<PtrTy>(static_cast<uintptr_t>(Addr));
114  }
115 
118  void *CallbackCtx) {
119  auto CCInfo = CCMgr->getCompileCallback();
120  CCInfo.setCompileAction([=]() -> JITTargetAddress {
121  return Callback(wrap(this), CallbackCtx);
122  });
123  return CCInfo.getAddress();
124  }
125 
127  JITTargetAddress Addr) {
128  return mapError(
129  IndirectStubsMgr->createStub(StubName, Addr, JITSymbolFlags::Exported));
130  }
131 
133  JITTargetAddress Addr) {
134  return mapError(IndirectStubsMgr->updatePointer(Name, Addr));
135  }
136 
137  std::unique_ptr<JITSymbolResolver>
139  void *ExternalResolverCtx) {
141  [this, ExternalResolver, ExternalResolverCtx](const std::string &Name)
142  -> JITSymbol {
143  // Search order:
144  // 1. JIT'd symbols.
145  // 2. Runtime overrides.
146  // 3. External resolver (if present).
147 
148  if (auto Sym = CODLayer.findSymbol(Name, true))
149  return Sym;
150  if (auto Sym = CXXRuntimeOverrides.searchOverrides(Name))
151  return Sym;
152 
153  if (ExternalResolver)
154  return JITSymbol(
155  ExternalResolver(Name.c_str(), ExternalResolverCtx),
157 
158  return JITSymbol(nullptr);
159  },
160  [](const std::string &Name) {
161  return JITSymbol(nullptr);
162  });
163  }
164 
165  template <typename LayerT>
166  ModuleHandleT addIRModule(LayerT &Layer, Module *M,
167  std::unique_ptr<RuntimeDyld::MemoryManager> MemMgr,
168  LLVMOrcSymbolResolverFn ExternalResolver,
169  void *ExternalResolverCtx) {
170 
171  // Attach a data-layout if one isn't already present.
172  if (M->getDataLayout().isDefault())
173  M->setDataLayout(DL);
174 
175  // Record the static constructors and destructors. We have to do this before
176  // we hand over ownership of the module to the JIT.
177  std::vector<std::string> CtorNames, DtorNames;
178  for (auto Ctor : orc::getConstructors(*M))
179  CtorNames.push_back(mangle(Ctor.Func->getName()));
180  for (auto Dtor : orc::getDestructors(*M))
181  DtorNames.push_back(mangle(Dtor.Func->getName()));
182 
183  // Create the resolver.
184  auto Resolver = createResolver(ExternalResolver, ExternalResolverCtx);
185 
186  // Add the module to the JIT.
187  std::vector<Module *> S;
188  S.push_back(std::move(M));
189 
190  auto LH = Layer.addModuleSet(std::move(S), std::move(MemMgr),
191  std::move(Resolver));
192  ModuleHandleT H = createHandle(Layer, LH);
193 
194  // Run the static constructors, and save the static destructor runner for
195  // execution when the JIT is torn down.
196  orc::CtorDtorRunner<OrcCBindingsStack> CtorRunner(std::move(CtorNames), H);
197  CtorRunner.runViaLayer(*this);
198 
199  IRStaticDestructorRunners.emplace_back(std::move(DtorNames), H);
200 
201  return H;
202  }
203 
204  ModuleHandleT addIRModuleEager(Module *M,
205  LLVMOrcSymbolResolverFn ExternalResolver,
206  void *ExternalResolverCtx) {
207  return addIRModule(CompileLayer, std::move(M),
208  llvm::make_unique<SectionMemoryManager>(),
209  std::move(ExternalResolver), ExternalResolverCtx);
210  }
211 
212  ModuleHandleT addIRModuleLazy(Module *M,
213  LLVMOrcSymbolResolverFn ExternalResolver,
214  void *ExternalResolverCtx) {
215  return addIRModule(CODLayer, std::move(M),
216  llvm::make_unique<SectionMemoryManager>(),
217  std::move(ExternalResolver), ExternalResolverCtx);
218  }
219 
220  void removeModule(ModuleHandleT H) {
221  GenericHandles[H]->removeModule();
222  GenericHandles[H] = nullptr;
223  FreeHandleIndexes.push_back(H);
224  }
225 
226  JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) {
227  if (auto Sym = IndirectStubsMgr->findStub(Name, ExportedSymbolsOnly))
228  return Sym;
229  return CODLayer.findSymbol(mangle(Name), ExportedSymbolsOnly);
230  }
231 
232  JITSymbol findSymbolIn(ModuleHandleT H, const std::string &Name,
233  bool ExportedSymbolsOnly) {
234  return GenericHandles[H]->findSymbolIn(Name, ExportedSymbolsOnly);
235  }
236 
237  const std::string &getErrorMessage() const { return ErrMsg; }
238 
239 private:
240  template <typename LayerT>
241  unsigned createHandle(LayerT &Layer,
242  typename LayerT::ModuleSetHandleT Handle) {
243  unsigned NewHandle;
244  if (!FreeHandleIndexes.empty()) {
245  NewHandle = FreeHandleIndexes.back();
246  FreeHandleIndexes.pop_back();
247  GenericHandles[NewHandle] = createGenericHandle(Layer, std::move(Handle));
248  return NewHandle;
249  } else {
250  NewHandle = GenericHandles.size();
251  GenericHandles.push_back(createGenericHandle(Layer, std::move(Handle)));
252  }
253  return NewHandle;
254  }
255 
256  LLVMOrcErrorCode mapError(Error Err) {
258  handleAllErrors(std::move(Err), [&](ErrorInfoBase &EIB) {
259  // Handler of last resort.
260  Result = LLVMOrcErrGeneric;
261  ErrMsg = "";
262  raw_string_ostream ErrStream(ErrMsg);
263  EIB.log(ErrStream);
264  });
265  return Result;
266  }
267 
268  DataLayout DL;
269  SectionMemoryManager CCMgrMemMgr;
270 
271  std::unique_ptr<orc::IndirectStubsManager> IndirectStubsMgr;
272 
273  std::unique_ptr<CompileCallbackMgr> CCMgr;
274  ObjLayerT ObjectLayer;
275  CompileLayerT CompileLayer;
276  CODLayerT CODLayer;
277 
278  std::vector<std::unique_ptr<GenericHandle>> GenericHandles;
279  std::vector<unsigned> FreeHandleIndexes;
280 
281  orc::LocalCXXRuntimeOverrides CXXRuntimeOverrides;
282  std::vector<orc::CtorDtorRunner<OrcCBindingsStack>> IRStaticDestructorRunners;
283  std::string ErrMsg;
284 };
285 
286 } // end namespace llvm
287 
288 #endif // LLVM_LIB_EXECUTIONENGINE_ORC_ORCCBINDINGSSTACK_H
uint64_t(* LLVMOrcLazyCompileCallbackFn)(LLVMOrcJITStackRef JITStack, void *CallbackCtx)
Definition: OrcBindings.h:36
std::function< std::unique_ptr< IndirectStubsManager >)> IndirectStubsManagerBuilderT
Builder for IndirectStubsManagers.
Represents a symbol in the JIT.
Definition: JITSymbol.h:113
A Module instance is used to store all the information related to an LLVM module. ...
Definition: Module.h:52
LLVMOrcErrorCode setIndirectStubPointer(StringRef Name, JITTargetAddress Addr)
bool runViaLayer(JITLayerT &JITLayer) const
Run the recorded constructors/destructors through the given JIT layer.
orc::IRCompileLayer< ObjLayerT > CompileLayerT
void setDataLayout(StringRef Desc)
Set the data layout.
Definition: Module.cpp:378
std::function< std::unique_ptr< CompileCallbackMgr >)> CallbackManagerBuilder
uint64_t(* LLVMOrcSymbolResolverFn)(const char *Name, void *LookupCtx)
Definition: OrcBindings.h:35
bool isDefault() const
Test if the DataLayout was constructed from an empty string.
Definition: DataLayout.h:233
Target-independent base class for compile callback management.
ModuleHandleT addIRModuleLazy(Module *M, LLVMOrcSymbolResolverFn ExternalResolver, void *ExternalResolverCtx)
#define DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ty, ref)
orc::JITCompileCallbackManager CompileCallbackMgr
struct LLVMOpaqueTargetMachine * LLVMTargetMachineRef
std::unique_ptr< LambdaResolver< DylibLookupFtorT, ExternalLookupFtorT > > createLambdaResolver(DylibLookupFtorT DylibLookupFtor, ExternalLookupFtorT ExternalLookupFtor)
void removeModule(ModuleHandleT H)
const std::string & getErrorMessage() const
Bare bones object linking layer.
std::unique_ptr< JITSymbolResolver > createResolver(LLVMOrcSymbolResolverFn ExternalResolver, void *ExternalResolverCtx)
#define F(x, y, z)
Definition: MD5.cpp:51
JITTargetAddress createLazyCompileCallback(LLVMOrcLazyCompileCallbackFn Callback, void *CallbackCtx)
iterator_range< CtorDtorIterator > getDestructors(const Module &M)
Create an iterator range over the entries of the llvm.global_ctors array.
OrcCBindingsStack(TargetMachine &TM, std::unique_ptr< CompileCallbackMgr > CCMgr, IndirectStubsManagerBuilder IndirectStubsMgrBuilder)
LLVMOrcErrorCode
Definition: OrcBindings.h:39
CODLayerT::IndirectStubsManagerBuilderT IndirectStubsManagerBuilder
JITSymbol findSymbolIn(ModuleHandleT H, const std::string &Name, bool ExportedSymbolsOnly)
Convenience class for recording constructor/destructor names for later execution. ...
ModuleHandleT addIRModule(LayerT &Layer, Module *M, std::unique_ptr< RuntimeDyld::MemoryManager > MemMgr, LLVMOrcSymbolResolverFn ExternalResolver, void *ExternalResolverCtx)
#define H(x, y, z)
Definition: MD5.cpp:53
LLVMOrcErrorCode createIndirectStub(StringRef StubName, JITTargetAddress Addr)
uint64_t JITTargetAddress
Represents an address in the target process's address space.
Definition: JITSymbol.h:33
void handleAllErrors(Error E, HandlerTs &&...Handlers)
Behaves the same as handleErrors, except that it requires that all errors be handled by the given han...
std::string mangle(StringRef Name)
*this CXXRuntimeOverrides([this](const std::string &S){return mangle(S);})
orc::ObjectLinkingLayer ObjLayerT
static PtrTy fromTargetAddress(JITTargetAddress Addr)
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
Definition: Module.cpp:384
LLVMAttributeRef wrap(Attribute Attr)
Definition: Attributes.h:186
void getNameWithPrefix(raw_ostream &OS, const GlobalValue *GV, bool CannotUsePrivateLabel) const
Print the appropriate prefix and the specified global variable's name.
Definition: Mangler.cpp:108
iterator_range< CtorDtorIterator > getConstructors(const Module &M)
Create an iterator range over the entries of the llvm.global_ctors array.
orc::CompileOnDemandLayer< CompileLayerT, CompileCallbackMgr > CODLayerT
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:463
JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly)
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:47
struct LLVMOrcOpaqueJITStack * LLVMOrcJITStackRef
Definition: OrcBindings.h:32
ModuleHandleT addIRModuleEager(Module *M, LLVMOrcSymbolResolverFn ExternalResolver, void *ExternalResolverCtx)