14 #ifndef LLVM_EXECUTIONENGINE_ORC_INDIRECTIONUTILS_H 15 #define LLVM_EXECUTIONENGINE_ORC_INDIRECTIONUTILS_H 32 #include <system_error> 64 virtual void anchor();
71 std::function<JITTargetAddress(JITTargetAddress TrampolineAddr)>;
80 auto LTP = std::unique_ptr<LocalTrampolinePool>(
84 return std::move(Err);
85 return std::move(LTP);
91 std::lock_guard<std::mutex>
Lock(LTPMutex);
92 if (AvailableTrampolines.empty()) {
93 if (
auto Err = grow())
94 return std::move(Err);
96 assert(!AvailableTrampolines.empty() &&
"Failed to grow trampoline pool");
97 auto TrampolineAddr = AvailableTrampolines.back();
98 AvailableTrampolines.pop_back();
99 return TrampolineAddr;
104 std::lock_guard<std::mutex>
Lock(LTPMutex);
105 AvailableTrampolines.push_back(TrampolineAddr);
109 static JITTargetAddress reenter(
void *TrampolinePoolPtr,
void *TrampolineId) {
112 return TrampolinePool->GetTrampolineLanding(static_cast<JITTargetAddress>(
113 reinterpret_cast<uintptr_t>(TrampolineId)));
118 : GetTrampolineLanding(std::move(GetTrampolineLanding)) {
125 ORCABI::ResolverCodeSize,
nullptr,
132 ORCABI::writeResolverCode(static_cast<uint8_t *>(ResolverBlock.base()),
145 assert(this->AvailableTrampolines.empty() &&
"Growing prematurely?");
148 auto TrampolineBlock =
155 unsigned NumTrampolines =
157 ORCABI::TrampolineSize;
159 uint8_t *TrampolineMem =
static_cast<uint8_t *
>(TrampolineBlock.base());
160 ORCABI::writeTrampolines(TrampolineMem, ResolverBlock.base(),
163 for (
unsigned I = 0;
I < NumTrampolines; ++
I)
164 this->AvailableTrampolines.push_back(
165 static_cast<JITTargetAddress>(reinterpret_cast<uintptr_t>(
166 TrampolineMem + (
I * ORCABI::TrampolineSize))));
169 TrampolineBlock.getMemoryBlock(),
173 TrampolineBlocks.push_back(std::move(TrampolineBlock));
181 std::vector<sys::OwningMemoryBlock> TrampolineBlocks;
182 std::vector<JITTargetAddress> AvailableTrampolines;
204 : TP(
std::move(TP)), ES(ES),
205 CallbacksJD(ES.createJITDylib(
"<Callbacks>")),
206 ErrorHandlerAddress(ErrorHandlerAddress) {}
209 this->TP = std::move(TP);
213 std::mutex CCMgrMutex;
214 std::unique_ptr<TrampolinePool> TP;
218 std::map<JITTargetAddress, SymbolStringPtr> AddrToSymbol;
219 size_t NextCallbackId = 0;
223 template <
typename ORCABI>
230 auto CCMgr = std::unique_ptr<LocalJITCompileCallbackManager>(
233 return std::move(Err);
234 return std::move(CCMgr);
248 return executeCompileCallback(TrampolineAddr);
252 Err = TP.takeError();
256 setTrampolinePool(std::move(*TP));
288 virtual void anchor();
293 template <
typename TargetT>
298 std::lock_guard<std::mutex>
Lock(StubsMutex);
299 if (
auto Err = reserveStubs(1))
302 createStubInternal(StubName, StubAddr, StubFlags);
308 std::lock_guard<std::mutex>
Lock(StubsMutex);
309 if (
auto Err = reserveStubs(StubInits.
size()))
312 for (
auto &Entry : StubInits)
313 createStubInternal(Entry.first(), Entry.second.first,
314 Entry.second.second);
320 std::lock_guard<std::mutex>
Lock(StubsMutex);
321 auto I = StubIndexes.find(Name);
322 if (
I == StubIndexes.end())
324 auto Key =
I->second.first;
325 void *StubAddr = IndirectStubsInfos[
Key.first].getStub(
Key.second);
326 assert(StubAddr &&
"Missing stub address");
327 auto StubTargetAddr =
330 if (ExportedStubsOnly && !StubSymbol.getFlags().isExported())
336 std::lock_guard<std::mutex>
Lock(StubsMutex);
337 auto I = StubIndexes.find(Name);
338 if (
I == StubIndexes.end())
340 auto Key =
I->second.first;
341 void *PtrAddr = IndirectStubsInfos[
Key.first].getPtr(
Key.second);
342 assert(PtrAddr &&
"Missing pointer address");
349 using AtomicIntPtr = std::atomic<uintptr_t>;
351 std::lock_guard<std::mutex>
Lock(StubsMutex);
352 auto I = StubIndexes.find(Name);
353 assert(
I != StubIndexes.end() &&
"No stub pointer for symbol");
354 auto Key =
I->second.first;
355 AtomicIntPtr *AtomicStubPtr =
reinterpret_cast<AtomicIntPtr *
>(
356 IndirectStubsInfos[Key.first].getPtr(Key.second));
357 *AtomicStubPtr =
static_cast<uintptr_t
>(NewAddr);
362 Error reserveStubs(
unsigned NumStubs) {
363 if (NumStubs <= FreeStubs.size())
366 unsigned NewStubsRequired = NumStubs - FreeStubs.size();
367 unsigned NewBlockId = IndirectStubsInfos.size();
368 typename TargetT::IndirectStubsInfo ISI;
370 TargetT::emitIndirectStubsBlock(ISI, NewStubsRequired,
nullptr))
372 for (
unsigned I = 0;
I < ISI.getNumStubs(); ++
I)
373 FreeStubs.push_back(std::make_pair(NewBlockId,
I));
374 IndirectStubsInfos.push_back(std::move(ISI));
380 auto Key = FreeStubs.back();
381 FreeStubs.pop_back();
382 *IndirectStubsInfos[
Key.first].getPtr(
Key.second) =
383 reinterpret_cast<void *
>(
static_cast<uintptr_t
>(InitAddr));
384 StubIndexes[StubName] = std::make_pair(
Key, StubFlags);
387 std::mutex StubsMutex;
388 std::vector<typename TargetT::IndirectStubsInfo> IndirectStubsInfos;
389 using StubKey = std::pair<uint16_t, uint16_t>;
390 std::vector<StubKey> FreeStubs;
406 std::function<std::unique_ptr<IndirectStubsManager>()>
432 std::vector<GlobalValue *> operator()(
Module &M);
494 #endif // LLVM_EXECUTIONENGINE_ORC_INDIRECTIONUTILS_H IndirectStubsManager implementation for the host architecture, e.g.
Base class for managing collections of named indirect stubs.
std::function< JITTargetAddress(JITTargetAddress TrampolineAddr)> GetTrampolineLandingFunction
This class represents lattice values for constants.
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. ...
A trampoline pool for trampolines within the current process.
void cloneModuleFlagsMetadata(Module &Dst, const Module &Src, ValueToValueMapTy &VMap)
Clone module flags metadata into the destination module.
Manage compile callbacks for in-process JITs.
static MemoryBlock allocateMappedMemory(size_t NumBytes, const MemoryBlock *const NearBlock, unsigned Flags, std::error_code &EC)
This method allocates a block of memory that is suitable for loading dynamically generated code (e...
void setTrampolinePool(std::unique_ptr< TrampolinePool > TP)
Target-independent base class for compile callback management.
static Expected< std::unique_ptr< LocalTrampolinePool > > Create(GetTrampolineLandingFunction GetTrampolineLanding)
Creates a LocalTrampolinePool with the given RunCallback function.
virtual Expected< JITTargetAddress > getTrampoline()=0
Get an available trampoline address.
amdgpu Simplify well known AMD library false Value Value const Twine & Name
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Error updatePointer(StringRef Name, JITTargetAddress NewAddr) override
Change the value of the implementation pointer for the stub.
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...
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...
Base class for pools of compiler re-entry trampolines.
Tagged union holding either a T or a Error.
JITEvaluatedSymbol findPointer(StringRef Name) override
Find the implementation-pointer for the stub.
void makeStub(Function &F, Value &ImplPointer)
Turn a function declaration into a stub function that makes an indirect call using the given function...
Class to represent function types.
uint64_t JITTargetAddress
Represents an address in the target process's address space.
GlobalVariable * cloneGlobalVariableDecl(Module &Dst, const GlobalVariable &GV, ValueToValueMapTy *VMap=nullptr)
Clone a global variable declaration into a new module.
Class to represent pointers.
void releaseTrampoline(JITTargetAddress TrampolineAddr)
Returns the given trampoline to the pool for re-use.
This is a class that can be implemented by clients to materialize Values on demand.
Expected< JITTargetAddress > getTrampoline() override
Get a free trampoline.
This is an important base class in LLVM.
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
JITCompileCallbackManager(std::unique_ptr< TrampolinePool > TP, ExecutionSession &ES, JITTargetAddress ErrorHandlerAddress)
Construct a JITCompileCallbackManager.
Flags for symbols in the JIT.
Triple - Helper class for working with autoconf configuration names.
static unsigned getPageSize()
Constant * createIRTypedAddress(FunctionType &FT, JITTargetAddress Addr)
Build a function pointer of FunctionType with the given constant address.
std::function< JITTargetAddress()> CompileFunction
static ErrorSuccess success()
Create a success value.
static Expected< std::unique_ptr< LocalJITCompileCallbackManager > > Create(ExecutionSession &ES, JITTargetAddress ErrorHandlerAddress)
Create a new LocalJITCompileCallbackManager.
Function * cloneFunctionDecl(Module &Dst, const Function &F, ValueToValueMapTy *VMap=nullptr)
Clone a function declaration into a new module.
Expected< std::unique_ptr< JITCompileCallbackManager > > createLocalCompileCallbackManager(const Triple &T, ExecutionSession &ES, JITTargetAddress ErrorHandlerAddress)
Create a local compile callback manager.
Error createStub(StringRef StubName, JITTargetAddress StubAddr, JITSymbolFlags StubFlags) override
Create a single stub with the given name, target address and flags.
Owning version of MemoryBlock.
An ExecutionSession represents a running JIT program.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings"...
Represents a symbol that has been evaluated to an address already.
Helper for Errors used as out-parameters.
Provides a library for accessing information about this process and other processes on the operating ...
virtual ~TrampolinePool()
Error createStubs(const StubInitsMap &StubInits) override
Create StubInits.size() stubs with the given names, target addresses, and flags.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
JITEvaluatedSymbol findStub(StringRef Name, bool ExportedStubsOnly) override
Find the stub with the given name.
LLVM Value Representation.
Lightweight error class with error context and mandatory checking.
StringRef - Represent a constant reference to a string, i.e.
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...
A symbol table that supports asynchoronous symbol queries.
static std::error_code protectMappedMemory(const MemoryBlock &Block, unsigned Flags)
This method sets the protection flags for a block of memory to the state specified by /p Flags...