Go to the documentation of this file.
35 static struct RegisterJIT {
46 std::shared_ptr<MCJITMemoryManager> MemMgr,
47 std::shared_ptr<LegacyJITSymbolResolver>
Resolver,
48 std::unique_ptr<TargetMachine>
TM) {
55 auto RTDyldMM = std::make_shared<SectionMemoryManager>();
66 MCJIT::MCJIT(std::unique_ptr<Module> M, std::unique_ptr<TargetMachine>
TM,
67 std::shared_ptr<MCJITMemoryManager> MemMgr,
68 std::shared_ptr<LegacyJITSymbolResolver>
Resolver)
70 Ctx(nullptr), MemMgr(
std::
move(MemMgr)),
86 if (
First->getDataLayout().isDefault())
94 std::lock_guard<sys::Mutex> locked(
lock);
98 for (
auto &Obj : LoadedObjects)
106 std::lock_guard<sys::Mutex> locked(
lock);
108 if (
M->getDataLayout().isDefault())
115 std::lock_guard<sys::Mutex> locked(
lock);
116 return OwnedModules.removeModule(
M);
120 std::unique_ptr<RuntimeDyld::LoadedObjectInfo> L = Dyld.
loadObject(*Obj);
130 std::unique_ptr<object::ObjectFile> ObjFile;
131 std::unique_ptr<MemoryBuffer> MemBuf;
142 std::lock_guard<sys::Mutex> locked(
lock);
147 assert(
M &&
"Can not emit a null module");
149 std::lock_guard<sys::Mutex> locked(
lock);
174 auto CompiledObjBuffer = std::make_unique<SmallVectorMemoryBuffer>(
186 return CompiledObjBuffer;
191 std::lock_guard<sys::Mutex> locked(
lock);
194 assert(OwnedModules.ownsModule(
M) &&
195 "MCJIT::generateCodeForModule: Unknown module.");
198 if (OwnedModules.hasModuleBeenLoaded(
M))
201 std::unique_ptr<MemoryBuffer> ObjectToLoad;
211 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())
265 ModsToAdd.push_back(
M);
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();
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(
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])));
555 (
char **)
GVTOP(ArgValues[1])));
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();
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);
670 std::lock_guard<sys::Mutex> locked(
lock);
672 L->notifyFreeingObject(
Key);
682 return ClientResolver->findSymbol(
Name);
685 void LinkingSymbolResolver::anchor() {}
uint64_t getFunctionAddress(const std::string &Name) override
getFunctionAddress - Return the address of the specified function.
@ FloatTyID
32-bit floating point type
@ DoubleTyID
64-bit floating point type
This is an optimization pass for GlobalISel generic memory operations.
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
bool isPointerTy() const
True if this is an instance of PointerType.
void finalizeLoadedModules()
uint64_t updateGlobalMapping(const GlobalValue *GV, void *Addr)
updateGlobalMapping - Replace an existing mapping for GV with a new address.
@ VoidTyID
type with no size
virtual void notifyObjectCompiled(const Module *M, MemoryBufferRef Obj)=0
notifyObjectCompiled - Provides a pointer to compiled code for Module M.
A raw_ostream that writes to an std::string.
Function * FindFunctionNamed(StringRef FnName) override
FindFunctionNamed - Search all of the active modules to find the function that defines FnName.
into xmm2 addss xmm2 xmm1 xmm3 addss xmm3 movaps xmm0 unpcklps xmm0 ret seems silly when it could just be one addps Expand libm rounding functions main should enable SSE DAZ mode and other fast SSE modes Think about doing i64 math in SSE regs on x86 This testcase should have no SSE instructions in and only one load from a constant double
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
TypeID getTypeID() const
Return the type id for the type.
void setObjectCache(ObjectCache *manager) override
Sets the object manager that MCJIT should use to avoid compilation.
void * getPointerToNamedFunction(StringRef Name, bool AbortOnFailure=true) override
getPointerToNamedFunction - This method returns the address of the specified function by using the dl...
uint64_t getSymbolAddress(const std::string &Name, bool CheckFunctionsOnly)
The instances of the Type class are immutable: once they are created, they are never changed.
auto reverse(ContainerTy &&C, std::enable_if_t< has_rbegin< ContainerTy >::value > *=nullptr)
bool isSymbolSearchingDisabled() const
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.
void generateCodeForModule(Module *M) override
generateCodeForModule - Run code generation for the specified module and load it into memory.
unsigned getNumParams() const
Return the number of fixed parameters this function type requires.
Tagged union holding either a T or a Error.
void * getPointerToFunction(Function *F) override
getPointerToFunction - The different EE's represent function bodies in different ways.
void consumeError(Error Err)
Consume a Error without doing anything.
SmallVector< std::unique_ptr< Module >, 1 > Modules
The list of Modules that we are JIT'ing from.
bool empty() const
empty - Check if the array is empty.
std::unique_ptr< LoadedObjectInfo > loadObject(const object::ObjectFile &O)
Add the referenced object file to the list of objects to be loaded and relocated.
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...
Interface for looking up the initializer for a variable name, used by Init::resolveReferences.
LLVM_NODISCARD StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
sys::Mutex lock
lock - This lock protects the ExecutionEngine and MCJIT classes.
GenericValue runFunction(Function *F, ArrayRef< GenericValue > ArgValues) override
runFunction - Execute the specified function with the specified arguments, and return the result.
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
bool getVerifyModules() const
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
void finalizeObject() override
finalizeObject - ensure the module is fully processed and is usable.
Clang compiles this i1 i64 store i64 i64 store i64 i64 store i64 i64 store i64 align Which gets codegen d xmm0 movaps rbp movaps rbp movaps rbp movaps rbp rbp rbp rbp rbp It would be better to have movq s of instead of the movaps s LLVM produces ret int
void runStaticConstructorsDestructors(bool isDtors) override
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...
void * GVTOP(const GenericValue &GV)
void getNameWithPrefix(raw_ostream &OS, const GlobalValue *GV, bool CannotUsePrivateLabel) const
Print the appropriate prefix and the specified global variable's name.
into llvm powi allowing the code generator to produce balanced multiplication trees First
void addModule(std::unique_ptr< Module > M) override
Add a Module to the list of modules that we can JIT from.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Module * findModuleForSymbol(const std::string &Name, bool CheckFunctionsOnly)
std::pair< std::unique_ptr< T >, std::unique_ptr< MemoryBuffer > > takeBinary()
void notifyFreeingObject(const object::ObjectFile &Obj)
bool removeModule(Module *M) override
removeModule - Removes a Module from the list of modules, but does not free the module's memory.
JITSymbol findSymbol(const std::string &Name) override
This method returns the address of the specified function or variable.
LLVM_NODISCARD std::string str() const
str - Get the contents as an std::string.
void registerEHFrames()
Register any EH frame sections that have been loaded but not previously registered with the memory ma...
virtual void runStaticConstructorsDestructors(bool isDtors)
runStaticConstructorsDestructors - This method is used to execute all of the static constructors or d...
const DataLayout & getDataLayout() const
uint64_t getGlobalValueAddress(const std::string &Name) override
getGlobalValueAddress - Return the address of the specified global value.
bool isIntegerTy() const
True if this is an instance of IntegerType.
virtual void finalizeModule(Module *)
SmallPtrSetIterator< Module * > iterator
std::unique_ptr< MemoryBuffer > emitObject(Module *M)
emitObject – Generate a JITed object in memory from the specified module Currently,...
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Type * getParamType(unsigned i) const
Parameter type accessors.
static Expected< OwningBinary< ObjectFile > > createObjectFile(StringRef ObjectPath)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
bool isVoidTy() const
Return true if this is 'void'.
A Module instance is used to store all the information related to an LLVM module.
void notifyObjectLoaded(const object::ObjectFile &Obj, const RuntimeDyld::LoadedObjectInfo &L)
JITEventListener - Abstract interface for use by the JIT to notify clients about significant events d...
Class for arbitrary precision integers.
@ FP128TyID
128-bit floating point type (112-bit significand)
JITSymbol findExistingSymbol(const std::string &Name)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
@ PPC_FP128TyID
128-bit floating point type (two 64-bits, PowerPC)
StringRef - Represent a constant reference to a string, i.e.
Analysis the ScalarEvolution expression for r is this
This class is the base class for all object file types.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
reference get()
Returns a reference to the stored T value.
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
@ IntegerTyID
Arbitrary bit width integers.
void logAllUnhandledErrors(Error E, raw_ostream &OS, Twine ErrorBanner={})
Log all errors (if any) in E to OS.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
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)
Abstract interface for implementation execution of LLVM modules, designed to support both interpreter...
Information about the loaded object.
PassManager manages ModulePassManagers.
constexpr unsigned BitWidth
GlobalVariable * FindGlobalVariableNamed(StringRef Name, bool AllowInternal=false) override
FindGlobalVariableNamed - Search all of the active modules to find the global variable that defines N...
void * getPointerToGlobalIfAvailable(StringRef S)
getPointerToGlobalIfAvailable - This returns the address of the specified global value if it is has a...
StringRef getErrorString()
Error takeError()
Take ownership of the stored error.
void UnregisterJITEventListener(JITEventListener *L) override
GenericValue PTOGV(void *P)
JITTargetAddress getAddress() const
Return the address of this symbol.
size_t size() const
size - Get the array size.
A raw_ostream that writes to an SmallVector or SmallString.
void deregisterEHFrames()
const LLVM_NODISCARD char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
JITSymbol findSymbol(const std::string &Name, bool CheckFunctionsOnly)
JITEvaluatedSymbol getSymbol(StringRef Name) const
Get the target address and flags for the named symbol.
StringRef getData() const
bool run(Module &M)
run - Execute all of the passes scheduled for execution.
const char LLVMTargetMachineRef TM
Represents a symbol in the JIT.
static bool LoadLibraryPermanently(const char *Filename, std::string *ErrMsg=nullptr)
This function permanently loads the dynamic library at the given path.
void addObjectFile(std::unique_ptr< object::ObjectFile > O) override
addObjectFile - Add an ObjectFile to the execution engine.
std::string & str()
Returns the string's reference.
static JITEventListener * createGDBRegistrationListener()
void RegisterJITEventListener(JITEventListener *L) override
Registers a listener to be called back on various events within the JIT.
void addArchive(object::OwningBinary< object::Archive > O) override
addArchive - Add an Archive to the execution engine.
Type * getReturnType() const
@ X86_FP80TyID
80-bit floating point type (X87)
Class to represent function types.