14 #ifndef LLVM_EXECUTIONENGINE_ORC_INDIRECTIONUTILS_H
15 #define LLVM_EXECUTIONENGINE_ORC_INDIRECTIONUTILS_H
34 #include <system_error>
52 : Addr(Addr), Compile(Compile) {}
56 this->Compile = std::move(Compile);
68 : ErrorHandlerAddress(ErrorHandlerAddress) {}
89 auto Compile = std::move(
I->second);
93 if (
auto Addr = Compile())
137 "Failed to grow available trampolines.");
140 return TrampolineAddr;
144 virtual void grow() = 0;
146 virtual void anchor();
150 template <
typename TargetT>
162 TargetT::ResolverCodeSize,
nullptr,
164 assert(!EC &&
"Failed to allocate resolver block");
166 TargetT::writeResolverCode(static_cast<uint8_t *>(ResolverBlock.
base()),
172 assert(!EC &&
"Failed to mprotect resolver block");
180 static_cast<JITTargetAddress>(
181 reinterpret_cast<uintptr_t>(TrampolineId)));
184 void grow()
override {
188 auto TrampolineBlock =
192 assert(!EC &&
"Failed to allocate trampoline block");
194 unsigned NumTrampolines =
196 TargetT::TrampolineSize;
198 uint8_t *TrampolineMem =
static_cast<uint8_t *
>(TrampolineBlock.base());
199 TargetT::writeTrampolines(TrampolineMem, ResolverBlock.
base(),
202 for (
unsigned I = 0;
I < NumTrampolines; ++
I)
204 static_cast<JITTargetAddress>(reinterpret_cast<uintptr_t>(
205 TrampolineMem + (
I * TargetT::TrampolineSize))));
210 assert(!EC &&
"Failed to mprotect trampoline block");
212 TrampolineBlocks.push_back(std::move(TrampolineBlock));
215 sys::OwningMemoryBlock ResolverBlock;
216 std::vector<sys::OwningMemoryBlock> TrampolineBlocks;
247 virtual void anchor();
252 template <
typename TargetT>
257 if (
auto Err = reserveStubs(1))
260 createStubInternal(StubName, StubAddr, StubFlags);
266 if (
auto Err = reserveStubs(StubInits.
size()))
269 for (
auto &Entry : StubInits)
270 createStubInternal(Entry.first(), Entry.second.first,
271 Entry.second.second);
277 auto I = StubIndexes.find(Name);
278 if (
I == StubIndexes.end())
280 auto Key =
I->second.first;
281 void *StubAddr = IndirectStubsInfos[Key.first].getStub(Key.second);
282 assert(StubAddr &&
"Missing stub address");
283 auto StubTargetAddr =
285 auto StubSymbol =
JITSymbol(StubTargetAddr,
I->second.second);
286 if (ExportedStubsOnly && !StubSymbol.getFlags().isExported())
292 auto I = StubIndexes.find(Name);
293 if (
I == StubIndexes.end())
295 auto Key =
I->second.first;
296 void *PtrAddr = IndirectStubsInfos[Key.first].getPtr(Key.second);
297 assert(PtrAddr &&
"Missing pointer address");
300 return JITSymbol(PtrTargetAddr,
I->second.second);
304 auto I = StubIndexes.find(Name);
305 assert(
I != StubIndexes.end() &&
"No stub pointer for symbol");
306 auto Key =
I->second.first;
307 *IndirectStubsInfos[Key.first].getPtr(Key.second) =
308 reinterpret_cast<void *
>(
static_cast<uintptr_t
>(NewAddr));
313 Error reserveStubs(
unsigned NumStubs) {
314 if (NumStubs <= FreeStubs.size())
317 unsigned NewStubsRequired = NumStubs - FreeStubs.size();
318 unsigned NewBlockId = IndirectStubsInfos.size();
319 typename TargetT::IndirectStubsInfo ISI;
321 TargetT::emitIndirectStubsBlock(ISI, NewStubsRequired,
nullptr))
323 for (
unsigned I = 0;
I < ISI.getNumStubs(); ++
I)
324 FreeStubs.push_back(std::make_pair(NewBlockId,
I));
325 IndirectStubsInfos.push_back(std::move(ISI));
331 auto Key = FreeStubs.back();
332 FreeStubs.pop_back();
333 *IndirectStubsInfos[Key.first].getPtr(Key.second) =
334 reinterpret_cast<void *
>(
static_cast<uintptr_t
>(InitAddr));
335 StubIndexes[StubName] = std::make_pair(Key, StubFlags);
338 std::vector<typename TargetT::IndirectStubsInfo> IndirectStubsInfos;
339 typedef std::pair<uint16_t, uint16_t> StubKey;
340 std::vector<StubKey> FreeStubs;
341 StringMap<std::pair<StubKey, JITSymbolFlags>> StubIndexes;
349 std::unique_ptr<JITCompileCallbackManager>
356 std::function<std::unique_ptr<IndirectStubsManager>()>
369 Constant *Initializer);
373 void makeStub(Function &
F, Value &ImplPointer);
406 ValueMaterializer *Materializer =
nullptr,
407 Function *NewF =
nullptr);
423 ValueMaterializer *Materializer =
nullptr,
424 GlobalVariable *NewGV =
nullptr);
437 #endif // LLVM_EXECUTIONENGINE_ORC_INDIRECTIONUTILS_H
IndirectStubsManager implementation for the host architecture, e.g.
Base class for managing collections of named indirect stubs.
Represents a symbol in the JIT.
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.
std::map< JITTargetAddress, CompileFtor > TrampolineMapT
void cloneModuleFlagsMetadata(Module &Dst, const Module &Src, ValueToValueMapTy &VMap)
Clone module flags metadata into the destination module.
TrampolineMapT ActiveTrampolines
virtual JITSymbol findStub(StringRef Name, bool ExportedStubsOnly)=0
Find the stub with the given name.
std::function< JITTargetAddress()> CompileFtor
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...
Target-independent base class for compile callback management.
Handle to a newly created compile callback.
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...
std::unique_ptr< JITCompileCallbackManager > createLocalCompileCallbackManager(const Triple &T, JITTargetAddress ErrorHandlerAddress)
Create a local compile callback manager.
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...
virtual Error createStub(StringRef StubName, JITTargetAddress StubAddr, JITSymbolFlags StubFlags)=0
Create a single stub with the given name, target address and flags.
JITTargetAddress ErrorHandlerAddress
void makeStub(Function &F, Value &ImplPointer)
Turn a function declaration into a stub function that makes an indirect call using the given function...
CompileCallbackInfo getCompileCallback()
Reserve a compile callback.
StringMap< std::pair< JITTargetAddress, JITSymbolFlags > > StubInitsMap
Map type for initializing the manager. See init.
std::vector< JITTargetAddress > AvailableTrampolines
GlobalVariable * cloneGlobalVariableDecl(Module &Dst, const GlobalVariable &GV, ValueToValueMapTy *VMap=nullptr)
Clone a global variable declaration into a new module.
MemoryBlock getMemoryBlock() const
CompileCallbackInfo(JITTargetAddress Addr, CompileFtor &Compile)
CompileCallbackInfo getCompileCallbackInfo(JITTargetAddress TrampolineAddr)
Get a CompileCallbackInfo for an existing callback.
Flags for symbols in the JIT.
uint64_t JITTargetAddress
Represents an address in the target process's address space.
ValueMap< const Value *, WeakVH > ValueToValueMapTy
void releaseCompileCallback(JITTargetAddress TrampolineAddr)
Release a compile callback.
static unsigned getPageSize()
Constant * createIRTypedAddress(FunctionType &FT, JITTargetAddress Addr)
Build a function pointer of FunctionType with the given constant address.
static ErrorSuccess success()
Create a success value.
Function * cloneFunctionDecl(Module &Dst, const Function &F, ValueToValueMapTy *VMap=nullptr)
Clone a function declaration into a new module.
Module.h This file contains the declarations for the Module class.
Error createStub(StringRef StubName, JITTargetAddress StubAddr, JITSymbolFlags StubFlags) override
Create a single stub with the given name, target address and flags.
virtual ~IndirectStubsManager()=default
Owning version of MemoryBlock.
JITSymbol findPointer(StringRef Name) override
Find the implementation-pointer for the stub.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings"...
JITTargetAddress getAddress() const
void makeAllSymbolsExternallyAccessible(Module &M)
Raise linkage types and rename as necessary to ensure that all symbols are accessible for other modul...
virtual JITSymbol findPointer(StringRef Name)=0
Find the implementation-pointer for the stub.
JITTargetAddress executeCompileCallback(JITTargetAddress TrampolineAddr)
Execute the callback for the given trampoline id.
Provides a library for accessing information about this process and other processes on the operating ...
virtual Error updatePointer(StringRef Name, JITTargetAddress NewAddr)=0
Change the value of the implementation pointer for the stub.
LocalJITCompileCallbackManager(JITTargetAddress ErrorHandlerAddress)
Construct a InProcessJITCompileCallbackManager.
JITCompileCallbackManager(JITTargetAddress ErrorHandlerAddress)
Construct a JITCompileCallbackManager.
Error createStubs(const StubInitsMap &StubInits) override
Create StubInits.size() stubs with the given names, target addresses, and flags.
virtual ~JITCompileCallbackManager()=default
void setCompileAction(CompileFtor Compile)
virtual Error createStubs(const StubInitsMap &StubInits)=0
Create StubInits.size() stubs with the given names, target addresses, and flags.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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...
JITSymbol findStub(StringRef Name, bool ExportedStubsOnly) override
Find the stub with the given name.
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...