19#define DEBUG_TYPE "orc"
31 CompileFunction Compile)
34 Name(std::move(Name)), Compile(std::move(Compile)) {}
39 void materialize(std::unique_ptr<MaterializationResponsibility> R)
override {
52 CompileFunction Compile;
61void IndirectStubsManager::anchor() {}
65 if (
auto TrampolineAddr = TP->getTrampoline()) {
67 ES.
intern(std::string(
"cc") + std::to_string(++NextCallbackId));
69 std::lock_guard<std::mutex> Lock(CCMgrMutex);
70 AddrToSymbol[*TrampolineAddr] = CallbackName;
72 CallbacksJD.
define(std::make_unique<CompileCallbackMaterializationUnit>(
73 std::move(CallbackName), std::move(Compile))));
74 return *TrampolineAddr;
76 return TrampolineAddr.takeError();
84 std::unique_lock<std::mutex> Lock(CCMgrMutex);
85 auto I = AddrToSymbol.find(TrampolineAddr);
90 if (
I == AddrToSymbol.end()) {
93 make_error<StringError>(
"No compile callback for trampoline at " +
94 formatv(
"{0:x}", TrampolineAddr),
96 return ErrorHandlerAddress;
105 return Sym->getAddress();
111 return ErrorHandlerAddress;
116 for (
auto &[
Name, Dest] : NewDests)
123 std::unique_ptr<MaterializationResponsibility> 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();
132 for (
auto &[
Name, Dest] : InitialDests) {
134 assert(StubSym.getAddress() &&
"Stub symbol should be present");
135 Stubs[
Name] = StubSym;
137 if (
auto Err = MR->notifyResolved(Stubs)) {
138 MR->getExecutionSession().reportError(std::move(Err));
139 return MR->failMaterialization();
141 if (
auto Err = MR->notifyEmitted({})) {
142 MR->getExecutionSession().reportError(std::move(Err));
143 return MR->failMaterialization();
150 switch (
T.getArch()) {
152 return make_error<StringError>(
153 std::string(
"No callback manager available for ") +
T.str(),
158 return CCMgrT::Create(ES, ErrorHandlerAddress);
163 return CCMgrT::Create(ES, ErrorHandlerAddress);
168 return CCMgrT::Create(ES, ErrorHandlerAddress);
173 return CCMgrT::Create(ES, ErrorHandlerAddress);
177 return CCMgrT::Create(ES, ErrorHandlerAddress);
183 return CCMgrT::Create(ES, ErrorHandlerAddress);
188 return CCMgrT::Create(ES, ErrorHandlerAddress);
194 return CCMgrT::Create(ES, ErrorHandlerAddress);
197 return CCMgrT::Create(ES, ErrorHandlerAddress);
204std::function<std::unique_ptr<IndirectStubsManager>()>
206 switch (
T.getArch()) {
209 return std::make_unique<
216 return std::make_unique<
222 return std::make_unique<
228 return std::make_unique<
234 return std::make_unique<
240 return std::make_unique<
247 return std::make_unique<
253 return std::make_unique<
260 return std::make_unique<
265 return std::make_unique<
284 Initializer,
Name,
nullptr,
291 assert(
F.isDeclaration() &&
"Can't turn a definition into a stub.");
292 assert(
F.getParent() &&
"Function isn't in a module.");
297 std::vector<Value*> CallArgs;
298 for (
auto &
A :
F.args())
299 CallArgs.push_back(&
A);
302 Call->setAttributes(
F.getAttributes());
303 if (
F.getReturnType()->isVoidTy())
310 std::vector<GlobalValue *> PromotedGlobals;
312 for (
auto &GV : M.global_values()) {
313 bool Promoted =
true;
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++));
325 if (GV.hasLocalLinkage()) {
333 PromotedGlobals.push_back(&GV);
336 return PromotedGlobals;
343 F.getLinkage(),
F.getName(), &Dst);
349 for (
auto ArgI =
F.arg_begin(), ArgE =
F.arg_end(); ArgI != ArgE;
351 (*VMap)[&*ArgI] = &*NewArgI;
365 (*VMap)[&GV] = NewGV;
375 NewA->copyAttributesFrom(&OrigA);
393 auto &
B =
Sym.getBlock();
394 assert(!
B.isZeroFill() &&
"expected content block");
395 auto SymAddress =
Sym.getAddress();
396 auto SymStartInBlock =
397 (
const uint8_t *)
B.getContent().data() +
Sym.getOffset();
398 auto SymSize =
Sym.getSize() ?
Sym.getSize() :
B.getSize() -
Sym.getOffset();
404 for (
auto &E :
B.edges()) {
405 if (E.isRelocation())
406 ExistingRelocations.
insert(E.getOffset());
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 "
419 return make_error<StringError>(
420 formatv(
"failed to disassemble at address {0:x16}", InstrStart),
429 if (!PCRelAddr || *PCRelAddr != SymAddress.getValue())
432 auto RelocOffInInstr =
434 if (!RelocOffInInstr || InstrSize - *RelocOffInInstr != 4) {
441 SymAddress +
Sym.getOffset();
442 if (ExistingRelocations.
contains(RelocOffInBlock))
445 LLVM_DEBUG(
dbgs() <<
"Adding delta32 self-relocation at " << InstrStart);
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
Module.h This file contains the declarations for the Module class.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
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 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 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
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...
ReturnInst * CreateRet(Value *V)
Create a 'ret <val>' instruction.
LoadInst * CreateLoad(Type *Ty, Value *Ptr, const char *Name)
Provided to resolve 'CreateLoad(Ty, Ptr, "...")' correctly, instead of converting the string to 'bool...
ReturnInst * CreateRetVoid()
Create a 'ret void' instruction.
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args={}, const Twine &Name="", MDNode *FPMathTag=nullptr)
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
DecodeStatus
Ternary decode status.
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.
static PointerType * get(Type *ElementType, unsigned AddressSpace)
This constructs a pointer to an object of the specified type in a numbered address space.
unsigned getAddressSpace() const
Return the address space of the Pointer type.
Implements a dense probed hash-table based set with some number of buckets stored inline.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
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...
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.
static IntegerType * getInt64Ty(LLVMContext &C)
LLVM Value Representation.
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.
An ExecutionSession represents a running JIT program.
void reportError(Error Err)
Report a error for this execution session.
SymbolStringPtr intern(StringRef SymName)
Add a symbol name to the SymbolStringPool and return a pointer to it.
void lookup(LookupKind K, const JITDylibSearchOrder &SearchOrder, SymbolLookupSet Symbols, SymbolState RequiredState, SymbolsResolvedCallback NotifyComplete, RegisterDependenciesFunction RegisterDependencies)
Search the given JITDylibs for the given symbols.
Represents an address in the executor process.
virtual ExecutorSymbolDef findStub(StringRef Name, bool ExportedStubsOnly)=0
Find the stub with the given name.
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.
Error redirect(JITDylib &JD, const SymbolMap &NewDests) override
— RedirectableSymbolManager implementation —
ExecutorAddr executeCompileCallback(ExecutorAddr TrampolineAddr)
Execute the callback for the given trampoline id.
Expected< ExecutorAddr > getCompileCallback(CompileFunction Compile)
Reserve a compile callback.
std::function< ExecutorAddr()> CompileFunction
Represents a JIT'd dynamic library.
Error define(std::unique_ptr< MaterializationUnitType > &&MU, ResourceTrackerSP RT=nullptr)
Define all symbols provided by the materialization unit to be part of this JITDylib.
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,...
virtual StringRef getName() const =0
Return the name of this materialization unit.
virtual void materialize(std::unique_ptr< MaterializationResponsibility > R)=0
Implementations of this method should materialize all symbols in the materialzation unit,...
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...
Constant * createIRTypedAddress(FunctionType &FT, ExecutorAddr Addr)
Build a function pointer of FunctionType with the given constant address.
Expected< std::unique_ptr< JITCompileCallbackManager > > createLocalCompileCallbackManager(const Triple &T, ExecutionSession &ES, ExecutorAddr ErrorHandlerAddress)
Create a local compile callback manager.
void makeStub(Function &F, Value &ImplPointer)
Turn a function declaration into a stub function that makes an indirect call using the given function...
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...
DenseMap< SymbolStringPtr, JITSymbolFlags > SymbolFlagsMap
A map from symbol names (as SymbolStringPtrs) to JITSymbolFlags.
GlobalVariable * cloneGlobalVariableDecl(Module &Dst, const GlobalVariable &GV, ValueToValueMapTy *VMap=nullptr)
Clone a global variable declaration into a new module.
Function * cloneFunctionDecl(Module &Dst, const Function &F, ValueToValueMapTy *VMap=nullptr)
Clone a function declaration into a new module.
std::function< std::unique_ptr< IndirectStubsManager >()> createLocalIndirectStubsManagerBuilder(const Triple &T)
Create a local indirect stubs manager builder.
GlobalAlias * cloneGlobalAliasDecl(Module &Dst, const GlobalAlias &OrigA, ValueToValueMapTy &VMap)
Clone a global alias declaration into a new module.
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.
This is an optimization pass for GlobalISel generic memory operations.
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)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.