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()) {
94 formatv(
"{0:x}", TrampolineAddr),
96 return ErrorHandlerAddress;
105 return Sym->getAddress();
110 ES.reportError(Sym.takeError());
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) {
133 auto StubSym =
findStub(*Name,
false);
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()) {
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.");
296 LoadInst *ImplAddr = Builder.CreateLoad(
F.getType(), &ImplPointer);
297 std::vector<Value*> CallArgs;
298 for (
auto &
A :
F.args())
299 CallArgs.push_back(&
A);
300 CallInst *
Call = Builder.CreateCall(
F.getFunctionType(), ImplAddr, CallArgs);
302 Call->setAttributes(
F.getAttributes());
303 if (
F.getReturnType()->isVoidTy())
304 Builder.CreateRetVoid();
306 Builder.CreateRet(
Call);
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;
348 for (
auto ArgI =
F.arg_begin(), ArgE =
F.arg_end(); ArgI != ArgE;
350 (*VMap)[&*ArgI] = &*NewArgI;
364 (*VMap)[&GV] = NewGV;
374 NewA->copyAttributesFrom(&OrigA);
393 assert(!
B.isZeroFill() &&
"expected content block");
395 auto SymStartInBlock =
398 auto Content =
ArrayRef(SymStartInBlock, SymSize);
403 for (
auto &E :
B.edges()) {
404 if (E.isRelocation())
405 ExistingRelocations.
insert(E.getOffset());
409 while (
I < Content.size()) {
412 uint64_t InstrStart = SymAddress.getValue() +
I;
414 Instr, InstrSize, Content.drop_front(
I), InstrStart, CommentStream);
416 LLVM_DEBUG(
dbgs() <<
"Aborting due to disassembly failure at address "
419 formatv(
"failed to disassemble at address {0:x16}", InstrStart),
428 if (!PCRelAddr || *PCRelAddr != SymAddress.getValue())
431 auto RelocOffInInstr =
433 if (!RelocOffInInstr || InstrSize - *RelocOffInInstr != 4) {
441 if (ExistingRelocations.
contains(RelocOffInBlock))
444 LLVM_DEBUG(
dbgs() <<
"Adding delta32 self-relocation at " << InstrStart);
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.
static LLVM_ABI PointerType * get(LLVMContext &C, unsigned AddressSpace)
This constructs an opaque pointer to an object 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.
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.
Error redirect(JITDylib &JD, const SymbolMap &NewDests) override
— RedirectableSymbolManager implementation —
LLVM_ABI ExecutorAddr executeCompileCallback(ExecutorAddr TrampolineAddr)
Execute the callback for the given trampoline id.
LLVM_ABI Expected< ExecutorAddr > getCompileCallback(CompileFunction Compile)
Reserve a compile callback.
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.
LLVM_ABI Expected< std::unique_ptr< JITCompileCallbackManager > > createLocalCompileCallbackManager(const Triple &T, ExecutionSession &ES, ExecutorAddr ErrorHandlerAddress)
Create a local compile callback manager.
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...
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...
LLVM_ABI GlobalVariable * cloneGlobalVariableDecl(Module &Dst, const GlobalVariable &GV, ValueToValueMapTy *VMap=nullptr)
Clone a global variable declaration into a new module.
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.
LLVM_ABI std::function< std::unique_ptr< IndirectStubsManager >()> createLocalIndirectStubsManagerBuilder(const Triple &T)
Create a local indirect stubs manager builder.
LLVM_ABI GlobalAlias * cloneGlobalAliasDecl(Module &Dst, const GlobalAlias &OrigA, ValueToValueMapTy &VMap)
Clone a global alias declaration into a new module.
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.
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