LLVM  8.0.0svn
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)
32  Name(std::move(Name)), Compile(std::move(Compile)) {}
33 
34 private:
35  void materialize(MaterializationResponsibility R) {
37  Result[Name] = JITEvaluatedSymbol(Compile(), JITSymbolFlags::Exported);
38  R.resolve(Result);
39  R.finalize();
40  }
41 
42  void discard(const VSO &V, SymbolStringPtr Name) {
43  llvm_unreachable("Discard should never occur on a LMU?");
44  }
45 
47  CompileFunction Compile;
48 };
49 
50 } // namespace
51 
52 namespace llvm {
53 namespace orc {
54 
55 void JITCompileCallbackManager::anchor() {}
56 void IndirectStubsManager::anchor() {}
57 
60  if (auto TrampolineAddr = getAvailableTrampolineAddr()) {
61  auto CallbackName = ES.getSymbolStringPool().intern(
62  std::string("cc") + std::to_string(++NextCallbackId));
63 
64  std::lock_guard<std::mutex> Lock(CCMgrMutex);
65  AddrToSymbol[*TrampolineAddr] = CallbackName;
66  cantFail(CallbacksVSO.define(
67  llvm::make_unique<CompileCallbackMaterializationUnit>(
68  std::move(CallbackName), std::move(Compile))));
69  return *TrampolineAddr;
70  } else
71  return TrampolineAddr.takeError();
72 }
73 
75  JITTargetAddress TrampolineAddr) {
77 
78  {
79  std::unique_lock<std::mutex> Lock(CCMgrMutex);
80  auto I = AddrToSymbol.find(TrampolineAddr);
81 
82  // If this address is not associated with a compile callback then report an
83  // error to the execution session and return ErrorHandlerAddress to the
84  // callee.
85  if (I == AddrToSymbol.end()) {
86  Lock.unlock();
87  std::string ErrMsg;
88  {
89  raw_string_ostream ErrMsgStream(ErrMsg);
90  ErrMsgStream << "No compile callback for trampoline at "
91  << format("0x%016x", TrampolineAddr);
92  }
93  ES.reportError(
94  make_error<StringError>(std::move(ErrMsg), inconvertibleErrorCode()));
95  return ErrorHandlerAddress;
96  } else
97  Name = I->second;
98  }
99 
100  if (auto Sym = lookup({&CallbacksVSO}, Name))
101  return Sym->getAddress();
102  else {
103  // If anything goes wrong materializing Sym then report it to the session
104  // and return the ErrorHandlerAddress;
105  ES.reportError(Sym.takeError());
106  return ErrorHandlerAddress;
107  }
108 }
109 
110 std::unique_ptr<JITCompileCallbackManager>
112  JITTargetAddress ErrorHandlerAddress) {
113  switch (T.getArch()) {
114  default: return nullptr;
115 
116  case Triple::aarch64: {
118  return llvm::make_unique<CCMgrT>(ES, ErrorHandlerAddress);
119  }
120 
121  case Triple::x86: {
123  return llvm::make_unique<CCMgrT>(ES, ErrorHandlerAddress);
124  }
125 
126  case Triple::x86_64: {
127  if ( T.getOS() == Triple::OSType::Win32 ) {
129  return llvm::make_unique<CCMgrT>(ES, ErrorHandlerAddress);
130  } else {
132  return llvm::make_unique<CCMgrT>(ES, ErrorHandlerAddress);
133  }
134  }
135 
136  }
137 }
138 
139 std::function<std::unique_ptr<IndirectStubsManager>()>
141  switch (T.getArch()) {
142  default:
143  return [](){
144  return llvm::make_unique<
146  };
147 
148  case Triple::aarch64:
149  return [](){
150  return llvm::make_unique<
152  };
153 
154  case Triple::x86:
155  return [](){
156  return llvm::make_unique<
158  };
159 
160  case Triple::x86_64:
161  if (T.getOS() == Triple::OSType::Win32) {
162  return [](){
163  return llvm::make_unique<
165  };
166  } else {
167  return [](){
168  return llvm::make_unique<
170  };
171  }
172 
173  }
174 }
175 
177  Constant *AddrIntVal =
179  Constant *AddrPtrVal =
180  ConstantExpr::getCast(Instruction::IntToPtr, AddrIntVal,
181  PointerType::get(&FT, 0));
182  return AddrPtrVal;
183 }
184 
186  const Twine &Name, Constant *Initializer) {
187  auto IP = new GlobalVariable(M, &PT, false, GlobalValue::ExternalLinkage,
188  Initializer, Name, nullptr,
189  GlobalValue::NotThreadLocal, 0, true);
190  IP->setVisibility(GlobalValue::HiddenVisibility);
191  return IP;
192 }
193 
194 void makeStub(Function &F, Value &ImplPointer) {
195  assert(F.isDeclaration() && "Can't turn a definition into a stub.");
196  assert(F.getParent() && "Function isn't in a module.");
197  Module &M = *F.getParent();
198  BasicBlock *EntryBlock = BasicBlock::Create(M.getContext(), "entry", &F);
199  IRBuilder<> Builder(EntryBlock);
200  LoadInst *ImplAddr = Builder.CreateLoad(&ImplPointer);
201  std::vector<Value*> CallArgs;
202  for (auto &A : F.args())
203  CallArgs.push_back(&A);
204  CallInst *Call = Builder.CreateCall(ImplAddr, CallArgs);
205  Call->setTailCall();
206  Call->setAttributes(F.getAttributes());
207  if (F.getReturnType()->isVoidTy())
208  Builder.CreateRetVoid();
209  else
210  Builder.CreateRet(Call);
211 }
212 
213 // Utility class for renaming global values and functions during partitioning.
215 public:
216 
217  static bool needsRenaming(const Value &New) {
218  return !New.hasName() || New.getName().startswith("\01L");
219  }
220 
221  const std::string& getRename(const Value &Orig) {
222  // See if we have a name for this global.
223  {
224  auto I = Names.find(&Orig);
225  if (I != Names.end())
226  return I->second;
227  }
228 
229  // Nope. Create a new one.
230  // FIXME: Use a more robust uniquing scheme. (This may blow up if the user
231  // writes a "__orc_anon[[:digit:]]* method).
232  unsigned ID = Names.size();
233  std::ostringstream NameStream;
234  NameStream << "__orc_anon" << ID++;
235  auto I = Names.insert(std::make_pair(&Orig, NameStream.str()));
236  return I.first->second;
237  }
238 private:
240 };
241 
243  if (V.hasLocalLinkage()) {
244  if (R.needsRenaming(V))
245  V.setName(R.getRename(V));
248  }
250  assert(!R.needsRenaming(V) && "Invalid global name.");
251 }
252 
254  GlobalRenamer Renamer;
255 
256  for (auto &F : M)
257  raiseVisibilityOnValue(F, Renamer);
258 
259  for (auto &GV : M.globals())
260  raiseVisibilityOnValue(GV, Renamer);
261 
262  for (auto &A : M.aliases())
263  raiseVisibilityOnValue(A, Renamer);
264 }
265 
267  ValueToValueMapTy *VMap) {
268  Function *NewF =
269  Function::Create(cast<FunctionType>(F.getValueType()),
270  F.getLinkage(), F.getName(), &Dst);
271  NewF->copyAttributesFrom(&F);
272 
273  if (VMap) {
274  (*VMap)[&F] = NewF;
275  auto NewArgI = NewF->arg_begin();
276  for (auto ArgI = F.arg_begin(), ArgE = F.arg_end(); ArgI != ArgE;
277  ++ArgI, ++NewArgI)
278  (*VMap)[&*ArgI] = &*NewArgI;
279  }
280 
281  return NewF;
282 }
283 
285  ValueMaterializer *Materializer,
286  Function *NewF) {
287  assert(!OrigF.isDeclaration() && "Nothing to move");
288  if (!NewF)
289  NewF = cast<Function>(VMap[&OrigF]);
290  else
291  assert(VMap[&OrigF] == NewF && "Incorrect function mapping in VMap.");
292  assert(NewF && "Function mapping missing from VMap.");
293  assert(NewF->getParent() != OrigF.getParent() &&
294  "moveFunctionBody should only be used to move bodies between "
295  "modules.");
296 
297  SmallVector<ReturnInst *, 8> Returns; // Ignore returns cloned.
298  CloneFunctionInto(NewF, &OrigF, VMap, /*ModuleLevelChanges=*/true, Returns,
299  "", nullptr, nullptr, Materializer);
300  OrigF.deleteBody();
301 }
302 
304  ValueToValueMapTy *VMap) {
305  GlobalVariable *NewGV = new GlobalVariable(
306  Dst, GV.getValueType(), GV.isConstant(),
307  GV.getLinkage(), nullptr, GV.getName(), nullptr,
309  NewGV->copyAttributesFrom(&GV);
310  if (VMap)
311  (*VMap)[&GV] = NewGV;
312  return NewGV;
313 }
314 
316  ValueToValueMapTy &VMap,
317  ValueMaterializer *Materializer,
318  GlobalVariable *NewGV) {
319  assert(OrigGV.hasInitializer() && "Nothing to move");
320  if (!NewGV)
321  NewGV = cast<GlobalVariable>(VMap[&OrigGV]);
322  else
323  assert(VMap[&OrigGV] == NewGV &&
324  "Incorrect global variable mapping in VMap.");
325  assert(NewGV->getParent() != OrigGV.getParent() &&
326  "moveGlobalVariableInitializer should only be used to move "
327  "initializers between modules");
328 
329  NewGV->setInitializer(MapValue(OrigGV.getInitializer(), VMap, RF_None,
330  nullptr, Materializer));
331 }
332 
334  ValueToValueMapTy &VMap) {
335  assert(OrigA.getAliasee() && "Original alias doesn't have an aliasee?");
336  auto *NewA = GlobalAlias::create(OrigA.getValueType(),
337  OrigA.getType()->getPointerAddressSpace(),
338  OrigA.getLinkage(), OrigA.getName(), &Dst);
339  NewA->copyAttributesFrom(&OrigA);
340  VMap[&OrigA] = NewA;
341  return NewA;
342 }
343 
344 void cloneModuleFlagsMetadata(Module &Dst, const Module &Src,
345  ValueToValueMapTy &VMap) {
346  auto *MFs = Src.getModuleFlagsMetadata();
347  if (!MFs)
348  return;
349  for (auto *MF : MFs->operands())
350  Dst.addModuleFlag(MapMetadata(MF, VMap));
351 }
352 
353 } // End namespace orc.
354 } // End namespace llvm.
void setVisibility(VisibilityTypes V)
Definition: GlobalValue.h:238
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
Definition: Error.h:697
ThreadLocalMode getThreadLocalMode() const
Definition: GlobalValue.h:254
bool hasLocalLinkage() const
Definition: GlobalValue.h:435
IndirectStubsManager implementation for the host architecture, e.g.
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
Compute iterated dominance frontiers using a linear time algorithm.
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:63
A symbol table that supports asynchoronous symbol queries.
Definition: Core.h:555
OSType getOS() const
getOS - Get the parsed operating system type of this triple.
Definition: Triple.h:294
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:617
static bool needsRenaming(const Value &New)
static sys::Mutex Lock
Externally visible function.
Definition: GlobalValue.h:49
arg_iterator arg_end()
Definition: Function.h:666
std::map< SymbolStringPtr, JITEvaluatedSymbol > SymbolMap
A map from symbol names (as SymbolStringPtrs) to JITSymbols (address/flags pairs).
Definition: Core.h:51
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:1166
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:130
const std::string & getRename(const Value &Orig)
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: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:358
std::map< SymbolStringPtr, JITSymbolFlags > SymbolFlagsMap
A map from symbol names (as SymbolStringPtrs) to JITSymbolFlags.
Definition: Core.h:57
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...
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition: IRBuilder.h:731
static void raiseVisibilityOnValue(GlobalValue &V, GlobalRenamer &R)
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...
void setName(const Twine &Name)
Change the name of the value.
Definition: Value.cpp:295
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:124
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition: StringRef.h:267
Class to represent function types.
Definition: DerivedTypes.h:103
ArchType getArch() const
getArch - Get the parsed architecture type of this triple.
Definition: Triple.h:285
void setAttributes(AttributeList A)
Set the parameter attributes for this call.
AttributeList getAttributes() const
Return the attribute list for this Function.
Definition: Function.h:210
uint64_t JITTargetAddress
Represents an address in the target process&#39;s address space.
Definition: JITSymbol.h:40
LinkageTypes getLinkage() const
Definition: GlobalValue.h:450
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:155
void getModuleFlagsMetadata(SmallVectorImpl< ModuleFlagEntry > &Flags) const
Returns the module flags in the provided vector.
Definition: Module.cpp:282
bool hasName() const
Definition: Value.h:251
LLVM Basic Block Representation.
Definition: BasicBlock.h:59
void deleteBody()
deleteBody - This method deletes the body of the function, and converts the linkage to external...
Definition: Function.h:595
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:471
void addModuleFlag(ModFlagBehavior Behavior, StringRef Key, Metadata *Val)
Add a module-level flag to the module-level flags metadata.
Definition: Module.cpp:329
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:101
arg_iterator arg_begin()
Definition: Function.h:657
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:205
Function * cloneFunctionDecl(Module &Dst, const Function &F, ValueToValueMapTy *VMap=nullptr)
Clone a function declaration into a new module.
void resolve(const SymbolMap &Symbols)
Resolves the given symbols.
Definition: Core.cpp:605
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:847
Expected< SymbolMap > lookup(const VSOList &VSOs, SymbolNameSet Names)
Look up the given names in the given VSOs.
Definition: Core.cpp:1679
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:621
Expected< JITTargetAddress > getCompileCallback(CompileFunction Compile)
Reserve a compile callback.
void setLinkage(LinkageTypes LT)
Definition: GlobalValue.h:444
An ExecutionSession represents a running JIT program.
Definition: Core.h:746
Represents a symbol that has been evaluated to an address already.
Definition: JITSymbol.h:162
void finalize()
Finalizes all symbols tracked by this instance.
Definition: Core.cpp:625
static Constant * getCast(unsigned ops, Constant *C, Type *Ty, bool OnlyIfReduced=false)
Convenience function for getting a Cast operation.
Definition: Constants.cpp:1507
void makeAllSymbolsExternallyAccessible(Module &M)
Raise linkage types and rename as necessary to ensure that all symbols are accessible for other modul...
JITTargetAddress executeCompileCallback(JITTargetAddress TrampolineAddr)
Execute the callback for the given trampoline id.
void setUnnamedAddr(UnnamedAddr Val)
Definition: GlobalValue.h:215
StringRef getName() const
Return a constant reference to the value&#39;s name.
Definition: Value.cpp:224
void copyAttributesFrom(const GlobalVariable *Src)
copyAttributesFrom - copy all additional attributes (those not needed to create a GlobalVariable) fro...
Definition: Globals.cpp:381
#define I(x, y, z)
Definition: MD5.cpp:58
std::unique_ptr< JITCompileCallbackManager > createLocalCompileCallbackManager(const Triple &T, ExecutionSession &ES, JITTargetAddress ErrorHandlerAddress)
Create a local compile callback manager.
Type * getValueType() const
Definition: GlobalValue.h:275
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:201
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:477
Module * getParent()
Get the module that this global value is contained inside of...
Definition: GlobalValue.h:565
LLVM Value Representation.
Definition: Value.h:73
bool hasInitializer() const
Definitions have initializers, declarations don&#39;t.
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, const Twine &N="", Module *M=nullptr)
Definition: Function.h:136
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:418
PointerType * getType() const
Global values are always pointers.
Definition: GlobalValue.h:273
iterator_range< arg_iterator > args()
Definition: Function.h:675
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Definition: Error.cpp:73
const Constant * getAliasee() const
Definition: GlobalAlias.h:78