LLVM  10.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  // No dependencies, so these calls cannot fail.
41  cantFail(R.notifyResolved(Result));
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  std::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:
124  case Triple::aarch64_32: {
126  return CCMgrT::Create(ES, ErrorHandlerAddress);
127  }
128 
129  case Triple::x86: {
131  return CCMgrT::Create(ES, ErrorHandlerAddress);
132  }
133 
134  case Triple::mips: {
136  return CCMgrT::Create(ES, ErrorHandlerAddress);
137  }
138  case Triple::mipsel: {
140  return CCMgrT::Create(ES, ErrorHandlerAddress);
141  }
142 
143  case Triple::mips64:
144  case Triple::mips64el: {
146  return CCMgrT::Create(ES, ErrorHandlerAddress);
147  }
148 
149  case Triple::x86_64: {
150  if ( T.getOS() == Triple::OSType::Win32 ) {
152  return CCMgrT::Create(ES, ErrorHandlerAddress);
153  } else {
155  return CCMgrT::Create(ES, ErrorHandlerAddress);
156  }
157  }
158 
159  }
160 }
161 
162 std::function<std::unique_ptr<IndirectStubsManager>()>
164  switch (T.getArch()) {
165  default:
166  return [](){
167  return std::make_unique<
169  };
170 
171  case Triple::aarch64:
172  case Triple::aarch64_32:
173  return [](){
174  return std::make_unique<
176  };
177 
178  case Triple::x86:
179  return [](){
180  return std::make_unique<
182  };
183 
184  case Triple::mips:
185  return [](){
186  return std::make_unique<
188  };
189 
190  case Triple::mipsel:
191  return [](){
192  return std::make_unique<
194  };
195 
196  case Triple::mips64:
197  case Triple::mips64el:
198  return [](){
199  return std::make_unique<
201  };
202 
203  case Triple::x86_64:
204  if (T.getOS() == Triple::OSType::Win32) {
205  return [](){
206  return std::make_unique<
208  };
209  } else {
210  return [](){
211  return std::make_unique<
213  };
214  }
215 
216  }
217 }
218 
220  Constant *AddrIntVal =
222  Constant *AddrPtrVal =
223  ConstantExpr::getCast(Instruction::IntToPtr, AddrIntVal,
224  PointerType::get(&FT, 0));
225  return AddrPtrVal;
226 }
227 
229  const Twine &Name, Constant *Initializer) {
230  auto IP = new GlobalVariable(M, &PT, false, GlobalValue::ExternalLinkage,
231  Initializer, Name, nullptr,
232  GlobalValue::NotThreadLocal, 0, true);
233  IP->setVisibility(GlobalValue::HiddenVisibility);
234  return IP;
235 }
236 
237 void makeStub(Function &F, Value &ImplPointer) {
238  assert(F.isDeclaration() && "Can't turn a definition into a stub.");
239  assert(F.getParent() && "Function isn't in a module.");
240  Module &M = *F.getParent();
241  BasicBlock *EntryBlock = BasicBlock::Create(M.getContext(), "entry", &F);
242  IRBuilder<> Builder(EntryBlock);
243  LoadInst *ImplAddr = Builder.CreateLoad(F.getType(), &ImplPointer);
244  std::vector<Value*> CallArgs;
245  for (auto &A : F.args())
246  CallArgs.push_back(&A);
247  CallInst *Call = Builder.CreateCall(F.getFunctionType(), ImplAddr, CallArgs);
248  Call->setTailCall();
249  Call->setAttributes(F.getAttributes());
250  if (F.getReturnType()->isVoidTy())
251  Builder.CreateRetVoid();
252  else
253  Builder.CreateRet(Call);
254 }
255 
256 std::vector<GlobalValue *> SymbolLinkagePromoter::operator()(Module &M) {
257  std::vector<GlobalValue *> PromotedGlobals;
258 
259  for (auto &GV : M.global_values()) {
260  bool Promoted = true;
261 
262  // Rename if necessary.
263  if (!GV.hasName())
264  GV.setName("__orc_anon." + Twine(NextId++));
265  else if (GV.getName().startswith("\01L"))
266  GV.setName("__" + GV.getName().substr(1) + "." + Twine(NextId++));
267  else if (GV.hasLocalLinkage())
268  GV.setName("__orc_lcl." + GV.getName() + "." + Twine(NextId++));
269  else
270  Promoted = false;
271 
272  if (GV.hasLocalLinkage()) {
273  GV.setLinkage(GlobalValue::ExternalLinkage);
274  GV.setVisibility(GlobalValue::HiddenVisibility);
275  Promoted = true;
276  }
277  GV.setUnnamedAddr(GlobalValue::UnnamedAddr::None);
278 
279  if (Promoted)
280  PromotedGlobals.push_back(&GV);
281  }
282 
283  return PromotedGlobals;
284 }
285 
287  ValueToValueMapTy *VMap) {
288  Function *NewF =
289  Function::Create(cast<FunctionType>(F.getValueType()),
290  F.getLinkage(), F.getName(), &Dst);
291  NewF->copyAttributesFrom(&F);
292 
293  if (VMap) {
294  (*VMap)[&F] = NewF;
295  auto NewArgI = NewF->arg_begin();
296  for (auto ArgI = F.arg_begin(), ArgE = F.arg_end(); ArgI != ArgE;
297  ++ArgI, ++NewArgI)
298  (*VMap)[&*ArgI] = &*NewArgI;
299  }
300 
301  return NewF;
302 }
303 
305  ValueMaterializer *Materializer,
306  Function *NewF) {
307  assert(!OrigF.isDeclaration() && "Nothing to move");
308  if (!NewF)
309  NewF = cast<Function>(VMap[&OrigF]);
310  else
311  assert(VMap[&OrigF] == NewF && "Incorrect function mapping in VMap.");
312  assert(NewF && "Function mapping missing from VMap.");
313  assert(NewF->getParent() != OrigF.getParent() &&
314  "moveFunctionBody should only be used to move bodies between "
315  "modules.");
316 
317  SmallVector<ReturnInst *, 8> Returns; // Ignore returns cloned.
318  CloneFunctionInto(NewF, &OrigF, VMap, /*ModuleLevelChanges=*/true, Returns,
319  "", nullptr, nullptr, Materializer);
320  OrigF.deleteBody();
321 }
322 
324  ValueToValueMapTy *VMap) {
325  GlobalVariable *NewGV = new GlobalVariable(
326  Dst, GV.getValueType(), GV.isConstant(),
327  GV.getLinkage(), nullptr, GV.getName(), nullptr,
329  NewGV->copyAttributesFrom(&GV);
330  if (VMap)
331  (*VMap)[&GV] = NewGV;
332  return NewGV;
333 }
334 
336  ValueToValueMapTy &VMap,
337  ValueMaterializer *Materializer,
338  GlobalVariable *NewGV) {
339  assert(OrigGV.hasInitializer() && "Nothing to move");
340  if (!NewGV)
341  NewGV = cast<GlobalVariable>(VMap[&OrigGV]);
342  else
343  assert(VMap[&OrigGV] == NewGV &&
344  "Incorrect global variable mapping in VMap.");
345  assert(NewGV->getParent() != OrigGV.getParent() &&
346  "moveGlobalVariableInitializer should only be used to move "
347  "initializers between modules");
348 
349  NewGV->setInitializer(MapValue(OrigGV.getInitializer(), VMap, RF_None,
350  nullptr, Materializer));
351 }
352 
354  ValueToValueMapTy &VMap) {
355  assert(OrigA.getAliasee() && "Original alias doesn't have an aliasee?");
356  auto *NewA = GlobalAlias::create(OrigA.getValueType(),
357  OrigA.getType()->getPointerAddressSpace(),
358  OrigA.getLinkage(), OrigA.getName(), &Dst);
359  NewA->copyAttributesFrom(&OrigA);
360  VMap[&OrigA] = NewA;
361  return NewA;
362 }
363 
364 void cloneModuleFlagsMetadata(Module &Dst, const Module &Src,
365  ValueToValueMapTy &VMap) {
366  auto *MFs = Src.getModuleFlagsMetadata();
367  if (!MFs)
368  return;
369  for (auto *MF : MFs->operands())
370  Dst.addModuleFlag(MapMetadata(MF, VMap));
371 }
372 
373 } // End namespace orc.
374 } // 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.
Error notifyEmitted()
Notifies the target JITDylib (and any pending queries on that JITDylib) that all symbols covered by t...
Definition: Core.cpp:396
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: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: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
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:228
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 setInitializer(Constant *InitVal)
setInitializer - Sets the initializer for this global variable, removing any existing initializer if ...
Definition: Globals.cpp:388
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:59
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: yaml2obj.h:21
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:171
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
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:41
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)
Error notifyResolved(const SymbolMap &Symbols)
Notifies the target JITDylib that the given symbols have been resolved.
Definition: Core.cpp:375
#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:43
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:282
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.
void copyAttributesFrom(const GlobalValue *Src)
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:653
Expected< JITTargetAddress > getCompileCallback(CompileFunction Compile)
Reserve a compile callback.
An ExecutionSession represents a running JIT program.
Definition: Core.h:761
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:190
static Constant * getCast(unsigned ops, Constant *C, Type *Ty, bool OnlyIfReduced=false)
Convenience function for getting a Cast operation.
Definition: Constants.cpp:1561
uint8_t uint64_t VModuleKey
VModuleKey provides a unique identifier (allocated and managed by ExecutionSessions) for a module add...
Definition: Core.h:42
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:411
#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:231
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:503
Module * getParent()
Get the module that this global value is contained inside of...
Definition: GlobalValue.h:575
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: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:485
PointerType * getType() const
Global values are always pointers.
Definition: GlobalValue.h:277
iterator_range< arg_iterator > args()
Definition: Function.h:719
A symbol table that supports asynchoronous symbol queries.
Definition: Core.h:495
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:73