LLVM: lib/ExecutionEngine/Orc/IndirectionUtils.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
18
19#define DEBUG_TYPE "orc"
20
21using namespace llvm;
23
24namespace {
25
27public:
29
31 CompileFunction Compile)
34 Name(std::move(Name)), Compile(std::move(Compile)) {}
35
36 StringRef getName() const override { return ""; }
37
38private:
39 void materialize(std::unique_ptr R) override {
42
44 cantFail(R->notifyEmitted({}));
45 }
46
49 }
50
52 CompileFunction Compile;
53};
54
55}
56
57namespace llvm {
58namespace orc {
59
61void IndirectStubsManager::anchor() {}
62
63Expected
65 if (auto TrampolineAddr = TP->getTrampoline()) {
66 auto CallbackName =
67 ES.intern(std::string("cc") + std::to_string(++NextCallbackId));
68
69 std::lock_guardstd::mutex Lock(CCMgrMutex);
70 AddrToSymbol[*TrampolineAddr] = CallbackName;
72 CallbacksJD.define(std::make_unique(
73 std::move(CallbackName), std::move(Compile))));
74 return *TrampolineAddr;
75 } else
76 return TrampolineAddr.takeError();
77}
78
82
83 {
84 std::unique_lockstd::mutex Lock(CCMgrMutex);
85 auto I = AddrToSymbol.find(TrampolineAddr);
86
87
88
89
90 if (I == AddrToSymbol.end()) {
91 Lock.unlock();
92 ES.reportError(
94 formatv("{0:x}", TrampolineAddr),
96 return ErrorHandlerAddress;
97 } else
98 Name = I->second;
99 }
100
101 if (auto Sym =
104 Name))
105 return Sym->getAddress();
106 else {
107 llvm::dbgs() << "Didn't find callback.\n";
108
109
110 ES.reportError(Sym.takeError());
111 return ErrorHandlerAddress;
112 }
113}
114
116 for (auto &[Name, Dest] : NewDests)
117 if (auto Err = updatePointer(*Name, Dest.getAddress()))
118 return Err;
120}
121
123 std::unique_ptr MR, SymbolMap InitialDests) {
125 for (auto &[Name, Dest] : InitialDests)
126 StubInits[*Name] = {Dest.getAddress(), Dest.getFlags()};
128 MR->getExecutionSession().reportError(std::move(Err));
129 return MR->failMaterialization();
130 }
132 for (auto &[Name, Dest] : InitialDests) {
133 auto StubSym = findStub(*Name, false);
134 assert(StubSym.getAddress() && "Stub symbol should be present");
135 Stubs[Name] = StubSym;
136 }
137 if (auto Err = MR->notifyResolved(Stubs)) {
138 MR->getExecutionSession().reportError(std::move(Err));
139 return MR->failMaterialization();
140 }
141 if (auto Err = MR->notifyEmitted({})) {
142 MR->getExecutionSession().reportError(std::move(Err));
143 return MR->failMaterialization();
144 }
145}
146
150 switch (T.getArch()) {
151 default:
153 std::string("No callback manager available for ") + T.str(),
158 return CCMgrT::Create(ES, ErrorHandlerAddress);
159 }
160
163 return CCMgrT::Create(ES, ErrorHandlerAddress);
164 }
165
168 return CCMgrT::Create(ES, ErrorHandlerAddress);
169 }
170
173 return CCMgrT::Create(ES, ErrorHandlerAddress);
174 }
177 return CCMgrT::Create(ES, ErrorHandlerAddress);
178 }
179
183 return CCMgrT::Create(ES, ErrorHandlerAddress);
184 }
185
188 return CCMgrT::Create(ES, ErrorHandlerAddress);
189 }
190
194 return CCMgrT::Create(ES, ErrorHandlerAddress);
195 } else {
197 return CCMgrT::Create(ES, ErrorHandlerAddress);
198 }
199 }
200
201 }
202}
203
204std::function<std::unique_ptr()>
206 switch (T.getArch()) {
207 default:
208 return [](){
209 return std::make_unique<
211 };
212
215 return [](){
216 return std::make_unique<
218 };
219
221 return [](){
222 return std::make_unique<
224 };
225
227 return []() {
228 return std::make_unique<
230 };
231
233 return [](){
234 return std::make_unique<
236 };
237
239 return [](){
240 return std::make_unique<
242 };
243
246 return [](){
247 return std::make_unique<
249 };
250
252 return []() {
253 return std::make_unique<
255 };
256
259 return [](){
260 return std::make_unique<
262 };
263 } else {
264 return [](){
265 return std::make_unique<
267 };
268 }
269
270 }
271}
272
278 return AddrPtrVal;
279}
280
284 Initializer, Name, nullptr,
287 return IP;
288}
289
291 assert(F.isDeclaration() && "Can't turn a definition into a stub.");
292 assert(F.getParent() && "Function isn't in a module.");
293 Module &M = *F.getParent();
296 LoadInst *ImplAddr = Builder.CreateLoad(F.getType(), &ImplPointer);
297 std::vector<Value*> CallArgs;
299 CallArgs.push_back(&A);
300 CallInst *Call = Builder.CreateCall(F.getFunctionType(), ImplAddr, CallArgs);
301 Call->setTailCall();
302 Call->setAttributes(F.getAttributes());
303 if (F.getReturnType()->isVoidTy())
304 Builder.CreateRetVoid();
305 else
306 Builder.CreateRet(Call);
307}
308
310 std::vector<GlobalValue *> PromotedGlobals;
311
312 for (auto &GV : M.global_values()) {
313 bool Promoted = true;
314
315
316 if (!GV.hasName())
317 GV.setName("__orc_anon." + Twine(NextId++));
318 else if (GV.getName().starts_with("\01L"))
319 GV.setName("__" + GV.getName().substr(1) + "." + Twine(NextId++));
320 else if (GV.hasLocalLinkage())
321 GV.setName("__orc_lcl." + GV.getName() + "." + Twine(NextId++));
322 else
323 Promoted = false;
324
325 if (GV.hasLocalLinkage()) {
328 Promoted = true;
329 }
331
332 if (Promoted)
333 PromotedGlobals.push_back(&GV);
334 }
335
336 return PromotedGlobals;
337}
338
343 F.getLinkage(), F.getName(), &Dst);
345
346 if (VMap) {
347 (*VMap)[&F] = NewF;
348 auto NewArgI = NewF->arg_begin();
349 for (auto ArgI = F.arg_begin(), ArgE = F.arg_end(); ArgI != ArgE;
350 ++ArgI, ++NewArgI)
351 (*VMap)[&*ArgI] = &*NewArgI;
352 }
353
354 return NewF;
355}
356
364 if (VMap)
365 (*VMap)[&GV] = NewGV;
366 return NewGV;
367}
368
371 assert(OrigA.getAliasee() && "Original alias doesn't have an aliasee?");
375 NewA->copyAttributesFrom(&OrigA);
376 VMap[&OrigA] = NewA;
377 return NewA;
378}
379
384
385
388
391
392
394 assert(.isZeroFill() && "expected content block");
396 auto SymStartInBlock =
399 auto Content = ArrayRef(SymStartInBlock, SymSize);
400
402
404 for (auto &E : B.edges()) {
405 if (E.isRelocation())
406 ExistingRelocations.insert(E.getOffset());
407 }
408
409 size_t I = 0;
410 while (I < Content.size()) {
413 uint64_t InstrStart = SymAddress.getValue() + I;
415 Instr, InstrSize, Content.drop_front(I), InstrStart, CommentStream);
417 LLVM_DEBUG(dbgs() << "Aborting due to disassembly failure at address "
418 << InstrStart);
420 formatv("failed to disassemble at address {0:x16}", InstrStart),
422 }
423
424 I += InstrSize;
425
426
427 auto PCRelAddr =
429 if (!PCRelAddr || *PCRelAddr != SymAddress.getValue())
430 continue;
431
432 auto RelocOffInInstr =
434 if (!RelocOffInInstr || InstrSize - *RelocOffInInstr != 4) {
435 LLVM_DEBUG(dbgs() << "Skipping unknown self-relocation at "
436 << InstrStart);
437 continue;
438 }
439
440 auto RelocOffInBlock = orc::ExecutorAddr(InstrStart) + *RelocOffInInstr -
442 if (ExistingRelocations.contains(RelocOffInBlock))
443 continue;
444
445 LLVM_DEBUG(dbgs() << "Adding delta32 self-relocation at " << InstrStart);
447 }
449}
450
451}
452}
MCDisassembler::DecodeStatus DecodeStatus
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Module.h This file contains the declarations for the Module class.
static StringRef getName(Value *V)
LLVM Basic Block Representation.
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
This class represents a function call, abstracting a target machine's calling convention.
static LLVM_ABI Constant * getIntToPtr(Constant *C, Type *Ty, bool OnlyIfReduced=false)
This is an important base class in LLVM.
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
Class to represent function types.
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
void copyAttributesFrom(const Function *Src)
copyAttributesFrom - copy all additional attributes (those not needed to create a Function) from the ...
const Constant * getAliasee() const
static LLVM_ABI 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...
LinkageTypes getLinkage() const
ThreadLocalMode getThreadLocalMode() const
PointerType * getType() const
Global values are always pointers.
@ HiddenVisibility
The GV is hidden.
@ ExternalLinkage
Externally visible function.
Type * getValueType() const
LLVM_ABI void copyAttributesFrom(const GlobalVariable *Src)
copyAttributesFrom - copy all additional attributes (those not needed to create a GlobalVariable) fro...
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...
An instruction for reading from memory.
Superclass for all disassemblers.
const MCSubtargetInfo & getSubtargetInfo() const
virtual DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size, ArrayRef< uint8_t > Bytes, uint64_t Address, raw_ostream &CStream) const =0
Returns the disassembly of a single instruction.
Instances of this class represent a single low-level machine instruction.
virtual std::optional< uint64_t > getMemoryOperandRelocationOffset(const MCInst &Inst, uint64_t Size) const
Given an instruction with a memory operand that could require relocation, returns the offset within t...
virtual std::optional< uint64_t > evaluateMemoryOperandAddress(const MCInst &Inst, const MCSubtargetInfo *STI, uint64_t Addr, uint64_t Size) const
Given an instruction tries to get the address of a memory operand.
A Module instance is used to store all the information related to an LLVM module.
Class to represent pointers.
unsigned getAddressSpace() const
Return the address space of the Pointer type.
static LLVM_ABI PointerType * get(Type *ElementType, unsigned AddressSpace)
This constructs a pointer to an object of the specified type in a numbered address space.
Implements a dense probed hash-table based set with some number of buckets stored inline.
StringRef - Represent a constant reference to a string, i.e.
Triple - Helper class for working with autoconf configuration names.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
static LLVM_ABI IntegerType * getInt64Ty(LLVMContext &C)
LLVM_ABI unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
LLVM Value Representation.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
std::pair< iterator, bool > insert(const ValueT &V)
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
const orc::SymbolStringPtr & getName() const
Returns the name of this symbol (empty if the symbol is anonymous).
orc::ExecutorAddr getAddress() const
Returns the address of this symbol.
Block & getBlock()
Return the Block for this Symbol (Symbol must be defined).
orc::ExecutorAddrDiff getSize() const
Returns the size of this symbol.
orc::ExecutorAddrDiff getOffset() const
Returns the offset for this symbol within the underlying addressable.
An ExecutionSession represents a running JIT program.
Represents an address in the executor process.
uint64_t getValue() const
virtual ExecutorSymbolDef findStub(StringRef Name, bool ExportedStubsOnly)=0
Find the stub with the given name.
StringMap< std::pair< ExecutorAddr, JITSymbolFlags > > StubInitsMap
Map type for initializing the manager. See init.
virtual Error updatePointer(StringRef Name, ExecutorAddr NewAddr)=0
Change the value of the implementation pointer for the stub.
virtual Error createStubs(const StubInitsMap &StubInits)=0
Create StubInits.size() stubs with the given names, target addresses, and flags.
void emitRedirectableSymbols(std::unique_ptr< MaterializationResponsibility > MR, SymbolMap InitialDests) override
Emit redirectable symbol.
Definition IndirectionUtils.cpp:122
Error redirect(JITDylib &JD, const SymbolMap &NewDests) override
— RedirectableSymbolManager implementation —
Definition IndirectionUtils.cpp:115
LLVM_ABI ExecutorAddr executeCompileCallback(ExecutorAddr TrampolineAddr)
Execute the callback for the given trampoline id.
Definition IndirectionUtils.cpp:80
LLVM_ABI Expected< ExecutorAddr > getCompileCallback(CompileFunction Compile)
Reserve a compile callback.
Definition IndirectionUtils.cpp:64
std::function< ExecutorAddr()> CompileFunction
Represents a JIT'd dynamic library.
IndirectStubsManager implementation for the host architecture, e.g.
Manage compile callbacks for in-process JITs.
A MaterializationUnit represents a set of symbol definitions that can be materialized as a group,...
Pointer to a pooled string representing a symbol name.
virtual ~TrampolinePool()
A raw_ostream that discards all output.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
JITDylibSearchOrder makeJITDylibSearchOrder(ArrayRef< JITDylib * > JDs, JITDylibLookupFlags Flags=JITDylibLookupFlags::MatchExportedSymbolsOnly)
Convenience function for creating a search order from an ArrayRef of JITDylib*, all with the same fla...
LLVM_ABI Constant * createIRTypedAddress(FunctionType &FT, ExecutorAddr Addr)
Build a function pointer of FunctionType with the given constant address.
Definition IndirectionUtils.cpp:273
LLVM_ABI Expected< std::unique_ptr< JITCompileCallbackManager > > createLocalCompileCallbackManager(const Triple &T, ExecutionSession &ES, ExecutorAddr ErrorHandlerAddress)
Create a local compile callback manager.
Definition IndirectionUtils.cpp:148
LLVM_ABI void makeStub(Function &F, Value &ImplPointer)
Turn a function declaration into a stub function that makes an indirect call using the given function...
Definition IndirectionUtils.cpp:290
LLVM_ABI Error addFunctionPointerRelocationsToCurrentSymbol(jitlink::Symbol &Sym, jitlink::LinkGraph &G, MCDisassembler &Disassembler, MCInstrAnalysis &MIA)
Introduce relocations to Sym in its own definition if there are any pointers formed via PC-relative a...
Definition IndirectionUtils.cpp:380
LLVM_ABI GlobalVariable * cloneGlobalVariableDecl(Module &Dst, const GlobalVariable &GV, ValueToValueMapTy *VMap=nullptr)
Clone a global variable declaration into a new module.
Definition IndirectionUtils.cpp:357
DenseMap< SymbolStringPtr, ExecutorSymbolDef > SymbolMap
A map from symbol names (as SymbolStringPtrs) to JITSymbols (address/flags pairs).
LLVM_ABI Function * cloneFunctionDecl(Module &Dst, const Function &F, ValueToValueMapTy *VMap=nullptr)
Clone a function declaration into a new module.
Definition IndirectionUtils.cpp:339
LLVM_ABI std::function< std::unique_ptr< IndirectStubsManager >()> createLocalIndirectStubsManagerBuilder(const Triple &T)
Create a local indirect stubs manager builder.
Definition IndirectionUtils.cpp:205
LLVM_ABI GlobalAlias * cloneGlobalAliasDecl(Module &Dst, const GlobalAlias &OrigA, ValueToValueMapTy &VMap)
Clone a global alias declaration into a new module.
Definition IndirectionUtils.cpp:369
LLVM_ABI 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.
Definition IndirectionUtils.cpp:281
DenseMap< SymbolStringPtr, JITSymbolFlags > SymbolFlagsMap
A map from symbol names (as SymbolStringPtrs) to JITSymbolFlags.
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
ArrayRef(const T &OneElt) -> ArrayRef< T >
ValueMap< const Value *, WeakTrackingVH > ValueToValueMapTy
decltype(auto) cast(const From &Val)
cast - Return the argument parameter cast to the specified type.