LLVM  8.0.1
IndirectionUtils.cpp
Go to the documentation of this file.
1 //===---- IndirectionUtils.cpp - Utilities for call indirection in Orc ----===//
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 
11 #include "llvm/ADT/STLExtras.h"
12 #include "llvm/ADT/Triple.h"
14 #include "llvm/IR/CallSite.h"
15 #include "llvm/IR/IRBuilder.h"
16 #include "llvm/Support/Format.h"
18 #include <sstream>
19 
20 using namespace llvm;
21 using namespace llvm::orc;
22 
23 namespace {
24 
25 class CompileCallbackMaterializationUnit : public orc::MaterializationUnit {
26 public:
27  using CompileFunction = JITCompileCallbackManager::CompileFunction;
28 
29  CompileCallbackMaterializationUnit(SymbolStringPtr Name,
30  CompileFunction Compile, VModuleKey K)
32  std::move(K)),
33  Name(std::move(Name)), Compile(std::move(Compile)) {}
34 
35  StringRef getName() const override { return "<Compile Callbacks>"; }
36 
37 private:
38  void materialize(MaterializationResponsibility R) override {
40  Result[Name] = JITEvaluatedSymbol(Compile(), JITSymbolFlags::Exported);
41  R.resolve(Result);
42  R.emit();
43  }
44 
45  void discard(const JITDylib &JD, const SymbolStringPtr &Name) override {
46  llvm_unreachable("Discard should never occur on a LMU?");
47  }
48 
50  CompileFunction Compile;
51 };
52 
53 } // namespace
54 
55 namespace llvm {
56 namespace orc {
57 
58 void IndirectStubsManager::anchor() {}
59 void TrampolinePool::anchor() {}
60 
63  if (auto TrampolineAddr = TP->getTrampoline()) {
64  auto CallbackName =
65  ES.intern(std::string("cc") + std::to_string(++NextCallbackId));
66 
67  std::lock_guard<std::mutex> Lock(CCMgrMutex);
68  AddrToSymbol[*TrampolineAddr] = CallbackName;
69  cantFail(CallbacksJD.define(
70  llvm::make_unique<CompileCallbackMaterializationUnit>(
71  std::move(CallbackName), std::move(Compile),
72  ES.allocateVModule())));
73  return *TrampolineAddr;
74  } else
75  return TrampolineAddr.takeError();
76 }
77 
79  JITTargetAddress TrampolineAddr) {
81 
82  {
83  std::unique_lock<std::mutex> Lock(CCMgrMutex);
84  auto I = AddrToSymbol.find(TrampolineAddr);
85 
86  // If this address is not associated with a compile callback then report an
87  // error to the execution session and return ErrorHandlerAddress to the
88  // callee.
89  if (I == AddrToSymbol.end()) {
90  Lock.unlock();
91  std::string ErrMsg;
92  {
93  raw_string_ostream ErrMsgStream(ErrMsg);
94  ErrMsgStream << "No compile callback for trampoline at "
95  << format("0x%016" PRIx64, TrampolineAddr);
96  }
97  ES.reportError(
98  make_error<StringError>(std::move(ErrMsg), inconvertibleErrorCode()));
99  return ErrorHandlerAddress;
100  } else
101  Name = I->second;
102  }
103 
104  if (auto Sym = ES.lookup(JITDylibSearchList({{&CallbacksJD, true}}), Name))
105  return Sym->getAddress();
106  else {
107  llvm::dbgs() << "Didn't find callback.\n";
108  // If anything goes wrong materializing Sym then report it to the session
109  // and return the ErrorHandlerAddress;
110  ES.reportError(Sym.takeError());
111  return ErrorHandlerAddress;
112  }
113 }
114 
117  JITTargetAddress ErrorHandlerAddress) {
118  switch (T.getArch()) {
119  default:
120  return make_error<StringError>(
121  std::string("No callback manager available for ") + T.str(),
123  case Triple::aarch64: {
125  return CCMgrT::Create(ES, ErrorHandlerAddress);
126  }
127 
128  case Triple::x86: {
130  return CCMgrT::Create(ES, ErrorHandlerAddress);
131  }
132 
133  case Triple::mips: {
135  return CCMgrT::Create(ES, ErrorHandlerAddress);
136  }
137  case Triple::mipsel: {
139  return CCMgrT::Create(ES, ErrorHandlerAddress);
140  }
141 
142  case Triple::mips64:
143  case Triple::mips64el: {
145  return CCMgrT::Create(ES, ErrorHandlerAddress);
146  }
147 
148  case Triple::x86_64: {
149  if ( T.getOS() == Triple::OSType::Win32 ) {
151  return CCMgrT::Create(ES, ErrorHandlerAddress);
152  } else {
154  return CCMgrT::Create(ES, ErrorHandlerAddress);
155  }
156  }
157 
158  }
159 }
160 
161 std::function<std::unique_ptr<IndirectStubsManager>()>
163  switch (T.getArch()) {
164  default:
165  return [](){
166  return llvm::make_unique<
168  };
169 
170  case Triple::aarch64:
171  return [](){
172  return llvm::make_unique<
174  };
175 
176  case Triple::x86:
177  return [](){
178  return llvm::make_unique<
180  };
181 
182  case Triple::mips:
183  return [](){
184  return llvm::make_unique<
186  };
187 
188  case Triple::mipsel:
189  return [](){
190  return llvm::make_unique<
192  };
193 
194  case Triple::mips64:
195  case Triple::mips64el:
196  return [](){
197  return llvm::make_unique<
199  };
200 
201  case Triple::x86_64:
202  if (T.getOS() == Triple::OSType::Win32) {
203  return [](){
204  return llvm::make_unique<
206  };
207  } else {
208  return [](){
209  return llvm::make_unique<
211  };
212  }
213 
214  }
215 }
216 
218  Constant *AddrIntVal =
220  Constant *AddrPtrVal =
221  ConstantExpr::getCast(Instruction::IntToPtr, AddrIntVal,
222  PointerType::get(&FT, 0));
223  return AddrPtrVal;
224 }
225 
227  const Twine &Name, Constant *Initializer) {
228  auto IP = new GlobalVariable(M, &PT, false, GlobalValue::ExternalLinkage,
229  Initializer, Name, nullptr,
230  GlobalValue::NotThreadLocal, 0, true);
231  IP->setVisibility(GlobalValue::HiddenVisibility);
232  return IP;
233 }
234 
235 void makeStub(Function &F, Value &ImplPointer) {
236  assert(F.isDeclaration() && "Can't turn a definition into a stub.");
237  assert(F.getParent() && "Function isn't in a module.");
238  Module &M = *F.getParent();
239  BasicBlock *EntryBlock = BasicBlock::Create(M.getContext(), "entry", &F);
240  IRBuilder<> Builder(EntryBlock);
241  LoadInst *ImplAddr = Builder.CreateLoad(&ImplPointer);
242  std::vector<Value*> CallArgs;
243  for (auto &A : F.args())
244  CallArgs.push_back(&A);
245  CallInst *Call = Builder.CreateCall(ImplAddr, CallArgs);
246  Call->setTailCall();
247  Call->setAttributes(F.getAttributes());
248  if (F.getReturnType()->isVoidTy())
249  Builder.CreateRetVoid();
250  else
251  Builder.CreateRet(Call);
252 }
253 
254 std::vector<GlobalValue *> SymbolLinkagePromoter::operator()(Module &M) {
255  std::vector<GlobalValue *> PromotedGlobals;
256 
257  for (auto &GV : M.global_values()) {
258  bool Promoted = true;
259 
260  // Rename if necessary.
261  if (!GV.hasName())
262  GV.setName("__orc_anon." + Twine(NextId++));
263  else if (GV.getName().startswith("\01L"))
264  GV.setName("__" + GV.getName().substr(1) + "." + Twine(NextId++));
265  else if (GV.hasLocalLinkage())
266  GV.setName("__orc_lcl." + GV.getName() + "." + Twine(NextId++));
267  else
268  Promoted = false;
269 
270  if (GV.hasLocalLinkage()) {
271  GV.setLinkage(GlobalValue::ExternalLinkage);
272  GV.setVisibility(GlobalValue::HiddenVisibility);
273  Promoted = true;
274  }
275  GV.setUnnamedAddr(GlobalValue::UnnamedAddr::None);
276 
277  if (Promoted)
278  PromotedGlobals.push_back(&GV);
279  }
280 
281  return PromotedGlobals;
282 }
283 
285  ValueToValueMapTy *VMap) {
286  Function *NewF =
287  Function::Create(cast<FunctionType>(F.getValueType()),
288  F.getLinkage(), F.getName(), &Dst);
289  NewF->copyAttributesFrom(&F);
290 
291  if (VMap) {
292  (*VMap)[&F] = NewF;
293  auto NewArgI = NewF->arg_begin();
294  for (auto ArgI = F.arg_begin(), ArgE = F.arg_end(); ArgI != ArgE;
295  ++ArgI, ++NewArgI)
296  (*VMap)[&*ArgI] = &*NewArgI;
297  }
298 
299  return NewF;
300 }
301 
303  ValueMaterializer *Materializer,
304  Function *NewF) {
305  assert(!OrigF.isDeclaration() && "Nothing to move");
306  if (!NewF)
307  NewF = cast<Function>(VMap[&OrigF]);
308  else
309  assert(VMap[&OrigF] == NewF && "Incorrect function mapping in VMap.");
310  assert(NewF && "Function mapping missing from VMap.");
311  assert(NewF->getParent() != OrigF.getParent() &&
312  "moveFunctionBody should only be used to move bodies between "
313  "modules.");
314 
315  SmallVector<ReturnInst *, 8> Returns; // Ignore returns cloned.
316  CloneFunctionInto(NewF, &OrigF, VMap, /*ModuleLevelChanges=*/true, Returns,
317  "", nullptr, nullptr, Materializer);
318  OrigF.deleteBody();
319 }
320 
322  ValueToValueMapTy *VMap) {
323  GlobalVariable *NewGV = new GlobalVariable(
324  Dst, GV.getValueType(), GV.isConstant(),
325  GV.getLinkage(), nullptr, GV.getName(), nullptr,
327  NewGV->copyAttributesFrom(&GV);
328  if (VMap)
329  (*VMap)[&GV] = NewGV;
330  return NewGV;
331 }
332 
334  ValueToValueMapTy &VMap,
335  ValueMaterializer *Materializer,
336  GlobalVariable *NewGV) {
337  assert(OrigGV.hasInitializer() && "Nothing to move");
338  if (!NewGV)
339  NewGV = cast<GlobalVariable>(VMap[&OrigGV]);
340  else
341  assert(VMap[&OrigGV] == NewGV &&
342  "Incorrect global variable mapping in VMap.");
343  assert(NewGV->getParent() != OrigGV.getParent() &&
344  "moveGlobalVariableInitializer should only be used to move "
345  "initializers between modules");
346 
347  NewGV->setInitializer(MapValue(OrigGV.getInitializer(), VMap, RF_None,
348  nullptr, Materializer));
349 }
350 
352  ValueToValueMapTy &VMap) {
353  assert(OrigA.getAliasee() && "Original alias doesn't have an aliasee?");
354  auto *NewA = GlobalAlias::create(OrigA.getValueType(),
355  OrigA.getType()->getPointerAddressSpace(),
356  OrigA.getLinkage(), OrigA.getName(), &Dst);
357  NewA->copyAttributesFrom(&OrigA);
358  VMap[&OrigA] = NewA;
359  return NewA;
360 }
361 
362 void cloneModuleFlagsMetadata(Module &Dst, const Module &Src,
363  ValueToValueMapTy &VMap) {
364  auto *MFs = Src.getModuleFlagsMetadata();
365  if (!MFs)
366  return;
367  for (auto *MF : MFs->operands())
368  Dst.addModuleFlag(MapMetadata(MF, VMap));
369 }
370 
371 } // End namespace orc.
372 } // End namespace llvm.
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
Definition: Error.h:704
ThreadLocalMode getThreadLocalMode() const
Definition: GlobalValue.h:255
IndirectStubsManager implementation for the host architecture, e.g.
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
void emit()
Notifies the target JITDylib (and any pending queries on that JITDylib) that all symbols covered by t...
Definition: Core.cpp:415
This class represents lattice values for constants.
Definition: AllocatorList.h:24
std::function< std::unique_ptr< IndirectStubsManager >)> createLocalIndirectStubsManagerBuilder(const Triple &T)
Create a local indriect stubs manager builder.
GlobalAlias * cloneGlobalAliasDecl(Module &Dst, const GlobalAlias &OrigA, ValueToValueMapTy &VMap)
Clone a global alias declaration into a new module.
A Module instance is used to store all the information related to an LLVM module. ...
Definition: Module.h:65
OSType getOS() const
getOS - Get the parsed operating system type of this triple.
Definition: Triple.h:299
void cloneModuleFlagsMetadata(Module &Dst, const Module &Src, ValueToValueMapTy &VMap)
Clone module flags metadata into the destination module.
This class represents a function call, abstracting a target machine&#39;s calling convention.
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Definition: Format.h:124
static PointerType * get(Type *ElementType, unsigned AddressSpace)
This constructs a pointer to an object of the specified type in a numbered address space...
Definition: Type.cpp:630
static sys::Mutex Lock
Externally visible function.
Definition: GlobalValue.h:49
arg_iterator arg_end()
Definition: Function.h:680
F(f)
unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
Definition: DerivedTypes.h:503
An instruction for reading from memory.
Definition: Instructions.h:168
static IntegerType * getInt64Ty(LLVMContext &C)
Definition: Type.cpp:177
std::enable_if<!std::is_array< T >::value, std::unique_ptr< T > >::type make_unique(Args &&... args)
Constructs a new T() with the given args and returns a unique_ptr<T> which owns the object...
Definition: STLExtras.h:1349
Manage compile callbacks for in-process JITs.
uint64_t VModuleKey
VModuleKey provides a unique identifier (allocated and managed by ExecutionSessions) for a module add...
Definition: Core.h:40
Metadata * MapMetadata(const Metadata *MD, ValueToValueMapTy &VM, RemapFlags Flags=RF_None, ValueMapTypeRemapper *TypeMapper=nullptr, ValueMaterializer *Materializer=nullptr)
Lookup or compute a mapping for a piece of metadata.
Definition: ValueMapper.h:228
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
Definition: Type.h:130
void CloneFunctionInto(Function *NewFunc, const Function *OldFunc, ValueToValueMapTy &VMap, bool ModuleLevelChanges, SmallVectorImpl< ReturnInst *> &Returns, const char *NameSuffix="", ClonedCodeInfo *CodeInfo=nullptr, ValueMapTypeRemapper *TypeMapper=nullptr, ValueMaterializer *Materializer=nullptr)
Clone OldFunc into NewFunc, transforming the old arguments into references to VMap values...
amdgpu Simplify well known AMD library false Value Value const Twine & Name
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
void copyAttributesFrom(const GlobalValue *Src)
Definition: GlobalAlias.h:62
void setInitializer(Constant *InitVal)
setInitializer - Sets the initializer for this global variable, removing any existing initializer if ...
Definition: Globals.cpp:363
GlobalVariable * createImplPointer(PointerType &PT, Module &M, const Twine &Name, Constant *Initializer)
Create a function pointer with the given type, name, and initializer in the given Module...
bool isConstant() const
If the value is a global constant, its value is immutable throughout the runtime execution of the pro...
std::vector< std::pair< JITDylib *, bool > > JITDylibSearchList
A list of (JITDylib*, bool) pairs.
Definition: Core.h:58
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition: IRBuilder.h:743
static StringRef getName(Value *V)
void moveGlobalVariableInitializer(GlobalVariable &OrigGV, ValueToValueMapTy &VMap, ValueMaterializer *Materializer=nullptr, GlobalVariable *NewGV=nullptr)
Move global variable GV from its parent module to cloned global declaration in a different module...
Tagged union holding either a T or a Error.
Definition: CachePruning.h:23
void makeStub(Function &F, Value &ImplPointer)
Turn a function declaration into a stub function that makes an indirect call using the given function...
Tracks responsibility for materialization, and mediates interactions between MaterializationUnits and...
Definition: Core.h:155
std::vector< GlobalValue * > operator()(Module &M)
Promote symbols in the given module.
Class to represent function types.
Definition: DerivedTypes.h:103
ArchType getArch() const
getArch - Get the parsed architecture type of this triple.
Definition: Triple.h:290
AttributeList getAttributes() const
Return the attribute list for this Function.
Definition: Function.h:224
uint64_t JITTargetAddress
Represents an address in the target process&#39;s address space.
Definition: JITSymbol.h:41
LinkageTypes getLinkage() const
Definition: GlobalValue.h:451
const std::string & str() const
Definition: Triple.h:359
GlobalVariable * cloneGlobalVariableDecl(Module &Dst, const GlobalVariable &GV, ValueToValueMapTy *VMap=nullptr)
Clone a global variable declaration into a new module.
Class to represent pointers.
Definition: DerivedTypes.h:467
Pointer to a pooled string representing a symbol name.
bool isVoidTy() const
Return true if this is &#39;void&#39;.
Definition: Type.h:141
This is a class that can be implemented by clients to materialize Values on demand.
Definition: ValueMapper.h:51
Type * getReturnType() const
Returns the type of the ret val.
Definition: Function.h:169
void getModuleFlagsMetadata(SmallVectorImpl< ModuleFlagEntry > &Flags) const
Returns the module flags in the provided vector.
Definition: Module.cpp:292
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
Definition: Function.h:136
LLVM Basic Block Representation.
Definition: BasicBlock.h:58
void deleteBody()
deleteBody - This method deletes the body of the function, and converts the linkage to external...
Definition: Function.h:609
This is an important base class in LLVM.
Definition: Constant.h:42
void copyAttributesFrom(const Function *Src)
copyAttributesFrom - copy all additional attributes (those not needed to create a Function) from the ...
Definition: Function.cpp:484
void addModuleFlag(ModFlagBehavior Behavior, StringRef Key, Metadata *Val)
Add a module-level flag to the module-level flags metadata.
Definition: Module.cpp:339
unsigned getAddressSpace() const
Return the address space of the Pointer type.
Definition: DerivedTypes.h:495
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition: BasicBlock.h:100
arg_iterator arg_begin()
Definition: Function.h:671
void setTailCall(bool isTC=true)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Value * MapValue(const Value *V, ValueToValueMapTy &VM, RemapFlags Flags=RF_None, ValueMapTypeRemapper *TypeMapper=nullptr, ValueMaterializer *Materializer=nullptr)
Look up or compute a value in the value map.
Definition: ValueMapper.h:206
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
Constant * createIRTypedAddress(FunctionType &FT, JITTargetAddress Addr)
Build a function pointer of FunctionType with the given constant address.
std::function< JITTargetAddress()> CompileFunction
A MaterializationUnit represents a set of symbol definitions that can be materialized as a group...
Definition: Core.h:252
See the file comment.
Definition: ValueMap.h:86
Function * cloneFunctionDecl(Module &Dst, const Function &F, ValueToValueMapTy *VMap=nullptr)
Clone a function declaration into a new module.
void resolve(const SymbolMap &Symbols)
Notifies the target JITDylib that the given symbols have been resolved.
Definition: Core.cpp:393
Expected< std::unique_ptr< JITCompileCallbackManager > > createLocalCompileCallbackManager(const Triple &T, ExecutionSession &ES, JITTargetAddress ErrorHandlerAddress)
Create a local compile callback manager.
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:847
static Constant * get(Type *Ty, uint64_t V, bool isSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
Definition: Constants.cpp:622
Expected< JITTargetAddress > getCompileCallback(CompileFunction Compile)
Reserve a compile callback.
An ExecutionSession represents a running JIT program.
Definition: Core.h:697
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:133
Represents a symbol that has been evaluated to an address already.
Definition: JITSymbol.h:209
static Constant * getCast(unsigned ops, Constant *C, Type *Ty, bool OnlyIfReduced=false)
Convenience function for getting a Cast operation.
Definition: Constants.cpp:1530
JITTargetAddress executeCompileCallback(JITTargetAddress TrampolineAddr)
Execute the callback for the given trampoline id.
StringRef getName() const
Return a constant reference to the value&#39;s name.
Definition: Value.cpp:214
void copyAttributesFrom(const GlobalVariable *Src)
copyAttributesFrom - copy all additional attributes (those not needed to create a GlobalVariable) fro...
Definition: Globals.cpp:386
#define I(x, y, z)
Definition: MD5.cpp:58
void setAttributes(AttributeList A)
Set the parameter attributes for this call.
Definition: InstrTypes.h:1248
Type * getValueType() const
Definition: GlobalValue.h:276
const std::string to_string(const T &Value)
Definition: ScopedPrinter.h:62
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
Definition: Globals.cpp:206
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:483
Module * getParent()
Get the module that this global value is contained inside of...
Definition: GlobalValue.h:566
LLVM Value Representation.
Definition: Value.h:73
bool hasInitializer() const
Definitions have initializers, declarations don&#39;t.
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
iterator_range< global_value_iterator > global_values()
Definition: Module.h:685
void moveFunctionBody(Function &OrigF, ValueToValueMapTy &VMap, ValueMaterializer *Materializer=nullptr, Function *NewF=nullptr)
Move the body of function &#39;F&#39; to a cloned function declaration in a different module (See related clo...
static GlobalAlias * create(Type *Ty, unsigned AddressSpace, LinkageTypes Linkage, const Twine &Name, Constant *Aliasee, Module *Parent)
If a parent module is specified, the alias is automatically inserted into the end of the specified mo...
Definition: Globals.cpp:423
PointerType * getType() const
Global values are always pointers.
Definition: GlobalValue.h:274
iterator_range< arg_iterator > args()
Definition: Function.h:689
A symbol table that supports asynchoronous symbol queries.
Definition: Core.h:496
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Definition: Error.cpp:78
const Constant * getAliasee() const
Definition: GlobalAlias.h:78