LLVM  7.0.0svn
ExecutionUtils.h
Go to the documentation of this file.
1 //===- ExecutionUtils.h - Utilities for executing code in Orc ---*- 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 // Contains utilities for executing code in Orc.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_EXECUTIONENGINE_ORC_EXECUTIONUTILS_H
15 #define LLVM_EXECUTIONENGINE_ORC_EXECUTIONUTILS_H
16 
17 #include "llvm/ADT/StringMap.h"
25 #include <algorithm>
26 #include <cstdint>
27 #include <string>
28 #include <utility>
29 #include <vector>
30 
31 namespace llvm {
32 
33 class ConstantArray;
34 class GlobalVariable;
35 class Function;
36 class Module;
37 class TargetMachine;
38 class Value;
39 
40 namespace orc {
41 
42 /// A utility class for building TargetMachines for JITs.
44 public:
48 
49  JITTargetMachineBuilder &setArch(std::string Arch) {
50  this->Arch = std::move(Arch);
51  return *this;
52  }
53  JITTargetMachineBuilder &setCPU(std::string CPU) {
54  this->CPU = std::move(CPU);
55  return *this;
56  }
58  this->RM = std::move(RM);
59  return *this;
60  }
62  this->CM = std::move(CM);
63  return *this;
64  }
66  addFeatures(const std::vector<std::string> &FeatureVec);
67  SubtargetFeatures &getFeatures() { return Features; }
68  TargetOptions &getOptions() { return Options; }
69 
70 private:
71  Triple TT;
72  std::string Arch;
73  std::string CPU;
74  SubtargetFeatures Features;
75  TargetOptions Options;
79 };
80 
81 /// This iterator provides a convenient way to iterate over the elements
82 /// of an llvm.global_ctors/llvm.global_dtors instance.
83 ///
84 /// The easiest way to get hold of instances of this class is to use the
85 /// getConstructors/getDestructors functions.
87 public:
88  /// Accessor for an element of the global_ctors/global_dtors array.
89  ///
90  /// This class provides a read-only view of the element with any casts on
91  /// the function stripped away.
92  struct Element {
93  Element(unsigned Priority, Function *Func, Value *Data)
94  : Priority(Priority), Func(Func), Data(Data) {}
95 
96  unsigned Priority;
99  };
100 
101  /// Construct an iterator instance. If End is true then this iterator
102  /// acts as the end of the range, otherwise it is the beginning.
103  CtorDtorIterator(const GlobalVariable *GV, bool End);
104 
105  /// Test iterators for equality.
106  bool operator==(const CtorDtorIterator &Other) const;
107 
108  /// Test iterators for inequality.
109  bool operator!=(const CtorDtorIterator &Other) const;
110 
111  /// Pre-increment iterator.
112  CtorDtorIterator& operator++();
113 
114  /// Post-increment iterator.
115  CtorDtorIterator operator++(int);
116 
117  /// Dereference iterator. The resulting value provides a read-only view
118  /// of this element of the global_ctors/global_dtors list.
119  Element operator*() const;
120 
121 private:
122  const ConstantArray *InitList;
123  unsigned I;
124 };
125 
126 /// Create an iterator range over the entries of the llvm.global_ctors
127 /// array.
129 
130 /// Create an iterator range over the entries of the llvm.global_ctors
131 /// array.
133 
134 /// Convenience class for recording constructor/destructor names for
135 /// later execution.
136 template <typename JITLayerT>
138 public:
139  /// Construct a CtorDtorRunner for the given range using the given
140  /// name mangling function.
141  CtorDtorRunner(std::vector<std::string> CtorDtorNames, VModuleKey K)
142  : CtorDtorNames(std::move(CtorDtorNames)), K(K) {}
143 
144  /// Run the recorded constructors/destructors through the given JIT
145  /// layer.
146  Error runViaLayer(JITLayerT &JITLayer) const {
147  using CtorDtorTy = void (*)();
148 
149  for (const auto &CtorDtorName : CtorDtorNames) {
150  if (auto CtorDtorSym = JITLayer.findSymbolIn(K, CtorDtorName, false)) {
151  if (auto AddrOrErr = CtorDtorSym.getAddress()) {
152  CtorDtorTy CtorDtor =
153  reinterpret_cast<CtorDtorTy>(static_cast<uintptr_t>(*AddrOrErr));
154  CtorDtor();
155  } else
156  return AddrOrErr.takeError();
157  } else {
158  if (auto Err = CtorDtorSym.takeError())
159  return Err;
160  else
161  return make_error<JITSymbolNotFound>(CtorDtorName);
162  }
163  }
164  return Error::success();
165  }
166 
167 private:
168  std::vector<std::string> CtorDtorNames;
169  orc::VModuleKey K;
170 };
171 
173 public:
174  CtorDtorRunner2(VSO &V) : V(V) {}
175  void add(iterator_range<CtorDtorIterator> CtorDtors);
176  Error run();
177 
178 private:
179  using CtorDtorList = std::vector<SymbolStringPtr>;
180  using CtorDtorPriorityMap = std::map<unsigned, CtorDtorList>;
181 
182  VSO &V;
183  CtorDtorPriorityMap CtorDtorsByPriority;
184 };
185 
186 /// Support class for static dtor execution. For hosted (in-process) JITs
187 /// only!
188 ///
189 /// If a __cxa_atexit function isn't found C++ programs that use static
190 /// destructors will fail to link. However, we don't want to use the host
191 /// process's __cxa_atexit, because it will schedule JIT'd destructors to run
192 /// after the JIT has been torn down, which is no good. This class makes it easy
193 /// to override __cxa_atexit (and the related __dso_handle).
194 ///
195 /// To use, clients should manually call searchOverrides from their symbol
196 /// resolver. This should generally be done after attempting symbol resolution
197 /// inside the JIT, but before searching the host process's symbol table. When
198 /// the client determines that destructors should be run (generally at JIT
199 /// teardown or after a return from main), the runDestructors method should be
200 /// called.
202 public:
203  /// Run any destructors recorded by the overriden __cxa_atexit function
204  /// (CXAAtExitOverride).
205  void runDestructors();
206 
207 protected:
208  template <typename PtrTy> JITTargetAddress toTargetAddress(PtrTy *P) {
209  return static_cast<JITTargetAddress>(reinterpret_cast<uintptr_t>(P));
210  }
211 
212  using DestructorPtr = void (*)(void *);
213  using CXXDestructorDataPair = std::pair<DestructorPtr, void *>;
214  using CXXDestructorDataPairList = std::vector<CXXDestructorDataPair>;
216  static int CXAAtExitOverride(DestructorPtr Destructor, void *Arg,
217  void *DSOHandle);
218 };
219 
221 public:
222  /// Create a runtime-overrides class.
223  template <typename MangleFtorT>
224  LocalCXXRuntimeOverrides(const MangleFtorT &Mangle) {
225  addOverride(Mangle("__dso_handle"), toTargetAddress(&DSOHandleOverride));
226  addOverride(Mangle("__cxa_atexit"), toTargetAddress(&CXAAtExitOverride));
227  }
228 
229  /// Search overrided symbols.
231  auto I = CXXRuntimeOverrides.find(Name);
232  if (I != CXXRuntimeOverrides.end())
234  return nullptr;
235  }
236 
237 private:
238  void addOverride(const std::string &Name, JITTargetAddress Addr) {
239  CXXRuntimeOverrides.insert(std::make_pair(Name, Addr));
240  }
241 
242  StringMap<JITTargetAddress> CXXRuntimeOverrides;
243 };
244 
246 public:
247  Error enable(VSO &V, MangleAndInterner &Mangler);
248 };
249 
250 /// A utility class to expose symbols found via dlsym to the JIT.
251 ///
252 /// If an instance of this class is attached to a VSO as a fallback definition
253 /// generator, then any symbol found in the given DynamicLibrary that passes
254 /// the 'Allow' predicate will be added to the VSO.
256 public:
257  using SymbolPredicate = std::function<bool(SymbolStringPtr)>;
259  const DataLayout &DL, SymbolPredicate Allow);
260  SymbolNameSet operator()(VSO &V, const SymbolNameSet &Names);
261 
262 private:
263  sys::DynamicLibrary Dylib;
264  SymbolPredicate Allow;
265  char GlobalPrefix;
266 };
267 
268 } // end namespace orc
269 } // end namespace llvm
270 
271 #endif // LLVM_EXECUTIONENGINE_ORC_EXECUTIONUTILS_H
JITTargetAddress toTargetAddress(PtrTy *P)
A parsed version of the target data layout string in and methods for querying it. ...
Definition: DataLayout.h:111
Accessor for an element of the global_ctors/global_dtors array.
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
A Module instance is used to store all the information related to an LLVM module. ...
Definition: Module.h:63
A symbol table that supports asynchoronous symbol queries.
Definition: Core.h:548
This provides a very simple, boring adaptor for a begin and end iterator into a range type...
Element(unsigned Priority, Function *Func, Value *Data)
JITTargetMachineBuilder & setRelocationModel(Optional< Reloc::Model > RM)
std::vector< CXXDestructorDataPair > CXXDestructorDataPairList
uint64_t VModuleKey
VModuleKey provides a unique identifier (allocated and managed by ExecutionSessions) for a module add...
Definition: Core.h:40
SubtargetFeatures & getFeatures()
Definition: BitVector.h:921
Mangles symbol names then uniques them in the context of an ExecutionSession.
Definition: Core.h:745
bool operator!=(const SymbolStringPtr &LHS, const SymbolStringPtr &RHS)
Tagged union holding either a T or a Error.
Definition: CachePruning.h:23
JITEvaluatedSymbol searchOverrides(const std::string &Name)
Search overrided symbols.
APInt operator*(APInt a, uint64_t RHS)
Definition: APInt.h:2084
This class provides a portable interface to dynamic libraries which also might be known as shared lib...
CXXDestructorDataPairList DSOHandleOverride
iterator_range< CtorDtorIterator > getDestructors(const Module &M)
Create an iterator range over the entries of the llvm.global_ctors array.
bool operator==(const SymbolStringPtr &LHS, const SymbolStringPtr &RHS)
uint64_t JITTargetAddress
Represents an address in the target process&#39;s address space.
Definition: JITSymbol.h:40
Error runViaLayer(JITLayerT &JITLayer) const
Run the recorded constructors/destructors through the given JIT layer.
static Expected< JITTargetMachineBuilder > detectHost()
Convenience class for recording constructor/destructor names for later execution. ...
#define P(N)
CtorDtorRunner(std::vector< std::string > CtorDtorNames, VModuleKey K)
Construct a CtorDtorRunner for the given range using the given name mangling function.
std::function< bool(SymbolStringPtr)> SymbolPredicate
Support class for static dtor execution.
JITTargetMachineBuilder & addFeatures(const std::vector< std::string > &FeatureVec)
std::pair< DestructorPtr, void * > CXXDestructorDataPair
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
A utility class to expose symbols found via dlsym to the JIT.
static ErrorSuccess success()
Create a success value.
Definition: Error.h:321
This iterator provides a convenient way to iterate over the elements of an llvm.global_ctors/llvm.global_dtors instance.
A range adaptor for a pair of iterators.
ConstantArray - Constant Array Declarations.
Definition: Constants.h:410
Manages the enabling and disabling of subtarget specific features.
Represents a symbol that has been evaluated to an address already.
Definition: JITSymbol.h:157
JITTargetMachineBuilder & setCPU(std::string CPU)
amdgpu Simplify well known AMD library false Value Value * Arg
LocalCXXRuntimeOverrides(const MangleFtorT &Mangle)
Create a runtime-overrides class.
Expected< std::unique_ptr< TargetMachine > > createTargetMachine()
iterator_range< CtorDtorIterator > getConstructors(const Module &M)
Create an iterator range over the entries of the llvm.global_ctors array.
#define I(x, y, z)
Definition: MD5.cpp:58
JITTargetMachineBuilder & setArch(std::string Arch)
JITTargetMachineBuilder & setCodeModel(Optional< CodeModel::Model > CM)
LLVM Value Representation.
Definition: Value.h:73
Lightweight error class with error context and mandatory checking.
Definition: Error.h:156
std::set< SymbolStringPtr > SymbolNameSet
A set of symbol names (represented by SymbolStringPtrs for.
Definition: Core.h:44
A utility class for building TargetMachines for JITs.