X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FExecutionEngine%2FExecutionEngine.cpp;h=12e0e6aee6e4ae215f8b8f98d50601a21ecc3621;hb=41367e252a806c1dfa36479d09643b3ac93a7263;hp=063f3fb05c2de903d85765d467b4285c19b3cb23;hpb=aa5b9c0f6f3a99f955fe0ded13d61d7eb4e1a0b5;p=oota-llvm.git diff --git a/lib/ExecutionEngine/ExecutionEngine.cpp b/lib/ExecutionEngine/ExecutionEngine.cpp index 063f3fb05c2..12e0e6aee6e 100644 --- a/lib/ExecutionEngine/ExecutionEngine.cpp +++ b/lib/ExecutionEngine/ExecutionEngine.cpp @@ -16,8 +16,7 @@ #include "llvm/ADT/SmallString.h" #include "llvm/ADT/Statistic.h" #include "llvm/ExecutionEngine/GenericValue.h" -#include "llvm/ExecutionEngine/JITMemoryManager.h" -#include "llvm/ExecutionEngine/ObjectCache.h" +#include "llvm/ExecutionEngine/JITEventListener.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/DerivedTypes.h" @@ -43,26 +42,21 @@ using namespace llvm; STATISTIC(NumInitBytes, "Number of bytes of global vars initialized"); STATISTIC(NumGlobals , "Number of global vars initialized"); -// Pin the vtable to this file. -void ObjectCache::anchor() {} -void ObjectBuffer::anchor() {} -void ObjectBufferStream::anchor() {} - -ExecutionEngine *(*ExecutionEngine::JITCtor)( - Module *M, - std::string *ErrorStr, - JITMemoryManager *JMM, - bool GVsWithCode, - TargetMachine *TM) = nullptr; ExecutionEngine *(*ExecutionEngine::MCJITCtor)( - Module *M, - std::string *ErrorStr, - RTDyldMemoryManager *MCJMM, - TargetMachine *TM) = nullptr; -ExecutionEngine *(*ExecutionEngine::InterpCtor)(Module *M, + std::unique_ptr M, std::string *ErrorStr, + std::unique_ptr MCJMM, + std::unique_ptr TM) = nullptr; + +ExecutionEngine *(*ExecutionEngine::OrcMCJITReplacementCtor)( + std::string *ErrorStr, std::unique_ptr OrcJMM, + std::unique_ptr TM) = nullptr; + +ExecutionEngine *(*ExecutionEngine::InterpCtor)(std::unique_ptr M, std::string *ErrorStr) =nullptr; -ExecutionEngine::ExecutionEngine(Module *M) +void JITEventListener::anchor() {} + +ExecutionEngine::ExecutionEngine(std::unique_ptr M) : EEState(*this), LazyFunctionCreator(nullptr) { CompilingLazily = false; @@ -77,14 +71,12 @@ ExecutionEngine::ExecutionEngine(Module *M) VerifyModules = false; #endif - Modules.push_back(M); assert(M && "Module is null?"); + Modules.push_back(std::move(M)); } ExecutionEngine::~ExecutionEngine() { clearAllGlobalMappings(); - for (unsigned i = 0, e = Modules.size(); i != e; ++i) - delete Modules[i]; } namespace { @@ -101,8 +93,8 @@ public: Type *ElTy = GV->getType()->getElementType(); size_t GVSize = (size_t)TD.getTypeAllocSize(ElTy); void *RawMemory = ::operator new( - DataLayout::RoundUpAlignment(sizeof(GVMemoryBlock), - TD.getPreferredAlignment(GV)) + RoundUpToAlignment(sizeof(GVMemoryBlock), + TD.getPreferredAlignment(GV)) + GVSize); new(RawMemory) GVMemoryBlock(GV); return static_cast(RawMemory) + sizeof(GVMemoryBlock); @@ -126,15 +118,20 @@ void ExecutionEngine::addObjectFile(std::unique_ptr O) { llvm_unreachable("ExecutionEngine subclass doesn't implement addObjectFile."); } -void ExecutionEngine::addArchive(std::unique_ptr A) { +void +ExecutionEngine::addObjectFile(object::OwningBinary O) { + llvm_unreachable("ExecutionEngine subclass doesn't implement addObjectFile."); +} + +void ExecutionEngine::addArchive(object::OwningBinary A) { llvm_unreachable("ExecutionEngine subclass doesn't implement addArchive."); } bool ExecutionEngine::removeModule(Module *M) { - for(SmallVectorImpl::iterator I = Modules.begin(), - E = Modules.end(); I != E; ++I) { - Module *Found = *I; + for (auto I = Modules.begin(), E = Modules.end(); I != E; ++I) { + Module *Found = I->get(); if (Found == M) { + I->release(); Modules.erase(I); clearGlobalMappingsFromModule(M); return true; @@ -145,7 +142,8 @@ bool ExecutionEngine::removeModule(Module *M) { Function *ExecutionEngine::FindFunctionNamed(const char *FnName) { for (unsigned i = 0, e = Modules.size(); i != e; ++i) { - if (Function *F = Modules[i]->getFunction(FnName)) + Function *F = Modules[i]->getFunction(FnName); + if (F && !F->isDeclaration()) return F; } return nullptr; @@ -258,19 +256,9 @@ const GlobalValue *ExecutionEngine::getGlobalValueAtAddress(void *Addr) { namespace { class ArgvArray { - char *Array; - std::vector Values; + std::unique_ptr Array; + std::vector> Values; public: - ArgvArray() : Array(nullptr) {} - ~ArgvArray() { clear(); } - void clear() { - delete[] Array; - Array = nullptr; - for (size_t I = 0, E = Values.size(); I != E; ++I) { - delete[] Values[I]; - } - Values.clear(); - } /// Turn a vector of strings into a nice argv style array of pointers to null /// terminated strings. void *reset(LLVMContext &C, ExecutionEngine *EE, @@ -279,38 +267,39 @@ public: } // anonymous namespace void *ArgvArray::reset(LLVMContext &C, ExecutionEngine *EE, const std::vector &InputArgv) { - clear(); // Free the old contents. + Values.clear(); // Free the old contents. + Values.reserve(InputArgv.size()); unsigned PtrSize = EE->getDataLayout()->getPointerSize(); - Array = new char[(InputArgv.size()+1)*PtrSize]; + Array = make_unique((InputArgv.size()+1)*PtrSize); - DEBUG(dbgs() << "JIT: ARGV = " << (void*)Array << "\n"); + DEBUG(dbgs() << "JIT: ARGV = " << (void*)Array.get() << "\n"); Type *SBytePtr = Type::getInt8PtrTy(C); for (unsigned i = 0; i != InputArgv.size(); ++i) { unsigned Size = InputArgv[i].size()+1; - char *Dest = new char[Size]; - Values.push_back(Dest); - DEBUG(dbgs() << "JIT: ARGV[" << i << "] = " << (void*)Dest << "\n"); + auto Dest = make_unique(Size); + DEBUG(dbgs() << "JIT: ARGV[" << i << "] = " << (void*)Dest.get() << "\n"); - std::copy(InputArgv[i].begin(), InputArgv[i].end(), Dest); + std::copy(InputArgv[i].begin(), InputArgv[i].end(), Dest.get()); Dest[Size-1] = 0; // Endian safe: Array[i] = (PointerTy)Dest; - EE->StoreValueToMemory(PTOGV(Dest), (GenericValue*)(Array+i*PtrSize), - SBytePtr); + EE->StoreValueToMemory(PTOGV(Dest.get()), + (GenericValue*)(&Array[i*PtrSize]), SBytePtr); + Values.push_back(std::move(Dest)); } // Null terminate it EE->StoreValueToMemory(PTOGV(nullptr), - (GenericValue*)(Array+InputArgv.size()*PtrSize), + (GenericValue*)(&Array[InputArgv.size()*PtrSize]), SBytePtr); - return Array; + return Array.get(); } -void ExecutionEngine::runStaticConstructorsDestructors(Module *module, +void ExecutionEngine::runStaticConstructorsDestructors(Module &module, bool isDtors) { const char *Name = isDtors ? "llvm.global_dtors" : "llvm.global_ctors"; - GlobalVariable *GV = module->getNamedGlobal(Name); + GlobalVariable *GV = module.getNamedGlobal(Name); // If this global has internal linkage, or if it has a use, then it must be // an old-style (llvmgcc3) static ctor with __main linked in and in use. If @@ -348,8 +337,8 @@ void ExecutionEngine::runStaticConstructorsDestructors(Module *module, void ExecutionEngine::runStaticConstructorsDestructors(bool isDtors) { // Execute global ctors/dtors for each module in the program. - for (unsigned i = 0, e = Modules.size(); i != e; ++i) - runStaticConstructorsDestructors(Modules[i], isDtors); + for (std::unique_ptr &M : Modules) + runStaticConstructorsDestructors(*M, isDtors); } #ifndef NDEBUG @@ -410,17 +399,32 @@ int ExecutionEngine::runFunctionAsMain(Function *Fn, return runFunction(Fn, GVArgs).IntVal.getZExtValue(); } +EngineBuilder::EngineBuilder() { + InitEngine(); +} + +EngineBuilder::EngineBuilder(std::unique_ptr M) + : M(std::move(M)), MCJMM(nullptr) { + InitEngine(); +} + +EngineBuilder::~EngineBuilder() {} + +EngineBuilder &EngineBuilder::setMCJITMemoryManager( + std::unique_ptr mcjmm) { + MCJMM = std::move(mcjmm); + return *this; +} + void EngineBuilder::InitEngine() { WhichEngine = EngineKind::Either; ErrorStr = nullptr; OptLevel = CodeGenOpt::Default; MCJMM = nullptr; - JMM = nullptr; Options = TargetOptions(); - AllocateGVsWithCode = false; RelocModel = Reloc::Default; CMModel = CodeModel::JITDefault; - UseMCJIT = false; + UseOrcMCJITReplacement = false; // IR module verification is enabled by default in debug builds, and disabled // by default in release builds. @@ -438,13 +442,11 @@ ExecutionEngine *EngineBuilder::create(TargetMachine *TM) { // to the function tells DynamicLibrary to load the program, not a library. if (sys::DynamicLibrary::LoadLibraryPermanently(nullptr, ErrorStr)) return nullptr; - - assert(!(JMM && MCJMM)); // If the user specified a memory manager but didn't specify which engine to // create, we assume they only want the JIT, and we fail if they only want // the interpreter. - if (JMM || MCJMM) { + if (MCJMM) { if (WhichEngine & EngineKind::JIT) WhichEngine = EngineKind::JIT; else { @@ -453,14 +455,6 @@ ExecutionEngine *EngineBuilder::create(TargetMachine *TM) { return nullptr; } } - - if (MCJMM && ! UseMCJIT) { - if (ErrorStr) - *ErrorStr = - "Cannot create a legacy JIT with a runtime dyld memory " - "manager."; - return nullptr; - } // Unless the interpreter was explicitly selected or the JIT is not linked, // try making a JIT. @@ -473,12 +467,13 @@ ExecutionEngine *EngineBuilder::create(TargetMachine *TM) { } ExecutionEngine *EE = nullptr; - if (UseMCJIT && ExecutionEngine::MCJITCtor) - EE = ExecutionEngine::MCJITCtor(M, ErrorStr, MCJMM ? MCJMM : JMM, - TheTM.release()); - else if (ExecutionEngine::JITCtor) - EE = ExecutionEngine::JITCtor(M, ErrorStr, JMM, - AllocateGVsWithCode, TheTM.release()); + if (ExecutionEngine::OrcMCJITReplacementCtor && UseOrcMCJITReplacement) { + EE = ExecutionEngine::OrcMCJITReplacementCtor(ErrorStr, std::move(MCJMM), + std::move(TheTM)); + EE->addModule(std::move(M)); + } else if (ExecutionEngine::MCJITCtor) + EE = ExecutionEngine::MCJITCtor(std::move(M), ErrorStr, std::move(MCJMM), + std::move(TheTM)); if (EE) { EE->setVerifyModules(VerifyModules); @@ -490,14 +485,13 @@ ExecutionEngine *EngineBuilder::create(TargetMachine *TM) { // an interpreter instead. if (WhichEngine & EngineKind::Interpreter) { if (ExecutionEngine::InterpCtor) - return ExecutionEngine::InterpCtor(M, ErrorStr); + return ExecutionEngine::InterpCtor(std::move(M), ErrorStr); if (ErrorStr) *ErrorStr = "Interpreter has not been linked in."; return nullptr; } - if ((WhichEngine & EngineKind::JIT) && !ExecutionEngine::JITCtor && - !ExecutionEngine::MCJITCtor) { + if ((WhichEngine & EngineKind::JIT) && !ExecutionEngine::MCJITCtor) { if (ErrorStr) *ErrorStr = "JIT has not been linked in."; } @@ -843,9 +837,6 @@ GenericValue ExecutionEngine::getConstantValue(const Constant *C) { Result = PTOGV(getPointerToFunctionOrStub(const_cast(F))); else if (const GlobalVariable *GV = dyn_cast(C)) Result = PTOGV(getOrEmitGlobalVariable(const_cast(GV))); - else if (const BlockAddress *BA = dyn_cast(C)) - Result = PTOGV(getPointerToBasicBlock(const_cast( - BA->getBasicBlock()))); else llvm_unreachable("Unknown constant pointer type!"); break;