34 static struct RegisterJIT {
45 std::shared_ptr<MCJITMemoryManager> MemMgr,
46 std::shared_ptr<LegacyJITSymbolResolver>
Resolver,
47 std::unique_ptr<TargetMachine>
TM) {
54 auto RTDyldMM = std::make_shared<SectionMemoryManager>();
65 MCJIT::MCJIT(std::unique_ptr<Module> M, std::unique_ptr<TargetMachine>
TM,
66 std::shared_ptr<MCJITMemoryManager> MemMgr,
67 std::shared_ptr<LegacyJITSymbolResolver>
Resolver)
69 Ctx(nullptr), MemMgr(
std::
move(MemMgr)),
85 if (First->getDataLayout().isDefault())
93 std::lock_guard<sys::Mutex> locked(
lock);
97 for (
auto &Obj : LoadedObjects)
105 std::lock_guard<sys::Mutex> locked(
lock);
107 if (M->getDataLayout().isDefault())
114 std::lock_guard<sys::Mutex> locked(
lock);
115 return OwnedModules.removeModule(M);
119 std::unique_ptr<RuntimeDyld::LoadedObjectInfo> L = Dyld.
loadObject(*Obj);
129 std::unique_ptr<object::ObjectFile> ObjFile;
130 std::unique_ptr<MemoryBuffer> MemBuf;
141 std::lock_guard<sys::Mutex> locked(
lock);
146 assert(M &&
"Can not emit a null module");
148 std::lock_guard<sys::Mutex> locked(
lock);
173 std::unique_ptr<MemoryBuffer> CompiledObjBuffer(
185 return CompiledObjBuffer;
190 std::lock_guard<sys::Mutex> locked(
lock);
193 assert(OwnedModules.ownsModule(M) &&
194 "MCJIT::generateCodeForModule: Unknown module.");
197 if (OwnedModules.hasModuleBeenLoaded(M))
200 std::unique_ptr<MemoryBuffer> ObjectToLoad;
210 assert(ObjectToLoad &&
"Compilation did not produce an object.");
224 std::unique_ptr<RuntimeDyld::LoadedObjectInfo> L =
232 Buffers.push_back(
std::move(ObjectToLoad));
233 LoadedObjects.push_back(
std::move(*LoadedObject));
235 OwnedModules.markModuleAsLoaded(M);
239 std::lock_guard<sys::Mutex> locked(
lock);
248 OwnedModules.markAllLoadedModulesAsFinalized();
254 MemMgr->finalizeMemory();
259 std::lock_guard<sys::Mutex> locked(
lock);
264 for (
auto M : OwnedModules.added())
267 for (
auto M : ModsToAdd)
274 std::lock_guard<sys::Mutex> locked(
lock);
277 assert(OwnedModules.ownsModule(M) &&
"MCJIT::finalizeModule: Unknown module.");
280 if (!OwnedModules.hasModuleBeenLoaded(M))
289 reinterpret_cast<uintptr_t>(
Addr)),
296 bool CheckFunctionsOnly) {
299 DemangledName = DemangledName.
substr(1);
301 std::lock_guard<sys::Mutex> locked(
lock);
305 E = OwnedModules.end_added();
308 Function *
F = M->getFunction(DemangledName);
309 if (
F && !
F->isDeclaration())
311 if (!CheckFunctionsOnly) {
313 if (
G && !
G->isDeclaration())
323 bool CheckFunctionsOnly) {
324 std::string MangledName;
329 if (
auto Sym =
findSymbol(MangledName, CheckFunctionsOnly)) {
330 if (
auto AddrOrErr = Sym.getAddress())
334 }
else if (
auto Err = Sym.takeError())
340 bool CheckFunctionsOnly) {
341 std::lock_guard<sys::Mutex> locked(
lock);
350 auto OptionalChildOrErr = A->findSym(
Name);
351 if (!OptionalChildOrErr)
353 auto &OptionalChild = *OptionalChildOrErr;
357 OptionalChild->getAsBinary();
358 if (!ChildBinOrErr) {
363 std::unique_ptr<object::Binary> &ChildBin = ChildBinOrErr.
get();
364 if (ChildBin->isObject()) {
365 std::unique_ptr<object::ObjectFile> OF(
366 static_cast<object::ObjectFile *>(ChildBin.release()));
388 auto Addr = static_cast<uint64_t>(
397 std::lock_guard<sys::Mutex> locked(
lock);
405 std::lock_guard<sys::Mutex> locked(
lock);
414 std::lock_guard<sys::Mutex> locked(
lock);
418 TM->getNameWithPrefix(
Name,
F, Mang);
420 if (
F->isDeclaration() ||
F->hasAvailableExternallyLinkage()) {
421 bool AbortOnFailure = !
F->hasExternalWeakLinkage();
428 bool HasBeenAddedButNotLoaded = OwnedModules.hasModuleBeenAddedButNotLoaded(M);
431 if (HasBeenAddedButNotLoaded)
433 else if (!OwnedModules.hasModuleBeenLoaded(M)) {
448 void MCJIT::runStaticConstructorsDestructorsInModulePtrSet(
449 bool isDtors, ModulePtrSet::iterator
I, ModulePtrSet::iterator
E) {
450 for (;
I !=
E; ++
I) {
457 runStaticConstructorsDestructorsInModulePtrSet(
458 isDtors, OwnedModules.begin_added(), OwnedModules.end_added());
459 runStaticConstructorsDestructorsInModulePtrSet(
460 isDtors, OwnedModules.begin_loaded(), OwnedModules.end_loaded());
461 runStaticConstructorsDestructorsInModulePtrSet(
462 isDtors, OwnedModules.begin_finalized(), OwnedModules.end_finalized());
466 ModulePtrSet::iterator
I,
467 ModulePtrSet::iterator
E) {
468 for (;
I !=
E; ++
I) {
470 if (
F && !
F->isDeclaration())
478 ModulePtrSet::iterator
I,
479 ModulePtrSet::iterator
E) {
480 for (;
I !=
E; ++
I) {
490 Function *
F = FindFunctionNamedInModulePtrSet(
491 FnName, OwnedModules.begin_added(), OwnedModules.end_added());
493 F = FindFunctionNamedInModulePtrSet(FnName, OwnedModules.begin_loaded(),
494 OwnedModules.end_loaded());
496 F = FindFunctionNamedInModulePtrSet(FnName, OwnedModules.begin_finalized(),
497 OwnedModules.end_finalized());
503 Name, AllowInternal, OwnedModules.begin_added(), OwnedModules.end_added());
505 GV = FindGlobalVariableNamedInModulePtrSet(
Name, AllowInternal, OwnedModules.begin_loaded(),
506 OwnedModules.end_loaded());
508 GV = FindGlobalVariableNamedInModulePtrSet(
Name, AllowInternal, OwnedModules.begin_finalized(),
509 OwnedModules.end_finalized());
514 assert(
F &&
"Function *F was null at entry to run()");
518 assert(FPtr &&
"Pointer to fn's code was null after getPointerToFunction");
524 "Wrong number of arguments passed into function!");
526 "This doesn't support passing arguments through varargs (yet)!");
531 switch (ArgValues.
size()) {
536 int (*PF)(int,
char **,
const char **) =
537 (
int(*)(int,
char **,
const char **))(
intptr_t)FPtr;
542 (
char **)
GVTOP(ArgValues[1]),
543 (
const char **)
GVTOP(ArgValues[2])));
550 int (*PF)(int,
char **) = (
int(*)(int,
char **))(
intptr_t)FPtr;
555 (
char **)
GVTOP(ArgValues[1])));
563 int (*PF)(int) = (
int(*)(int))(
intptr_t)FPtr;
572 if (ArgValues.
empty()) {
577 unsigned BitWidth = cast<IntegerType>(RetTy)->getBitWidth();
611 "argument passing. Please use " 612 "ExecutionEngine::getFunctionAddress and cast the result " 613 "to the desired function pointer type.");
618 if (
auto Sym =
Resolver.findSymbol(std::string(
Name))) {
619 if (
auto AddrOrErr = Sym.getAddress())
620 return reinterpret_cast<void*>(
621 static_cast<uintptr_t>(*AddrOrErr));
622 }
else if (
auto Err = Sym.takeError())
631 if (AbortOnFailure) {
633 "' which could not be resolved!");
641 std::lock_guard<sys::Mutex> locked(
lock);
642 EventListeners.push_back(L);
648 std::lock_guard<sys::Mutex> locked(
lock);
650 if (
I != EventListeners.rend()) {
652 EventListeners.pop_back();
659 static_cast<uint64_t>(reinterpret_cast<uintptr_t>(Obj.
getData().
data()));
660 std::lock_guard<sys::Mutex> locked(
lock);
661 MemMgr->notifyObjectLoaded(
this, Obj);
662 for (
unsigned I = 0, S = EventListeners.size();
I < S; ++
I) {
663 EventListeners[
I]->notifyObjectLoaded(
Key, Obj, L);
669 static_cast<uint64_t>(reinterpret_cast<uintptr_t>(Obj.
getData().
data()));
670 std::lock_guard<sys::Mutex> locked(
lock);
672 L->notifyFreeingObject(
Key);
682 return ClientResolver->findSymbol(
Name);
685 void LinkingSymbolResolver::anchor() {}
Function * FindFunctionNamed(StringRef FnName) override
FindFunctionNamed - Search all of the active modules to find the function that defines FnName.
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
static Expected< OwningBinary< ObjectFile > > createObjectFile(StringRef ObjectPath)
Information about the loaded object.
void setObjectCache(ObjectCache *manager) override
Sets the object manager that MCJIT should use to avoid compilation.
std::unique_ptr< LoadedObjectInfo > loadObject(const object::ObjectFile &O)
Add the referenced object file to the list of objects to be loaded and relocated.
void registerEHFrames()
Register any EH frame sections that have been loaded but not previously registered with the memory ma...
LLVM_NODISCARD std::string str() const
str - Get the contents as an std::string.
Represents a symbol in the JIT.
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
This class represents lattice values for constants.
Type * getParamType(unsigned i) const
Parameter type accessors.
A Module instance is used to store all the information related to an LLVM module.
32-bit floating point type
virtual std::unique_ptr< MemoryBuffer > getObject(const Module *M)=0
Returns a pointer to a newly allocated MemoryBuffer that contains the object which corresponds with M...
void * getPointerToGlobalIfAvailable(StringRef S)
getPointerToGlobalIfAvailable - This returns the address of the specified global value if it is has a...
sys::Mutex lock
lock - This lock protects the ExecutionEngine and MCJIT classes.
void push_back(const T &Elt)
uint64_t updateGlobalMapping(const GlobalValue *GV, void *Addr)
updateGlobalMapping - Replace an existing mapping for GV with a new address.
JITEventListener - Abstract interface for use by the JIT to notify clients about significant events d...
StringRef getErrorString()
static JITEventListener * createGDBRegistrationListener()
This class is the base class for all object file types.
A raw_ostream that writes to an SmallVector or SmallString.
void generateCodeForModule(Module *M) override
generateCodeForModule - Run code generation for the specified module and load it into memory.
80-bit floating point type (X87)
const DataLayout & getDataLayout() const
Error takeError()
Take ownership of the stored error.
JITEvaluatedSymbol getSymbol(StringRef Name) const
Get the target address and flags for the named symbol.
void UnregisterJITEventListener(JITEventListener *L) override
void deregisterEHFrames()
virtual void runStaticConstructorsDestructors(bool isDtors)
runStaticConstructorsDestructors - This method is used to execute all of the static constructors or d...
TypeID getTypeID() const
Return the type id for the type.
bool isIntegerTy() const
True if this is an instance of IntegerType.
static bool LoadLibraryPermanently(const char *Filename, std::string *ErrMsg=nullptr)
This function permanently loads the dynamic library at the given path.
Tagged union holding either a T or a Error.
void runStaticConstructorsDestructors(bool isDtors) override
runStaticConstructorsDestructors - This method is used to execute all of the static constructors or d...
LLVM_NODISCARD StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
uint64_t getGlobalValueAddress(const std::string &Name) override
getGlobalValueAddress - Return the address of the specified global value.
Class to represent function types.
virtual void finalizeModule(Module *)
void notifyObjectLoaded(const object::ObjectFile &Obj, const RuntimeDyld::LoadedObjectInfo &L)
GlobalVariable * FindGlobalVariableNamed(StringRef Name, bool AllowInternal=false) override
FindGlobalVariableNamed - Search all of the active modules to find the global variable that defines N...
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
void * getPointerToFunction(Function *F) override
getPointerToFunction - The different EE's represent function bodies in different ways.
JITSymbol findSymbol(const std::string &Name) override
This method returns the address of the specified function or variable.
bool isSymbolSearchingDisabled() const
JITSymbol findExistingSymbol(const std::string &Name)
void finalizeObject() override
finalizeObject - ensure the module is fully processed and is usable.
Arbitrary bit width integers.
PassManager manages ModulePassManagers.
bool isVoidTy() const
Return true if this is 'void'.
void addModule(std::unique_ptr< Module > M) override
Add a Module to the list of modules that we can JIT from.
The instances of the Type class are immutable: once they are created, they are never changed.
static ExecutionEngine * createJIT(std::unique_ptr< Module > M, std::string *ErrorStr, std::shared_ptr< MCJITMemoryManager > MemMgr, std::shared_ptr< LegacyJITSymbolResolver > Resolver, std::unique_ptr< TargetMachine > TM)
bool removeModule(Module *M) override
removeModule - Removes a Module from the list of modules, but does not free the module's memory.
size_t size() const
size - Get the array size.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
void * getPointerToNamedFunction(StringRef Name, bool AbortOnFailure=true) override
getPointerToNamedFunction - This method returns the address of the specified function by using the dl...
bool isPointerTy() const
True if this is an instance of PointerType.
Interface for looking up the initializer for a variable name, used by Init::resolveReferences.
unsigned getNumParams() const
Return the number of fixed parameters this function type requires.
uint64_t getFunctionAddress(const std::string &Name) override
getFunctionAddress - Return the address of the specified function.
128-bit floating point type (two 64-bits, PowerPC)
constexpr unsigned BitWidth
JITSymbol findSymbol(const std::string &Name, bool CheckFunctionsOnly)
bool getVerifyModules() const
void consumeError(Error Err)
Consume a Error without doing anything.
void logAllUnhandledErrors(Error E, raw_ostream &OS, Twine ErrorBanner={})
Log all errors (if any) in E to OS.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Abstract interface for implementation execution of LLVM modules, designed to support both interpreter...
virtual void notifyObjectCompiled(const Module *M, MemoryBufferRef Obj)=0
notifyObjectCompiled - Provides a pointer to compiled code for Module M.
void * GVTOP(const GenericValue &GV)
std::pair< std::unique_ptr< T >, std::unique_ptr< MemoryBuffer > > takeBinary()
void addArchive(object::OwningBinary< object::Archive > O) override
addArchive - Add an Archive to the execution engine.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
Module.h This file contains the declarations for the Module class.
Type * getReturnType() const
reference get()
Returns a reference to the stored T value.
uint64_t getSymbolAddress(const std::string &Name, bool CheckFunctionsOnly)
void RegisterJITEventListener(JITEventListener *L) override
Registers a listener to be called back on various events within the JIT.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
GenericValue PTOGV(void *P)
Class for arbitrary precision integers.
Module * findModuleForSymbol(const std::string &Name, bool CheckFunctionsOnly)
GenericValue runFunction(Function *F, ArrayRef< GenericValue > ArgValues) override
runFunction - Execute the specified function with the specified arguments, and return the result.
void notifyFreeingObject(const object::ObjectFile &Obj)
std::unique_ptr< MemoryBuffer > emitObject(Module *M)
emitObject – Generate a JITed object in memory from the specified module Currently,...
SmallVector< std::unique_ptr< Module >, 1 > Modules
The list of Modules that we are JIT'ing from.
SmallVector-backed MemoryBuffer instance.
This is the base ObjectCache type which can be provided to an ExecutionEngine for the purpose of avoi...
void resolveRelocations()
Resolve the relocations for all symbols we currently know about.
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
64-bit floating point type
LLVM_NODISCARD const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
FunctionCreator LazyFunctionCreator
LazyFunctionCreator - If an unknown function is needed, this function pointer is invoked to create it...
A raw_ostream that writes to an std::string.
SmallPtrSetIterator< Module * > iterator
void getNameWithPrefix(raw_ostream &OS, const GlobalValue *GV, bool CannotUsePrivateLabel) const
Print the appropriate prefix and the specified global variable's name.
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
StringRef - Represent a constant reference to a string, i.e.
JITTargetAddress getAddress() const
Return the address of this symbol.
auto reverse(ContainerTy &&C, std::enable_if_t< has_rbegin< ContainerTy >::value > *=nullptr)
StringRef getData() const
void finalizeLoadedModules()
bool empty() const
empty - Check if the array is empty.
128-bit floating point type (112-bit significand)
void addObjectFile(std::unique_ptr< object::ObjectFile > O) override
addObjectFile - Add an ObjectFile to the execution engine.