diff options
author | Andrew Kaylor <andrew.kaylor@intel.com> | 2012-08-07 18:33:00 +0000 |
---|---|---|
committer | Andrew Kaylor <andrew.kaylor@intel.com> | 2012-08-07 18:33:00 +0000 |
commit | ea708d1071898bd8fda58f9d58d1d3fe38faf9f2 (patch) | |
tree | 85142cb268f20ccdd7123d494aec0e7eaa2e9ae8 /lib | |
parent | 7a8f311ece7108e44ded601237091c23ef7782eb (diff) | |
download | external_llvm-ea708d1071898bd8fda58f9d58d1d3fe38faf9f2.zip external_llvm-ea708d1071898bd8fda58f9d58d1d3fe38faf9f2.tar.gz external_llvm-ea708d1071898bd8fda58f9d58d1d3fe38faf9f2.tar.bz2 |
Enable lazy compilation in MCJIT
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@161438 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/ExecutionEngine/MCJIT/MCJIT.cpp | 49 | ||||
-rw-r--r-- | lib/ExecutionEngine/MCJIT/MCJIT.h | 19 |
2 files changed, 55 insertions, 13 deletions
diff --git a/lib/ExecutionEngine/MCJIT/MCJIT.cpp b/lib/ExecutionEngine/MCJIT/MCJIT.cpp index 84274c0..739ffd7 100644 --- a/lib/ExecutionEngine/MCJIT/MCJIT.cpp +++ b/lib/ExecutionEngine/MCJIT/MCJIT.cpp @@ -18,6 +18,7 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/DynamicLibrary.h" #include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/MutexGuard.h" #include "llvm/Target/TargetData.h" using namespace llvm; @@ -54,9 +55,35 @@ ExecutionEngine *MCJIT::createJIT(Module *M, MCJIT::MCJIT(Module *m, TargetMachine *tm, TargetJITInfo &tji, RTDyldMemoryManager *MM, bool AllocateGVsWithCode) - : ExecutionEngine(m), TM(tm), MemMgr(MM), M(m), OS(Buffer), Dyld(MM) { + : ExecutionEngine(m), TM(tm), Ctx(0), MemMgr(MM), Dyld(MM), + isCompiled(false), M(m), OS(Buffer) { setTargetData(TM->getTargetData()); +} + +MCJIT::~MCJIT() { + delete MemMgr; + delete TM; +} + +void MCJIT::emitObject(Module *m) { + /// Currently, MCJIT only supports a single module and the module passed to + /// this function call is expected to be the contained module. The module + /// is passed as a parameter here to prepare for multiple module support in + /// the future. + assert(M == m); + + // Get a thread lock to make sure we aren't trying to compile multiple times + MutexGuard locked(lock); + + // FIXME: Track compilation state on a per-module basis when multiple modules + // are supported. + // Re-compilation is not supported + if (isCompiled) + return; + + PassManager PM; + PM.add(new TargetData(*TM->getTargetData())); // Turn the machine code intermediate representation into bytes in memory @@ -69,23 +96,22 @@ MCJIT::MCJIT(Module *m, TargetMachine *tm, TargetJITInfo &tji, // FIXME: When we support multiple modules, we'll want to move the code // gen and finalization out of the constructor here and do it more // on-demand as part of getPointerToFunction(). - PM.run(*M); + PM.run(*m); // Flush the output buffer so the SmallVector gets its data. OS.flush(); // Load the object into the dynamic linker. - MemoryBuffer *MB = MemoryBuffer::getMemBuffer(StringRef(Buffer.data(), + MemoryBuffer* MB = MemoryBuffer::getMemBuffer(StringRef(Buffer.data(), Buffer.size()), "", false); if (Dyld.loadObject(MB)) report_fatal_error(Dyld.getErrorString()); + // Resolve any relocations. Dyld.resolveRelocations(); -} -MCJIT::~MCJIT() { - delete MemMgr; - delete TM; + // FIXME: Add support for per-module compilation state + isCompiled = true; } void *MCJIT::getPointerToBasicBlock(BasicBlock *BB) { @@ -93,6 +119,10 @@ void *MCJIT::getPointerToBasicBlock(BasicBlock *BB) { } void *MCJIT::getPointerToFunction(Function *F) { + // FIXME: Add support for per-module compilation state + if (!isCompiled) + emitObject(M); + if (F->isDeclaration() || F->hasAvailableExternallyLinkage()) { bool AbortOnFailure = !F->hasExternalWeakLinkage(); void *Addr = getPointerToNamedFunction(F->getName(), AbortOnFailure); @@ -100,6 +130,7 @@ void *MCJIT::getPointerToFunction(Function *F) { return Addr; } + // FIXME: Should the Dyld be retaining module information? Probably not. // FIXME: Should we be using the mangler for this? Probably. StringRef BaseName = F->getName(); if (BaseName[0] == '\1') @@ -218,6 +249,10 @@ GenericValue MCJIT::runFunction(Function *F, void *MCJIT::getPointerToNamedFunction(const std::string &Name, bool AbortOnFailure) { + // FIXME: Add support for per-module compilation state + if (!isCompiled) + emitObject(M); + if (!isSymbolSearchingDisabled() && MemMgr) { void *ptr = MemMgr->getPointerToNamedFunction(Name, false); if (ptr) diff --git a/lib/ExecutionEngine/MCJIT/MCJIT.h b/lib/ExecutionEngine/MCJIT/MCJIT.h index 2b3df98..1d272e9 100644 --- a/lib/ExecutionEngine/MCJIT/MCJIT.h +++ b/lib/ExecutionEngine/MCJIT/MCJIT.h @@ -29,17 +29,16 @@ class MCJIT : public ExecutionEngine { TargetMachine *TM; MCContext *Ctx; RTDyldMemoryManager *MemMgr; + RuntimeDyld Dyld; - // FIXME: These may need moved to a separate 'jitstate' member like the - // non-MC JIT does for multithreading and such. Just keep them here for now. - PassManager PM; + // FIXME: Add support for multiple modules + bool isCompiled; Module *M; - // FIXME: This really doesn't belong here. + + // FIXME: Move these to a single container which manages JITed objects SmallVector<char, 4096> Buffer; // Working buffer into which we JIT. raw_svector_ostream OS; - RuntimeDyld Dyld; - public: ~MCJIT(); @@ -91,6 +90,14 @@ public: TargetMachine *TM); // @} + +protected: + /// emitObject -- Generate a JITed object in memory from the specified module + /// Currently, MCJIT only supports a single module and the module passed to + /// this function call is expected to be the contained module. The module + /// is passed as a parameter here to prepare for multiple module support in + /// the future. + void emitObject(Module *M); }; } // End llvm namespace |