LLVM: lib/ExecutionEngine/MCJIT/MCJIT.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
28#include
29
30using namespace llvm;
31
32namespace {
33
34static struct RegisterJIT {
36} JITRegistrator;
37
38}
39
41}
42
45 std::shared_ptr MemMgr,
46 std::shared_ptr Resolver,
47 std::unique_ptr TM) {
48
49
50
52
54 auto RTDyldMM = std::make_shared();
55 if (!MemMgr)
56 MemMgr = RTDyldMM;
59 }
60
61 return new MCJIT(std::move(M), std::move(TM), std::move(MemMgr),
63}
64
65MCJIT::MCJIT(std::unique_ptr M, std::unique_ptr TM,
66 std::shared_ptr MemMgr,
67 std::shared_ptr Resolver)
69 Ctx(nullptr), MemMgr(std::move(MemMgr)),
71 ObjCache(nullptr) {
72
73
74
75
76
77
78
79
80
81
82 std::unique_ptr First = std::move(Modules[0]);
84
85 if (First->getDataLayout().isDefault())
87
88 OwnedModules.addModule(std::move(First));
90}
91
93 std::lock_guardsys::Mutex locked(lock);
94
96
97 for (auto &Obj : LoadedObjects)
98 if (Obj)
100
101 Archives.clear();
102}
103
105 std::lock_guardsys::Mutex locked(lock);
106
107 if (M->getDataLayout().isDefault())
109
110 OwnedModules.addModule(std::move(M));
111}
112
114 std::lock_guardsys::Mutex locked(lock);
115 return OwnedModules.removeModule(M);
116}
117
119 std::unique_ptrRuntimeDyld::LoadedObjectInfo L = Dyld.loadObject(*Obj);
122
124
125 LoadedObjects.push_back(std::move(Obj));
126}
127
129 std::unique_ptrobject::ObjectFile ObjFile;
130 std::unique_ptr MemBuf;
131 std::tie(ObjFile, MemBuf) = Obj.takeBinary();
133 Buffers.push_back(std::move(MemBuf));
134}
135
137 Archives.push_back(std::move(A));
138}
139
141 std::lock_guardsys::Mutex locked(lock);
142 ObjCache = NewCache;
143}
144
146 assert(M && "Can not emit a null module");
147
148 std::lock_guardsys::Mutex locked(lock);
149
150
151
152 cantFail(M->materializeAll());
153
154
155
156
157
159
160
163
164
165
166 if (TM->addPassesToEmitMC(PM, Ctx, ObjStream, ()))
168
169
170 PM.run(*M);
171
172
173 auto CompiledObjBuffer = std::make_unique(
174 std::move(ObjBufferSV), false);
175
176
177
178 if (ObjCache) {
179
180
181 MemoryBufferRef MB = CompiledObjBuffer->getMemBufferRef();
183 }
184
185 return CompiledObjBuffer;
186}
187
189
190 std::lock_guardsys::Mutex locked(lock);
191
192
193 assert(OwnedModules.ownsModule(M) &&
194 "MCJIT::generateCodeForModule: Unknown module.");
195
196
197 if (OwnedModules.hasModuleBeenLoaded(M))
198 return;
199
200 std::unique_ptr ObjectToLoad;
201
202 if (ObjCache)
203 ObjectToLoad = ObjCache->getObject(M);
204
206
207
208 if (!ObjectToLoad) {
210 assert(ObjectToLoad && "Compilation did not produce an object.");
211 }
212
213
214
217 if (!LoadedObject) {
218 std::string Buf;
222 }
223 std::unique_ptrRuntimeDyld::LoadedObjectInfo L =
225
228
230
231 Buffers.push_back(std::move(ObjectToLoad));
232 LoadedObjects.push_back(std::move(*LoadedObject));
233
234 OwnedModules.markModuleAsLoaded(M);
235}
236
238 std::lock_guardsys::Mutex locked(lock);
239
240
242
243
246
247 OwnedModules.markAllLoadedModulesAsFinalized();
248
249
251
252
253 MemMgr->finalizeMemory();
254}
255
256
258 std::lock_guardsys::Mutex locked(lock);
259
260
261
263
264 for (auto *M : ModsToAdd)
266
268}
269
271 std::lock_guardsys::Mutex locked(lock);
272
273
274 assert(OwnedModules.ownsModule(M) && "MCJIT::finalizeModule: Unknown module.");
275
276
277 if (!OwnedModules.hasModuleBeenLoaded(M))
279
281}
282
286 reinterpret_cast<uintptr_t>(Addr)),
288
290}
291
293 bool CheckFunctionsOnly) {
295 if (DemangledName[0] == getDataLayout().getGlobalPrefix())
296 DemangledName = DemangledName.substr(1);
297
298 std::lock_guardsys::Mutex locked(lock);
299
300
302 E = OwnedModules.end_added();
305 Function *F = M->getFunction(DemangledName);
306 if (F && ->isDeclaration())
307 return M;
308 if (!CheckFunctionsOnly) {
310 if (G && ->isDeclaration())
311 return M;
312
313 }
314 }
315
316 return nullptr;
317}
318
320 bool CheckFunctionsOnly) {
321 std::string MangledName;
322 {
325 }
326 if (auto Sym = findSymbol(MangledName, CheckFunctionsOnly)) {
327 if (auto AddrOrErr = Sym.getAddress())
328 return *AddrOrErr;
329 else
331 } else if (auto Err = Sym.takeError())
333 return 0;
334}
335
337 bool CheckFunctionsOnly) {
338 std::lock_guardsys::Mutex locked(lock);
339
340
342 return Sym;
343
346
347 auto OptionalChildOrErr = A->findSym(Name);
348 if (!OptionalChildOrErr)
350 auto &OptionalChild = *OptionalChildOrErr;
351 if (OptionalChild) {
352
354 OptionalChild->getAsBinary();
355 if (!ChildBinOrErr) {
356
358 continue;
359 }
360 std::unique_ptrobject::Binary &ChildBin = ChildBinOrErr.get();
361 if (ChildBin->isObject()) {
362 std::unique_ptrobject::ObjectFile OF(
364
366
368 return Sym;
369 }
370 }
371 }
372
373
375 if (M) {
377
378
380 }
381
382
383
388 }
389
390 return nullptr;
391}
392
394 std::lock_guardsys::Mutex locked(lock);
396 if (Result != 0)
398 return Result;
399}
400
402 std::lock_guardsys::Mutex locked(lock);
404 if (Result != 0)
406 return Result;
407}
408
409
411 std::lock_guardsys::Mutex locked(lock);
412
415 TM->getNameWithPrefix(Name, F, Mang);
416
417 if (F->isDeclaration() || F->hasAvailableExternallyLinkage()) {
418 bool AbortOnFailure = ->hasExternalWeakLinkage();
422 }
423
424 Module *M = F->getParent();
425 bool HasBeenAddedButNotLoaded = OwnedModules.hasModuleBeenAddedButNotLoaded(M);
426
427
428 if (HasBeenAddedButNotLoaded)
430 else if (!OwnedModules.hasModuleBeenLoaded(M)) {
431
432
433
434
435 return nullptr;
436 }
437
438
439
440
441
443}
444
445void MCJIT::runStaticConstructorsDestructorsInModulePtrSet(
446 bool isDtors, ModulePtrSet::iterator I, ModulePtrSet::iterator E) {
449 }
450}
451
453
454 runStaticConstructorsDestructorsInModulePtrSet(
455 isDtors, OwnedModules.begin_added(), OwnedModules.end_added());
456 runStaticConstructorsDestructorsInModulePtrSet(
457 isDtors, OwnedModules.begin_loaded(), OwnedModules.end_loaded());
458 runStaticConstructorsDestructorsInModulePtrSet(
459 isDtors, OwnedModules.begin_finalized(), OwnedModules.end_finalized());
460}
461
462Function *MCJIT::FindFunctionNamedInModulePtrSet(StringRef FnName,
463 ModulePtrSet::iterator I,
464 ModulePtrSet::iterator E) {
466 Function *F = (*I)->getFunction(FnName);
467 if (F && ->isDeclaration())
468 return F;
469 }
470 return nullptr;
471}
472
474 bool AllowInternal,
475 ModulePtrSet::iterator I,
476 ModulePtrSet::iterator E) {
480 return GV;
481 }
482 return nullptr;
483}
484
485
487 Function *F = FindFunctionNamedInModulePtrSet(
488 FnName, OwnedModules.begin_added(), OwnedModules.end_added());
489 if ()
490 F = FindFunctionNamedInModulePtrSet(FnName, OwnedModules.begin_loaded(),
491 OwnedModules.end_loaded());
492 if ()
493 F = FindFunctionNamedInModulePtrSet(FnName, OwnedModules.begin_finalized(),
494 OwnedModules.end_finalized());
495 return F;
496}
497
499 GlobalVariable *GV = FindGlobalVariableNamedInModulePtrSet(
500 Name, AllowInternal, OwnedModules.begin_added(), OwnedModules.end_added());
501 if (!GV)
502 GV = FindGlobalVariableNamedInModulePtrSet(Name, AllowInternal, OwnedModules.begin_loaded(),
503 OwnedModules.end_loaded());
504 if (!GV)
505 GV = FindGlobalVariableNamedInModulePtrSet(Name, AllowInternal, OwnedModules.begin_finalized(),
506 OwnedModules.end_finalized());
507 return GV;
508}
509
511 assert(F && "Function *F was null at entry to run()");
512
515 assert(FPtr && "Pointer to fn's code was null after getPointerToFunction");
518
521 "Wrong number of arguments passed into function!");
523 "This doesn't support passing arguments through varargs (yet)!");
524
525
526
527 if (RetTy->isIntegerTy(32) || RetTy->isVoidTy()) {
528 switch (ArgValues.size()) {
529 case 3:
533 int (*PF)(int, char **, const char **) =
534 (int(*)(int, char **, const char **))(intptr_t)FPtr;
535
536
538 rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue(),
539 (char **)GVTOP(ArgValues[1]),
540 (const char **)GVTOP(ArgValues[2])));
541 return rv;
542 }
543 break;
544 case 2:
547 int (*PF)(int, char **) = (int(*)(int, char **))(intptr_t)FPtr;
548
549
551 rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue(),
552 (char **)GVTOP(ArgValues[1])));
553 return rv;
554 }
555 break;
556 case 1:
560 int (*PF)(int) = (int(*)(int))(intptr_t)FPtr;
561 rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue()));
562 return rv;
563 }
564 break;
565 }
566 }
567
568
569 if (ArgValues.empty()) {
571 switch (RetTy->getTypeID()) {
572 default: llvm_unreachable("Unknown return type for function call!");
574 unsigned BitWidth = cast(RetTy)->getBitWidth();
585 else
587 return rv;
588 }
590 rv.IntVal = APInt(32, ((int (*)())(intptr_t)FPtr)(), true);
591 return rv;
593 rv.FloatVal = ((float(*)())(intptr_t)FPtr)();
594 return rv;
596 rv.DoubleVal = ((double(*)())(intptr_t)FPtr)();
597 return rv;
603 return PTOGV(((void*(*)())(intptr_t)FPtr)());
604 }
605 }
606
607 report_fatal_error("MCJIT::runFunction does not support full-featured "
608 "argument passing. Please use "
609 "ExecutionEngine::getFunctionAddress and cast the result "
610 "to the desired function pointer type.");
611}
612
616 if (auto AddrOrErr = Sym.getAddress())
617 return reinterpret_cast<void*>(
618 static_cast<uintptr_t>(*AddrOrErr));
619 } else if (auto Err = Sym.takeError())
621 }
622
623
626 return RP;
627
628 if (AbortOnFailure) {
630 "' which could not be resolved!");
631 }
632 return nullptr;
633}
634
636 if (!L)
637 return;
638 std::lock_guardsys::Mutex locked(lock);
639 EventListeners.push_back(L);
640}
641
643 if (!L)
644 return;
645 std::lock_guardsys::Mutex locked(lock);
647 if (I != EventListeners.rend()) {
648 std::swap(*I, EventListeners.back());
649 EventListeners.pop_back();
650 }
651}
652
656 static_cast<uint64_t>(reinterpret_cast<uintptr_t>(Obj.getData().data()));
657 std::lock_guardsys::Mutex locked(lock);
658 MemMgr->notifyObjectLoaded(this, Obj);
660 EL->notifyObjectLoaded(Key, Obj, L);
661}
662
665 static_cast<uint64_t>(reinterpret_cast<uintptr_t>(Obj.getData().data()));
666 std::lock_guardsys::Mutex locked(lock);
668 L->notifyFreeingObject(Key);
669}
670
674 if (Result)
675 return Result;
677 return nullptr;
678 return ClientResolver->findSymbol(Name);
679}
680
681void LinkingSymbolResolver::anchor() {}
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
Module.h This file contains the declarations for the Module class.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Class for arbitrary precision integers.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
bool empty() const
empty - Check if the array is empty.
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
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
JITTargetAddress getAddress() const
Return the address of this symbol.
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.
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...
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...
virtual void notifyObjectCompiled(const Module *M, MemoryBufferRef Obj)=0
notifyObjectCompiled - Provides a pointer to compiled code for Module M.
Interface for looking up the initializer for a variable name, used by Init::resolveReferences.
Information about the loaded object.
void resolveRelocations()
Resolve the relocations for all symbols we currently know about.
void deregisterEHFrames()
void registerEHFrames()
Register any EH frame sections that have been loaded but not previously registered with the memory ma...
JITEvaluatedSymbol getSymbol(StringRef Name) const
Get the target address and flags for the named symbol.
std::unique_ptr< LoadedObjectInfo > loadObject(const object::ObjectFile &O)
Add the referenced object file to the list of objects to be loaded and relocated.
StringRef getErrorString()
SmallPtrSetIterator - This implements a const_iterator for SmallPtrSet.
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.
StringRef - Represent a constant reference to a string, i.e.
std::string str() const
str - Get the contents as an std::string.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
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.
PassManager manages ModulePassManagers.
bool run(Module &M)
run - Execute all of the passes scheduled for execution.
StringRef getData() const
This class is the base class for all object file types.
static Expected< OwningBinary< ObjectFile > > createObjectFile(StringRef ObjectPath)
std::pair< std::unique_ptr< T >, std::unique_ptr< MemoryBuffer > > takeBinary()
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.
#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.
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)
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
@ 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)
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.