LLVM  9.0.0svn
IndirectionUtils.cpp
Go to the documentation of this file.
1 //===---- IndirectionUtils.cpp - Utilities for call indirection in Orc ----===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
10 #include "llvm/ADT/STLExtras.h"
11 #include "llvm/ADT/Triple.h"
13 #include "llvm/IR/CallSite.h"
14 #include "llvm/IR/IRBuilder.h"
15 #include "llvm/Support/Format.h"
17 #include <sstream>
18 
19 using namespace llvm;
20 using namespace llvm::orc;
21 
22 namespace {
23 
24 class CompileCallbackMaterializationUnit : public orc::MaterializationUnit {
25 public:
26  using CompileFunction = JITCompileCallbackManager::CompileFunction;
27 
28  CompileCallbackMaterializationUnit(SymbolStringPtr Name,
29  CompileFunction Compile, VModuleKey K)
31  std::move(K)),
32  Name(std::move(Name)), Compile(std::move(Compile)) {}
33 
34  StringRef getName() const override { return "<Compile Callbacks>"; }
35 
36 private:
37  void materialize(MaterializationResponsibility R) override {
39  Result[Name] = JITEvaluatedSymbol(Compile(), JITSymbolFlags::Exported);
40  R.notifyResolved(Result);
41  R.notifyEmitted();
42  }
43 
44  void discard(const JITDylib &JD, const SymbolStringPtr &Name) override {
45  llvm_unreachable("Discard should never occur on a LMU?");
46  }
47 
49  CompileFunction Compile;
50 };
51 
52 } // namespace
53 
54 namespace llvm {
55 namespace orc {
56 
57 void IndirectStubsManager::anchor() {}
58 void TrampolinePool::anchor() {}
59 
62  if (auto TrampolineAddr = TP->getTrampoline()) {
63  auto CallbackName =
64  ES.intern(std::string("cc") + std::to_string(++NextCallbackId));
65 
66  std::lock_guard<std::mutex> Lock(CCMgrMutex);
67  AddrToSymbol[*TrampolineAddr] = CallbackName;
68  cantFail(CallbacksJD.define(
69  llvm::make_unique<CompileCallbackMaterializationUnit>(
70  std::move(CallbackName), std::move(Compile),
71  ES.allocateVModule())));
72  return *TrampolineAddr;
73  } else
74  return TrampolineAddr.takeError();
75 }
76 
78  JITTargetAddress TrampolineAddr) {
80 
81  {
82  std::unique_lock<std::mutex> Lock(CCMgrMutex);
83  auto I = AddrToSymbol.find(TrampolineAddr);
84 
85  // If this address is not associated with a compile callback then report an
86  // error to the execution session and return ErrorHandlerAddress to the
87  // callee.
88  if (I == AddrToSymbol.end()) {
89  Lock.unlock();
90  std::string ErrMsg;
91  {
92  raw_string_ostream ErrMsgStream(ErrMsg);
93  ErrMsgStream << "No compile callback for trampoline at "
94  << format("0x%016" PRIx64, TrampolineAddr);
95  }
96  ES.reportError(
97  make_error<StringError>(std::move(ErrMsg), inconvertibleErrorCode()));
98  return ErrorHandlerAddress;
99  } else
100  Name = I->second;
101  }
102 
103  if (auto Sym = ES.lookup(JITDylibSearchList({{&CallbacksJD, true}}), Name))
104  return Sym->getAddress();
105  else {
106  llvm::dbgs() << "Didn't find callback.\n";
107  // If anything goes wrong materializing Sym then report it to the session
108  // and return the ErrorHandlerAddress;
109  ES.reportError(Sym.takeError());
110  return ErrorHandlerAddress;
111  }
112 }
113 
116  JITTargetAddress ErrorHandlerAddress) {
117  switch (T.getArch()) {
118  default:
119  return make_error<StringError>(
120  std::string("No callback manager available for ") + T.str(),
122  case Triple::aarch64: {
124  return CCMgrT::Create(ES, ErrorHandlerAddress);
125  }
126 
127  case Triple::x86: {
129  return CCMgrT::Create(ES, ErrorHandlerAddress);
130  }
131 
132  case Triple::mips: {
134  return CCMgrT::Create(ES, ErrorHandlerAddress);
135  }
136  case Triple::mipsel: {
138  return CCMgrT::Create(ES, ErrorHandlerAddress);
139  }
140 
141  case Triple::mips64:
142  case Triple::mips64el: {
144  return CCMgrT::Create(ES, ErrorHandlerAddress);
145  }
146 
147  case Triple::x86_64: {
148  if ( T.getOS() == Triple::OSType::Win32 ) {
150  return CCMgrT::Create(ES, ErrorHandlerAddress);
151  } else {
153  return CCMgrT::Create(ES, ErrorHandlerAddress);
154  }
155  }
156 
157  }
158 }
159 
160 std::function<std::unique_ptr<IndirectStubsManager>()>
162  switch (T.getArch()) {
163  default:
164  return [](){
165  return llvm::make_unique<
167  };
168 
169  case Triple::aarch64:
170  return [](){
171  return llvm::make_unique<
173  };
174 
175  case Triple::x86:
176  return [](){
177  return llvm::make_unique<
179  };
180 
181  case Triple::mips:
182  return [](){
183  return llvm::make_unique<
185  };
186 
187  case Triple::mipsel:
188  return [](){
189  return llvm::make_unique<
191  };
192 
193  case Triple::mips64:
194  case Triple::mips64el:
195  return [](){
196  return llvm::make_unique<
198  };
199 
200  case Triple::x86_64:
201  if (T.getOS() == Triple::OSType::Win32) {
202  return [](){
203  return llvm::make_unique<
205  };
206  } else {
207  return [](){
208  return llvm::make_unique<
210  };
211  }
212 
213  }
214 }
215 
217  Constant *AddrIntVal =
219  Constant *AddrPtrVal =
220  ConstantExpr::getCast(Instruction::IntToPtr, AddrIntVal,
221  PointerType::get(&FT, 0));
222  return AddrPtrVal;
223 }
224 
226  const Twine &Name, Constant *Initializer) {
227  auto IP = new GlobalVariable(M, &PT, false, GlobalValue::ExternalLinkage,
228  Initializer, Name, nullptr,
229  GlobalValue::NotThreadLocal, 0, true);
230  IP->setVisibility(GlobalValue::HiddenVisibility);
231  return IP;
232 }
233 
234 void makeStub(Function &F, Value &ImplPointer) {
235  assert(F.isDeclaration() && "Can't turn a definition into a stub.");
236  assert(F.getParent() && "Function isn't in a module.");
237  Module &M = *F.getParent();
238  BasicBlock *EntryBlock = BasicBlock::Create(M.getContext(), "entry", &F);
239  IRBuilder<> Builder(EntryBlock);
240  LoadInst *ImplAddr = Builder.CreateLoad(F.getType(), &ImplPointer);
241  std::vector<Value*> CallArgs;
242  for (auto &A : F.args())
243  CallArgs.push_back(&A);
244  CallInst *Call = Builder.CreateCall(F.getFunctionType(), ImplAddr, CallArgs);
245  Call->setTailCall();
246  Call->setAttributes(F.getAttributes());
247  if (F.getReturnType()->isVoidTy())
248  Builder.CreateRetVoid();
249  else
250  Builder.CreateRet(Call);
251 }
252 
253 std::vector<GlobalValue *> SymbolLinkagePromoter::operator()(Module &M) {
254  std::vector<GlobalValue *> PromotedGlobals;
255 
256  for (auto &GV : M.global_values()) {
257  bool Promoted = true;
258 
259  // Rename if necessary.
260  if (!GV.hasName())
261  GV.setName("__orc_anon." + Twine(NextId++));
262  else if (GV.getName().startswith("\01L"))
263  GV.setName("__" + GV.getName().substr(1) + "." + Twine(NextId++));
264  else if (GV.hasLocalLinkage())
265  GV.setName("__orc_lcl." + GV.getName() + "." + Twine(NextId++));
266  else
267  Promoted = false;
268 
269  if (GV.hasLocalLinkage()) {
270  GV.setLinkage(GlobalValue::ExternalLinkage);
271  GV.setVisibility(GlobalValue::HiddenVisibility);
272  Promoted = true;
273  }
274  GV.setUnnamedAddr(GlobalValue::UnnamedAddr::None);
275 
276  if (Promoted)
277  PromotedGlobals.push_back(&GV);
278  }
279 
280  return PromotedGlobals;
281 }
282 
284  ValueToValueMapTy *VMap) {
285  Function *NewF =
286  Function::Create(cast<FunctionType>(F.getValueType()),
287  F.getLinkage(), F.getName(), &Dst);
288  NewF->copyAttributesFrom(&F);
289 
290  if (VMap) {
291  (*VMap)[&F] = NewF;
292  auto NewArgI = NewF->arg_begin();
293  for (auto ArgI = F.arg_begin(), ArgE = F.arg_end(); ArgI != ArgE;
294  ++ArgI, ++NewArgI)
295  (*VMap)[&*ArgI] = &*NewArgI;
296  }
297 
298  return NewF;
299 }
300 
302  ValueMaterializer *Materializer,
303  Function *NewF) {
304  assert(!OrigF.isDeclaration() && "Nothing to move");
305  if (!NewF)
306  NewF = cast<Function>(VMap[&OrigF]);
307  else
308  assert(VMap[&OrigF] == NewF && "Incorrect function mapping in VMap.");
309  assert(NewF && "Function mapping missing from VMap.");
310  assert(NewF->getParent() != OrigF.getParent() &&
311  "moveFunctionBody should only be used to move bodies between "
312  "modules.");
313 
314  SmallVector<ReturnInst *, 8> Returns; // Ignore returns cloned.
315  CloneFunctionInto(NewF, &OrigF, VMap, /*ModuleLevelChanges=*/true, Returns,
316  "", nullptr, nullptr, Materializer);
317  OrigF.deleteBody();
318 }
319 
321  ValueToValueMapTy *VMap) {
322  GlobalVariable *NewGV = new GlobalVariable(
323  Dst, GV.getValueType(), GV.isConstant(),
324  GV.getLinkage(), nullptr, GV.getName(), nullptr,
326  NewGV->copyAttributesFrom(&GV);
327  if (VMap)
328  (*VMap)[&GV] = NewGV;
329  return NewGV;
330 }
331 
333  ValueToValueMapTy &VMap,
334  ValueMaterializer *Materializer,
335  GlobalVariable *NewGV) {
336  assert(OrigGV.hasInitializer() && "Nothing to move");
337  if (!NewGV)
338  NewGV = cast<GlobalVariable>(VMap[&OrigGV]);
339  else
340  assert(VMap[&OrigGV] == NewGV &&
341  "Incorrect global variable mapping in VMap.");
342  assert(NewGV->getParent() != OrigGV.getParent() &&
343  "moveGlobalVariableInitializer should only be used to move "
344  "initializers between modules");
345 
346  NewGV->setInitializer(MapValue(OrigGV.getInitializer(), VMap, RF_None,
347  nullptr, Materializer));
348 }
349 
351  ValueToValueMapTy &VMap) {
352  assert(OrigA.getAliasee() && "Original alias doesn't have an aliasee?");
353  auto *NewA = GlobalAlias::create(OrigA.getValueType(),
354  OrigA.getType()->getPointerAddressSpace(),
355  OrigA.getLinkage(), OrigA.getName(), &Dst);
356  NewA->copyAttributesFrom(&OrigA);
357  VMap[&OrigA] = NewA;
358  return NewA;
359 }
360 
361 void cloneModuleFlagsMetadata(Module &Dst, const Module &Src,
362  ValueToValueMapTy &VMap) {
363  auto *MFs = Src.getModuleFlagsMetadata();
364  if (!MFs)
365  return;
366  for (auto *MF : MFs->operands())
367  Dst.addModuleFlag(MapMetadata(MF, VMap));
368 }
369 
370 } // End namespace orc.
371 } // End namespace llvm.
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
Definition: Error.h:703
ThreadLocalMode getThreadLocalMode() const
Definition: GlobalValue.h:258
IndirectStubsManager implementation for the host architecture, e.g.
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
This class represents lattice values for constants.
Definition: AllocatorList.h:23
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
amdgpu Simplify well known AMD library false FunctionCallee Value const Twine & Name
OSType getOS() const
getOS - Get the parsed operating system type of this triple.
Definition: Triple.h:305
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:123
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:632
static sys::Mutex Lock
Externally visible function.
Definition: GlobalValue.h:48
arg_iterator arg_end()
Definition: Function.h:704
F(f)
unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
Definition: DerivedTypes.h:580
An instruction for reading from memory.
Definition: Instructions.h:167
static IntegerType * getInt64Ty(LLVMContext &C)
Definition: Type.cpp:176
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:1405
Manage compile callbacks for in-process JITs.
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:227
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
Definition: Type.h:129
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...
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:80
void copyAttributesFrom(const GlobalValue *Src)
Definition: GlobalAlias.h:61
void setInitializer(Constant *InitVal)
setInitializer - Sets the initializer for this global variable, removing any existing initializer if ...
Definition: Globals.cpp:384
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:779
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:22
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:170
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:296
void notifyResolved(const SymbolMap &Symbols)
Notifies the target JITDylib that the given symbols have been resolved.
Definition: Core.cpp:370
AttributeList getAttributes() const
Return the attribute list for this Function.
Definition: Function.h:223
uint64_t JITTargetAddress
Represents an address in the target process&#39;s address space.
Definition: JITSymbol.h:40
LinkageTypes getLinkage() const
Definition: GlobalValue.h:460
const std::string & str() const
Definition: Triple.h:365
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:544
Pointer to a pooled string representing a symbol name.
bool isVoidTy() const
Return true if this is &#39;void&#39;.
Definition: Type.h:140
This is a class that can be implemented by clients to materialize Values on demand.
Definition: ValueMapper.h:50
Type * getReturnType() const
Returns the type of the ret val.
Definition: Function.h:168
void getModuleFlagsMetadata(SmallVectorImpl< ModuleFlagEntry > &Flags) const
Returns the module flags in the provided vector.
Definition: Module.cpp:290
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
Definition: Function.h:135
LLVM Basic Block Representation.
Definition: BasicBlock.h:57
void deleteBody()
deleteBody - This method deletes the body of the function, and converts the linkage to external...
Definition: Function.h:633
This is an important base class in LLVM.
Definition: Constant.h:41
void copyAttributesFrom(const Function *Src)
copyAttributesFrom - copy all additional attributes (those not needed to create a Function) from the ...
Definition: Function.cpp:496
void addModuleFlag(ModFlagBehavior Behavior, StringRef Key, Metadata *Val)
Add a module-level flag to the module-level flags metadata.
Definition: Module.cpp:337
unsigned getAddressSpace() const
Return the address space of the Pointer type.
Definition: DerivedTypes.h:572
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition: BasicBlock.h:99
arg_iterator arg_begin()
Definition: Function.h:695
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:205
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:43
Constant * createIRTypedAddress(FunctionType &FT, JITTargetAddress Addr)
Build a function pointer of FunctionType with the given constant address.
std::function< JITTargetAddress()> CompileFunction
void notifyEmitted()
Notifies the target JITDylib (and any pending queries on that JITDylib) that all symbols covered by t...
Definition: Core.cpp:391
A MaterializationUnit represents a set of symbol definitions that can be materialized as a group...
Definition: Core.h:267
See the file comment.
Definition: ValueMap.h:85
Function * cloneFunctionDecl(Module &Dst, const Function &F, ValueToValueMapTy *VMap=nullptr)
Clone a function declaration into a new module.
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:837
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:631
Expected< JITTargetAddress > getCompileCallback(CompileFunction Compile)
Reserve a compile callback.
An ExecutionSession represents a running JIT program.
Definition: Core.h:752
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
FunctionType * getFunctionType() const
Returns the FunctionType for me.
Definition: Function.h:163
Represents a symbol that has been evaluated to an address already.
Definition: JITSymbol.h:189
static Constant * getCast(unsigned ops, Constant *C, Type *Ty, bool OnlyIfReduced=false)
Convenience function for getting a Cast operation.
Definition: Constants.cpp:1539
uint8_t uint64_t VModuleKey
VModuleKey provides a unique identifier (allocated and managed by ExecutionSessions) for a module add...
Definition: Core.h:40
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:407
#define I(x, y, z)
Definition: MD5.cpp:58
void setAttributes(AttributeList A)
Set the parameter attributes for this call.
Definition: InstrTypes.h:1370
Type * getValueType() const
Definition: GlobalValue.h:279
const std::string to_string(const T &Value)
Definition: ScopedPrinter.h:61
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
Definition: Globals.cpp:227
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:482
Module * getParent()
Get the module that this global value is contained inside of...
Definition: GlobalValue.h:575
LLVM Value Representation.
Definition: Value.h:72
bool hasInitializer() const
Definitions have initializers, declarations don&#39;t.
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
iterator_range< global_value_iterator > global_values()
Definition: Module.h:688
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:444
PointerType * getType() const
Global values are always pointers.
Definition: GlobalValue.h:277
iterator_range< arg_iterator > args()
Definition: Function.h:713
A symbol table that supports asynchoronous symbol queries.
Definition: Core.h:499
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Definition: Error.cpp:77
const Constant * getAliasee() const
Definition: GlobalAlias.h:77