21#define DEBUG_TYPE "orc"
33 CompileFunction Compile)
36 Name(std::move(Name)), Compile(std::move(Compile)) {}
41 void materialize(std::unique_ptr<MaterializationResponsibility> R)
override {
54 CompileFunction Compile;
63void IndirectStubsManager::anchor() {}
67 if (
auto TrampolineAddr = TP->getTrampoline()) {
69 ES.
intern(std::string(
"cc") + std::to_string(++NextCallbackId));
71 std::lock_guard<std::mutex> Lock(CCMgrMutex);
72 AddrToSymbol[*TrampolineAddr] = CallbackName;
74 CallbacksJD.
define(std::make_unique<CompileCallbackMaterializationUnit>(
75 std::move(CallbackName), std::move(Compile))));
76 return *TrampolineAddr;
78 return TrampolineAddr.takeError();
86 std::unique_lock<std::mutex> Lock(CCMgrMutex);
87 auto I = AddrToSymbol.find(TrampolineAddr);
92 if (
I == AddrToSymbol.end()) {
97 ErrMsgStream <<
"No compile callback for trampoline at "
98 <<
format(
"0x%016" PRIx64, TrampolineAddr);
102 return ErrorHandlerAddress;
111 return Sym->getAddress();
117 return ErrorHandlerAddress;
124 switch (
T.getArch()) {
126 return make_error<StringError>(
127 std::string(
"No callback manager available for ") +
T.str(),
132 return CCMgrT::Create(ES, ErrorHandlerAddress);
137 return CCMgrT::Create(ES, ErrorHandlerAddress);
142 return CCMgrT::Create(ES, ErrorHandlerAddress);
147 return CCMgrT::Create(ES, ErrorHandlerAddress);
151 return CCMgrT::Create(ES, ErrorHandlerAddress);
157 return CCMgrT::Create(ES, ErrorHandlerAddress);
162 return CCMgrT::Create(ES, ErrorHandlerAddress);
168 return CCMgrT::Create(ES, ErrorHandlerAddress);
171 return CCMgrT::Create(ES, ErrorHandlerAddress);
178std::function<std::unique_ptr<IndirectStubsManager>()>
180 switch (
T.getArch()) {
183 return std::make_unique<
190 return std::make_unique<
196 return std::make_unique<
202 return std::make_unique<
208 return std::make_unique<
214 return std::make_unique<
221 return std::make_unique<
227 return std::make_unique<
234 return std::make_unique<
239 return std::make_unique<
259 Initializer,
Name,
nullptr,
266 assert(
F.isDeclaration() &&
"Can't turn a definition into a stub.");
267 assert(
F.getParent() &&
"Function isn't in a module.");
272 std::vector<Value*> CallArgs;
273 for (
auto &
A :
F.args())
274 CallArgs.push_back(&
A);
275 CallInst *Call =
Builder.CreateCall(
F.getFunctionType(), ImplAddr, CallArgs);
277 Call->setAttributes(
F.getAttributes());
278 if (
F.getReturnType()->isVoidTy())
285 std::vector<GlobalValue *> PromotedGlobals;
287 for (
auto &GV : M.global_values()) {
288 bool Promoted =
true;
292 GV.setName(
"__orc_anon." +
Twine(NextId++));
293 else if (GV.getName().startswith(
"\01L"))
294 GV.setName(
"__" + GV.getName().substr(1) +
"." +
Twine(NextId++));
295 else if (GV.hasLocalLinkage())
296 GV.setName(
"__orc_lcl." + GV.getName() +
"." +
Twine(NextId++));
300 if (GV.hasLocalLinkage()) {
308 PromotedGlobals.push_back(&GV);
311 return PromotedGlobals;
318 F.getLinkage(),
F.getName(), &Dst);
324 for (
auto ArgI =
F.arg_begin(), ArgE =
F.arg_end(); ArgI != ArgE;
326 (*VMap)[&*ArgI] = &*NewArgI;
337 NewF = cast<Function>(VMap[&OrigF]);
339 assert(VMap[&OrigF] == NewF &&
"Incorrect function mapping in VMap.");
340 assert(NewF &&
"Function mapping missing from VMap.");
342 "moveFunctionBody should only be used to move bodies between "
348 nullptr,
nullptr, Materializer);
360 (*VMap)[&GV] = NewGV;
370 NewGV = cast<GlobalVariable>(VMap[&OrigGV]);
372 assert(VMap[&OrigGV] == NewGV &&
373 "Incorrect global variable mapping in VMap.");
375 "moveGlobalVariableInitializer should only be used to move "
376 "initializers between modules");
379 nullptr, Materializer));
388 NewA->copyAttributesFrom(&OrigA);
395 auto *MFs = Src.getModuleFlagsMetadata();
398 for (
auto *MF : MFs->operands())
416 assert(!
B.isZeroFill() &&
"expected content block");
418 auto SymStartInBlock =
419 (
const uint8_t *)
B.getContent().data() + Sym.
getOffset();
426 for (
auto &
E :
B.edges()) {
427 if (
E.isRelocation())
428 ExistingRelocations.
insert(
E.getOffset());
435 uint64_t InstrStart = SymAddress.getValue() +
I;
437 Instr, InstrSize,
Content.drop_front(
I), InstrStart, CommentStream);
439 LLVM_DEBUG(
dbgs() <<
"Aborting due to disassembly failure at address "
441 return make_error<StringError>(
442 formatv(
"failed to disassemble at address {0:x16}", InstrStart),
451 if (!PCRelAddr || *PCRelAddr != SymAddress.getValue())
454 auto RelocOffInInstr =
456 if (!RelocOffInInstr || InstrSize - *RelocOffInInstr != 4) {
464 if (ExistingRelocations.
contains(RelocOffInBlock))
467 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")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
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 * getCast(unsigned ops, Constant *C, Type *Ty, bool OnlyIfReduced=false)
Convenience function for getting a Cast operation.
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.
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.
void deleteBody()
deleteBody - This method deletes the body of the function, and converts the linkage to external.
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...
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
LinkageTypes getLinkage() const
ThreadLocalMode getThreadLocalMode() const
Module * getParent()
Get the module that this global value is contained inside of...
PointerType * getType() const
Global values are always pointers.
@ HiddenVisibility
The GV is hidden.
@ ExternalLinkage
Externally visible function.
Type * getValueType() const
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
void setInitializer(Constant *InitVal)
setInitializer - Sets the initializer for this global variable, removing any existing initializer if ...
bool hasInitializer() const
Definitions have initializers, declarations don't.
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...
Represents a symbol that has been evaluated to an address already.
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.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
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)
This is a class that can be implemented by clients to materialize Values on demand.
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.
StringRef 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.
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.
std::function< JITTargetAddress()> CompileFunction
JITTargetAddress executeCompileCallback(JITTargetAddress TrampolineAddr)
Execute the callback for the given trampoline id.
Expected< JITTargetAddress > getCompileCallback(CompileFunction Compile)
Reserve a compile callback.
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.
A raw_ostream that writes to an std::string.
#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...
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 cloneModuleFlagsMetadata(Module &Dst, const Module &Src, ValueToValueMapTy &VMap)
Clone module flags metadata into the destination module.
Expected< std::unique_ptr< JITCompileCallbackManager > > createLocalCompileCallbackManager(const Triple &T, ExecutionSession &ES, JITTargetAddress 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.
void moveFunctionBody(Function &OrigF, ValueToValueMapTy &VMap, ValueMaterializer *Materializer=nullptr, Function *NewF=nullptr)
Move the body of function 'F' to a cloned function declaration in a different module (See related clo...
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.
Constant * createIRTypedAddress(FunctionType &FT, JITTargetAddress Addr)
Build a function pointer of FunctionType with the given constant address.
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.
auto formatv(const char *Fmt, Ts &&... Vals) -> formatv_object< decltype(std::make_tuple(detail::build_format_adapter(std::forward< Ts >(Vals))...))>
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
uint64_t JITTargetAddress
Represents an address in the target process's address space.
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.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
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.
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
void CloneFunctionInto(Function *NewFunc, const Function *OldFunc, ValueToValueMapTy &VMap, CloneFunctionChangeType Changes, 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.