34static struct RegisterJIT {
45 std::shared_ptr<MCJITMemoryManager> MemMgr,
46 std::shared_ptr<LegacyJITSymbolResolver> Resolver,
47 std::unique_ptr<TargetMachine> TM) {
53 if (!MemMgr || !Resolver) {
54 auto RTDyldMM = std::make_shared<SectionMemoryManager>();
61 return new MCJIT(std::move(M), std::move(TM), std::move(MemMgr),
65MCJIT::MCJIT(std::unique_ptr<Module> M, std::unique_ptr<TargetMachine> TM,
66 std::shared_ptr<MCJITMemoryManager> MemMgr,
67 std::shared_ptr<LegacyJITSymbolResolver>
Resolver)
69 TM->
Options.MCOptions.getABIName())),
87 if (
First->getDataLayout().isDefault())
90 OwnedModules.addModule(std::move(
First));
95 std::lock_guard<sys::Mutex> locked(
lock);
97 Dyld.deregisterEHFrames();
99 for (
auto &Obj : LoadedObjects)
107 std::lock_guard<sys::Mutex> locked(
lock);
109 if (M->getDataLayout().isDefault())
112 OwnedModules.addModule(std::move(M));
116 std::lock_guard<sys::Mutex> locked(
lock);
117 return OwnedModules.removeModule(M);
121 std::unique_ptr<RuntimeDyld::LoadedObjectInfo> L = Dyld.loadObject(*Obj);
127 LoadedObjects.push_back(std::move(Obj));
131 std::unique_ptr<object::ObjectFile> ObjFile;
132 std::unique_ptr<MemoryBuffer> MemBuf;
133 std::tie(ObjFile, MemBuf) = Obj.takeBinary();
135 Buffers.push_back(std::move(MemBuf));
139 Archives.push_back(std::move(
A));
143 std::lock_guard<sys::Mutex> locked(
lock);
148 assert(M &&
"Can not emit a null module");
150 std::lock_guard<sys::Mutex> locked(
lock);
175 auto CompiledObjBuffer = std::make_unique<SmallVectorMemoryBuffer>(
176 std::move(ObjBufferSV),
false);
184 ObjCache->notifyObjectCompiled(M, MB);
187 return CompiledObjBuffer;
192 std::lock_guard<sys::Mutex> locked(
lock);
195 assert(OwnedModules.ownsModule(M) &&
196 "MCJIT::generateCodeForModule: Unknown module.");
199 if (OwnedModules.hasModuleBeenLoaded(M))
202 std::unique_ptr<MemoryBuffer> ObjectToLoad;
205 ObjectToLoad = ObjCache->getObject(M);
212 assert(ObjectToLoad &&
"Compilation did not produce an object.");
225 std::unique_ptr<RuntimeDyld::LoadedObjectInfo> L =
226 Dyld.loadObject(*LoadedObject.
get());
233 Buffers.push_back(std::move(ObjectToLoad));
234 LoadedObjects.push_back(std::move(*LoadedObject));
236 OwnedModules.markModuleAsLoaded(M);
240 std::lock_guard<sys::Mutex> locked(
lock);
243 Dyld.resolveRelocations();
247 ErrMsg = Dyld.getErrorString().str();
249 OwnedModules.markAllLoadedModulesAsFinalized();
252 Dyld.registerEHFrames();
255 MemMgr->finalizeMemory();
260 std::lock_guard<sys::Mutex> locked(
lock);
266 for (
auto *M : ModsToAdd)
273 std::lock_guard<sys::Mutex> locked(
lock);
276 assert(OwnedModules.ownsModule(M) &&
"MCJIT::finalizeModule: Unknown module.");
279 if (!OwnedModules.hasModuleBeenLoaded(M))
291 return Dyld.getSymbol(Name);
295 bool CheckFunctionsOnly) {
298 DemangledName = DemangledName.
substr(1);
300 std::lock_guard<sys::Mutex> locked(
lock);
304 E = OwnedModules.end_added();
307 Function *
F = M->getFunction(DemangledName);
308 if (
F && !
F->isDeclaration())
310 if (!CheckFunctionsOnly) {
312 if (
G && !
G->isDeclaration())
322 bool CheckFunctionsOnly) {
323 std::string MangledName;
328 if (
auto Sym =
findSymbol(MangledName, CheckFunctionsOnly)) {
329 if (
auto AddrOrErr = Sym.getAddress())
333 }
else if (
auto Err = Sym.takeError())
339 bool CheckFunctionsOnly) {
340 std::lock_guard<sys::Mutex> locked(
lock);
349 auto OptionalChildOrErr =
A->findSym(Name);
350 if (!OptionalChildOrErr)
352 auto &OptionalChild = *OptionalChildOrErr;
356 OptionalChild->getAsBinary();
357 if (!ChildBinOrErr) {
362 std::unique_ptr<object::Binary> &ChildBin = ChildBinOrErr.
get();
363 if (ChildBin->isObject()) {
364 std::unique_ptr<object::ObjectFile> OF(
387 auto Addr =
static_cast<uint64_t
>(
396 std::lock_guard<sys::Mutex> locked(
lock);
404 std::lock_guard<sys::Mutex> locked(
lock);
413 std::lock_guard<sys::Mutex> locked(
lock);
417 TM->getNameWithPrefix(Name,
F, Mang);
419 if (
F->isDeclaration() ||
F->hasAvailableExternallyLinkage()) {
420 bool AbortOnFailure = !
F->hasExternalWeakLinkage();
427 bool HasBeenAddedButNotLoaded = OwnedModules.hasModuleBeenAddedButNotLoaded(M);
430 if (HasBeenAddedButNotLoaded)
432 else if (!OwnedModules.hasModuleBeenLoaded(M)) {
444 return (
void*)Dyld.getSymbol(Name).getAddress();
447void MCJIT::runStaticConstructorsDestructorsInModulePtrSet(
448 bool isDtors, ModulePtrSet::iterator
I, ModulePtrSet::iterator E) {
449 for (;
I != E; ++
I) {
456 runStaticConstructorsDestructorsInModulePtrSet(
457 isDtors, OwnedModules.begin_added(), OwnedModules.end_added());
458 runStaticConstructorsDestructorsInModulePtrSet(
459 isDtors, OwnedModules.begin_loaded(), OwnedModules.end_loaded());
460 runStaticConstructorsDestructorsInModulePtrSet(
461 isDtors, OwnedModules.begin_finalized(), OwnedModules.end_finalized());
465 ModulePtrSet::iterator
I,
466 ModulePtrSet::iterator E) {
467 for (;
I != E; ++
I) {
469 if (
F && !
F->isDeclaration())
477 ModulePtrSet::iterator
I,
478 ModulePtrSet::iterator
E) {
479 for (;
I !=
E; ++
I) {
480 GlobalVariable *GV = (*I)->getGlobalVariable(Name, AllowInternal);
489 Function *
F = FindFunctionNamedInModulePtrSet(
490 FnName, OwnedModules.begin_added(), OwnedModules.end_added());
492 F = FindFunctionNamedInModulePtrSet(FnName, OwnedModules.begin_loaded(),
493 OwnedModules.end_loaded());
495 F = FindFunctionNamedInModulePtrSet(FnName, OwnedModules.begin_finalized(),
496 OwnedModules.end_finalized());
502 Name, AllowInternal, OwnedModules.begin_added(), OwnedModules.end_added());
504 GV = FindGlobalVariableNamedInModulePtrSet(Name, AllowInternal, OwnedModules.begin_loaded(),
505 OwnedModules.end_loaded());
507 GV = FindGlobalVariableNamedInModulePtrSet(Name, AllowInternal, OwnedModules.begin_finalized(),
508 OwnedModules.end_finalized());
513 assert(
F &&
"Function *F was null at entry to run()");
517 assert(FPtr &&
"Pointer to fn's code was null after getPointerToFunction");
523 "Wrong number of arguments passed into function!");
525 "This doesn't support passing arguments through varargs (yet)!");
530 switch (ArgValues.
size()) {
535 int (*PF)(int,
char **,
const char **) =
536 (
int(*)(
int,
char **,
const char **))(intptr_t)FPtr;
540 rv.
IntVal =
APInt(32, PF(ArgValues[0].IntVal.getZExtValue(),
541 (
char **)
GVTOP(ArgValues[1]),
542 (
const char **)
GVTOP(ArgValues[2])));
549 int (*PF)(int,
char **) = (
int(*)(
int,
char **))(intptr_t)FPtr;
553 rv.
IntVal =
APInt(32, PF(ArgValues[0].IntVal.getZExtValue(),
554 (
char **)
GVTOP(ArgValues[1])));
562 int (*PF)(int) = (
int(*)(
int))(intptr_t)FPtr;
563 rv.
IntVal =
APInt(32, PF(ArgValues[0].IntVal.getZExtValue()));
571 if (ArgValues.
empty()) {
592 rv.
IntVal =
APInt(32, ((
int (*)())(intptr_t)FPtr)(),
true);
595 rv.
FloatVal = ((float(*)())(intptr_t)FPtr)();
598 rv.
DoubleVal = ((double(*)())(intptr_t)FPtr)();
605 return PTOGV(((
void*(*)())(intptr_t)FPtr)());
610 "argument passing. Please use "
611 "ExecutionEngine::getFunctionAddress and cast the result "
612 "to the desired function pointer type.");
617 if (
auto Sym = Resolver.findSymbol(std::string(Name))) {
618 if (
auto AddrOrErr = Sym.getAddress())
619 return reinterpret_cast<void*
>(
621 }
else if (
auto Err = Sym.takeError())
630 if (AbortOnFailure) {
632 "' which could not be resolved!");
640 std::lock_guard<sys::Mutex> locked(
lock);
641 EventListeners.push_back(L);
647 std::lock_guard<sys::Mutex> locked(
lock);
649 if (
I != EventListeners.rend()) {
651 EventListeners.pop_back();
658 static_cast<uint64_t
>(
reinterpret_cast<uintptr_t>(Obj.getData().
data()));
659 std::lock_guard<sys::Mutex> locked(
lock);
660 MemMgr->notifyObjectLoaded(
this, Obj);
662 EL->notifyObjectLoaded(
Key, Obj, L);
667 static_cast<uint64_t
>(
reinterpret_cast<uintptr_t>(Obj.getData().
data()));
668 std::lock_guard<sys::Mutex> locked(
lock);
670 L->notifyFreeingObject(
Key);
675 auto Result = ParentEngine.findSymbol(Name,
false);
678 if (ParentEngine.isSymbolSearchingDisabled())
680 return ClientResolver->findSymbol(Name);
683void LinkingSymbolResolver::anchor() {}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Module.h This file contains the declarations for the Module class.
Class for arbitrary precision integers.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
Get the array size.
bool empty() const
Check if the array is empty.
A parsed version of the target data layout string in and methods for querying it.
Abstract interface for implementation execution of LLVM modules, designed to support both interpreter...
const DataLayout & getDataLayout() const
bool getVerifyModules() const
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.
virtual void runStaticConstructorsDestructors(bool isDtors)
runStaticConstructorsDestructors - This method is used to execute all of the static constructors or d...
FunctionCreator LazyFunctionCreator
LazyFunctionCreator - If an unknown function is needed, this function pointer is invoked to create it...
SmallVector< std::unique_ptr< Module >, 1 > Modules
The list of Modules that we are JIT'ing from.
uint64_t updateGlobalMapping(const GlobalValue *GV, void *Addr)
updateGlobalMapping - Replace an existing mapping for GV with a new address.
bool isSymbolSearchingDisabled() const
Tagged union holding either a T or a Error.
Error takeError()
Take ownership of the stored error.
reference get()
Returns a reference to the stored T value.
Class to represent function types.
unsigned getNumParams() const
Return the number of fixed parameters this function type requires.
Type * getParamType(unsigned i) const
Parameter type accessors.
Type * getReturnType() const
LLVM_ABI bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
JITEventListener - Abstract interface for use by the JIT to notify clients about significant events d...
static JITEventListener * createGDBRegistrationListener()
Represents a symbol in the JIT.
JITSymbol findSymbol(const std::string &Name) override
This method returns the address of the specified function or variable.
GenericValue runFunction(Function *F, ArrayRef< GenericValue > ArgValues) override
runFunction - Execute the specified function with the specified arguments, and return the result.
void * getPointerToNamedFunction(StringRef Name, bool AbortOnFailure=true) override
getPointerToNamedFunction - This method returns the address of the specified function by using the dl...
void RegisterJITEventListener(JITEventListener *L) override
Registers a listener to be called back on various events within the JIT.
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)
void runStaticConstructorsDestructors(bool isDtors) override
runStaticConstructorsDestructors - This method is used to execute all of the static constructors or d...
Module * findModuleForSymbol(const std::string &Name, bool CheckFunctionsOnly)
void addArchive(object::OwningBinary< object::Archive > O) override
addArchive - Add an Archive to the execution engine.
Function * FindFunctionNamed(StringRef FnName) override
FindFunctionNamed - Search all of the active modules to find the function that defines FnName.
void finalizeObject() override
finalizeObject - ensure the module is fully processed and is usable.
void finalizeLoadedModules()
void notifyObjectLoaded(const object::ObjectFile &Obj, const RuntimeDyld::LoadedObjectInfo &L)
void generateCodeForModule(Module *M) override
generateCodeForModule - Run code generation for the specified module and load it into memory.
uint64_t getFunctionAddress(const std::string &Name) override
getFunctionAddress - Return the address of the specified function.
void addObjectFile(std::unique_ptr< object::ObjectFile > O) override
addObjectFile - Add an ObjectFile to the execution engine.
std::unique_ptr< MemoryBuffer > emitObject(Module *M)
emitObject – Generate a JITed object in memory from the specified module Currently,...
void UnregisterJITEventListener(JITEventListener *L) override
bool removeModule(Module *M) override
removeModule - Removes a Module from the list of modules, but does not free the module's memory.
JITSymbol findExistingSymbol(const std::string &Name)
GlobalVariable * FindGlobalVariableNamed(StringRef Name, bool AllowInternal=false) override
FindGlobalVariableNamed - Search all of the active modules to find the global variable that defines N...
uint64_t getGlobalValueAddress(const std::string &Name) override
getGlobalValueAddress - Return the address of the specified global value.
uint64_t getSymbolAddress(const std::string &Name, bool CheckFunctionsOnly)
void notifyFreeingObject(const object::ObjectFile &Obj)
virtual void finalizeModule(Module *)
JITSymbol findSymbol(const std::string &Name, bool CheckFunctionsOnly)
void * getPointerToFunction(Function *F) override
getPointerToFunction - The different EE's represent function bodies in different ways.
void setObjectCache(ObjectCache *manager) override
Sets the object manager that MCJIT should use to avoid compilation.
void addModule(std::unique_ptr< Module > M) override
Add a Module to the list of modules that we can JIT from.
LLVM_ABI void getNameWithPrefix(raw_ostream &OS, const GlobalValue *GV, bool CannotUsePrivateLabel) const
Print the appropriate prefix and the specified global variable's name.
A Module instance is used to store all the information related to an LLVM module.
This is the base ObjectCache type which can be provided to an ExecutionEngine for the purpose of avoi...
Interface for looking up the initializer for a variable name, used by Init::resolveReferences.
Information about the loaded object.
SmallPtrSetIterator< PtrType > iterator
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
bool isPointerTy() const
True if this is an instance of PointerType.
@ VoidTyID
type with no size
@ FloatTyID
32-bit floating point type
@ IntegerTyID
Arbitrary bit width integers.
@ DoubleTyID
64-bit floating point type
@ X86_FP80TyID
80-bit floating point type (X87)
@ PPC_FP128TyID
128-bit floating point type (two 64-bits, PowerPC)
@ FP128TyID
128-bit floating point type (112-bit significand)
bool isIntegerTy() const
True if this is an instance of IntegerType.
TypeID getTypeID() const
Return the type id for the type.
bool isVoidTy() const
Return true if this is 'void'.
PassManager manages ModulePassManagers.
bool run(Module &M)
run - Execute all of the passes scheduled for execution.
This class is the base class for all object file types.
static Expected< OwningBinary< ObjectFile > > createObjectFile(StringRef ObjectPath)
A raw_ostream that writes to an std::string.
A raw_ostream that writes to an SmallVector or SmallString.
static bool LoadLibraryPermanently(const char *Filename, std::string *ErrMsg=nullptr)
This function permanently loads the dynamic library at the given path.
void LLVMLinkInMCJIT()
Empty function used to force the linker to link MCJIT.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI void logAllUnhandledErrors(Error E, raw_ostream &OS, Twine ErrorBanner={})
Log all errors (if any) in E to OS.
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
auto reverse(ContainerTy &&C)
GenericValue PTOGV(void *P)
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
constexpr unsigned BitWidth
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
void * GVTOP(const GenericValue &GV)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
void consumeError(Error Err)
Consume a Error without doing anything.
Implement std::hash so that hash_code can be used in STL containers.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.