X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FExecutionEngine%2FExecutionEngine.cpp;h=a41dd26ee6837458d5706016efc404be28b8c912;hb=165897841bdb651c9d10f4b078f5804b2ca8c30c;hp=e43ba4f1dd02c54752f36c3f7f1ea101adb649bd;hpb=21a01d1ea89dba97c4f9e1f9f41485729a4046bc;p=oota-llvm.git diff --git a/lib/ExecutionEngine/ExecutionEngine.cpp b/lib/ExecutionEngine/ExecutionEngine.cpp index e43ba4f1dd0..a41dd26ee68 100644 --- a/lib/ExecutionEngine/ExecutionEngine.cpp +++ b/lib/ExecutionEngine/ExecutionEngine.cpp @@ -12,55 +12,71 @@ // //===----------------------------------------------------------------------===// -#define DEBUG_TYPE "jit" #include "llvm/ExecutionEngine/ExecutionEngine.h" #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/IR/Constants.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Module.h" #include "llvm/IR/Operator.h" +#include "llvm/IR/ValueHandle.h" +#include "llvm/Object/Archive.h" +#include "llvm/Object/ObjectFile.h" #include "llvm/Support/Debug.h" #include "llvm/Support/DynamicLibrary.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Host.h" #include "llvm/Support/MutexGuard.h" #include "llvm/Support/TargetRegistry.h" -#include "llvm/Support/ValueHandle.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetMachine.h" #include #include using namespace llvm; +#define DEBUG_TYPE "jit" + 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) = 0; + TargetMachine *TM) = nullptr; ExecutionEngine *(*ExecutionEngine::MCJITCtor)( Module *M, std::string *ErrorStr, - JITMemoryManager *JMM, - bool GVsWithCode, - TargetMachine *TM) = 0; + RTDyldMemoryManager *MCJMM, + TargetMachine *TM) = nullptr; ExecutionEngine *(*ExecutionEngine::InterpCtor)(Module *M, - std::string *ErrorStr) = 0; + std::string *ErrorStr) =nullptr; ExecutionEngine::ExecutionEngine(Module *M) : EEState(*this), - LazyFunctionCreator(0), - ExceptionTableRegister(0), - ExceptionTableDeregister(0) { + LazyFunctionCreator(nullptr) { CompilingLazily = false; GVCompilationDisabled = false; SymbolSearchingDisabled = false; + + // IR module verification is enabled by default in debug builds, and disabled + // by default in release builds. +#ifndef NDEBUG + VerifyModules = true; +#else + VerifyModules = false; +#endif + Modules.push_back(M); assert(M && "Module is null?"); } @@ -71,16 +87,6 @@ ExecutionEngine::~ExecutionEngine() { delete Modules[i]; } -void ExecutionEngine::DeregisterAllTables() { - if (ExceptionTableDeregister) { - DenseMap::iterator it = AllExceptionTables.begin(); - DenseMap::iterator ite = AllExceptionTables.end(); - for (; it != ite; ++it) - ExceptionTableDeregister(it->second); - AllExceptionTables.clear(); - } -} - namespace { /// \brief Helper class which uses a value handler to automatically deletes the /// memory block when the GlobalVariable is destroyed. @@ -102,7 +108,7 @@ public: return static_cast(RawMemory) + sizeof(GVMemoryBlock); } - virtual void deleted() { + void deleted() override { // We allocated with operator new and with some extra memory hanging off the // end, so don't just delete this. I'm not sure if this is actually // required. @@ -116,8 +122,16 @@ char *ExecutionEngine::getMemoryForGV(const GlobalVariable *GV) { return GVMemoryBlock::Create(GV, *getDataLayout()); } +void ExecutionEngine::addObjectFile(std::unique_ptr O) { + llvm_unreachable("ExecutionEngine subclass doesn't implement addObjectFile."); +} + +void ExecutionEngine::addArchive(std::unique_ptr A) { + llvm_unreachable("ExecutionEngine subclass doesn't implement addArchive."); +} + bool ExecutionEngine::removeModule(Module *M) { - for(SmallVector::iterator I = Modules.begin(), + for(SmallVectorImpl::iterator I = Modules.begin(), E = Modules.end(); I != E; ++I) { Module *Found = *I; if (Found == M) { @@ -134,19 +148,18 @@ Function *ExecutionEngine::FindFunctionNamed(const char *FnName) { if (Function *F = Modules[i]->getFunction(FnName)) return F; } - return 0; + return nullptr; } -void *ExecutionEngineState::RemoveMapping(const MutexGuard &, - const GlobalValue *ToUnmap) { +void *ExecutionEngineState::RemoveMapping(const GlobalValue *ToUnmap) { GlobalAddressMapTy::iterator I = GlobalAddressMap.find(ToUnmap); void *OldVal; // FIXME: This is silly, we shouldn't end up with a mapping -> 0 in the // GlobalAddressMap. if (I == GlobalAddressMap.end()) - OldVal = 0; + OldVal = nullptr; else { OldVal = I->second; GlobalAddressMap.erase(I); @@ -161,15 +174,15 @@ void ExecutionEngine::addGlobalMapping(const GlobalValue *GV, void *Addr) { DEBUG(dbgs() << "JIT: Map \'" << GV->getName() << "\' to [" << Addr << "]\n";); - void *&CurVal = EEState.getGlobalAddressMap(locked)[GV]; - assert((CurVal == 0 || Addr == 0) && "GlobalMapping already established!"); + void *&CurVal = EEState.getGlobalAddressMap()[GV]; + assert((!CurVal || !Addr) && "GlobalMapping already established!"); CurVal = Addr; // If we are using the reverse mapping, add it too. - if (!EEState.getGlobalAddressReverseMap(locked).empty()) { + if (!EEState.getGlobalAddressReverseMap().empty()) { AssertingVH &V = - EEState.getGlobalAddressReverseMap(locked)[Addr]; - assert((V == 0 || GV == 0) && "GlobalMapping already established!"); + EEState.getGlobalAddressReverseMap()[Addr]; + assert((!V || !GV) && "GlobalMapping already established!"); V = GV; } } @@ -177,42 +190,42 @@ void ExecutionEngine::addGlobalMapping(const GlobalValue *GV, void *Addr) { void ExecutionEngine::clearAllGlobalMappings() { MutexGuard locked(lock); - EEState.getGlobalAddressMap(locked).clear(); - EEState.getGlobalAddressReverseMap(locked).clear(); + EEState.getGlobalAddressMap().clear(); + EEState.getGlobalAddressReverseMap().clear(); } void ExecutionEngine::clearGlobalMappingsFromModule(Module *M) { MutexGuard locked(lock); for (Module::iterator FI = M->begin(), FE = M->end(); FI != FE; ++FI) - EEState.RemoveMapping(locked, FI); + EEState.RemoveMapping(FI); for (Module::global_iterator GI = M->global_begin(), GE = M->global_end(); GI != GE; ++GI) - EEState.RemoveMapping(locked, GI); + EEState.RemoveMapping(GI); } void *ExecutionEngine::updateGlobalMapping(const GlobalValue *GV, void *Addr) { MutexGuard locked(lock); ExecutionEngineState::GlobalAddressMapTy &Map = - EEState.getGlobalAddressMap(locked); + EEState.getGlobalAddressMap(); // Deleting from the mapping? - if (Addr == 0) - return EEState.RemoveMapping(locked, GV); + if (!Addr) + return EEState.RemoveMapping(GV); void *&CurVal = Map[GV]; void *OldVal = CurVal; - if (CurVal && !EEState.getGlobalAddressReverseMap(locked).empty()) - EEState.getGlobalAddressReverseMap(locked).erase(CurVal); + if (CurVal && !EEState.getGlobalAddressReverseMap().empty()) + EEState.getGlobalAddressReverseMap().erase(CurVal); CurVal = Addr; // If we are using the reverse mapping, add it too. - if (!EEState.getGlobalAddressReverseMap(locked).empty()) { + if (!EEState.getGlobalAddressReverseMap().empty()) { AssertingVH &V = - EEState.getGlobalAddressReverseMap(locked)[Addr]; - assert((V == 0 || GV == 0) && "GlobalMapping already established!"); + EEState.getGlobalAddressReverseMap()[Addr]; + assert((!V || !GV) && "GlobalMapping already established!"); V = GV; } return OldVal; @@ -222,25 +235,25 @@ void *ExecutionEngine::getPointerToGlobalIfAvailable(const GlobalValue *GV) { MutexGuard locked(lock); ExecutionEngineState::GlobalAddressMapTy::iterator I = - EEState.getGlobalAddressMap(locked).find(GV); - return I != EEState.getGlobalAddressMap(locked).end() ? I->second : 0; + EEState.getGlobalAddressMap().find(GV); + return I != EEState.getGlobalAddressMap().end() ? I->second : nullptr; } const GlobalValue *ExecutionEngine::getGlobalValueAtAddress(void *Addr) { MutexGuard locked(lock); // If we haven't computed the reverse mapping yet, do so first. - if (EEState.getGlobalAddressReverseMap(locked).empty()) { + if (EEState.getGlobalAddressReverseMap().empty()) { for (ExecutionEngineState::GlobalAddressMapTy::iterator - I = EEState.getGlobalAddressMap(locked).begin(), - E = EEState.getGlobalAddressMap(locked).end(); I != E; ++I) - EEState.getGlobalAddressReverseMap(locked).insert(std::make_pair( + I = EEState.getGlobalAddressMap().begin(), + E = EEState.getGlobalAddressMap().end(); I != E; ++I) + EEState.getGlobalAddressReverseMap().insert(std::make_pair( I->second, I->first)); } std::map >::iterator I = - EEState.getGlobalAddressReverseMap(locked).find(Addr); - return I != EEState.getGlobalAddressReverseMap(locked).end() ? I->second : 0; + EEState.getGlobalAddressReverseMap().find(Addr); + return I != EEState.getGlobalAddressReverseMap().end() ? I->second : nullptr; } namespace { @@ -248,11 +261,11 @@ class ArgvArray { char *Array; std::vector Values; public: - ArgvArray() : Array(NULL) {} + ArgvArray() : Array(nullptr) {} ~ArgvArray() { clear(); } void clear() { delete[] Array; - Array = NULL; + Array = nullptr; for (size_t I = 0, E = Values.size(); I != E; ++I) { delete[] Values[I]; } @@ -288,7 +301,7 @@ void *ArgvArray::reset(LLVMContext &C, ExecutionEngine *EE, } // Null terminate it - EE->StoreValueToMemory(PTOGV(0), + EE->StoreValueToMemory(PTOGV(nullptr), (GenericValue*)(Array+InputArgv.size()*PtrSize), SBytePtr); return Array; @@ -308,11 +321,11 @@ void ExecutionEngine::runStaticConstructorsDestructors(Module *module, // Should be an array of '{ i32, void ()* }' structs. The first value is // the init priority, which we ignore. ConstantArray *InitList = dyn_cast(GV->getInitializer()); - if (InitList == 0) + if (!InitList) return; for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) { ConstantStruct *CS = dyn_cast(InitList->getOperand(i)); - if (CS == 0) continue; + if (!CS) continue; Constant *FP = CS->getOperand(1); if (FP->isNullValue()) @@ -335,8 +348,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 (Module *M : Modules) + runStaticConstructorsDestructors(M, isDtors); } #ifndef NDEBUG @@ -397,76 +410,57 @@ int ExecutionEngine::runFunctionAsMain(Function *Fn, return runFunction(Fn, GVArgs).IntVal.getZExtValue(); } -ExecutionEngine *ExecutionEngine::create(Module *M, - bool ForceInterpreter, - std::string *ErrorStr, - CodeGenOpt::Level OptLevel, - bool GVsWithCode) { - EngineBuilder EB = EngineBuilder(M) - .setEngineKind(ForceInterpreter - ? EngineKind::Interpreter - : EngineKind::JIT) - .setErrorStr(ErrorStr) - .setOptLevel(OptLevel) - .setAllocateGVsWithCode(GVsWithCode); - - return EB.create(); -} - -/// createJIT - This is the factory method for creating a JIT for the current -/// machine, it does not fall back to the interpreter. This takes ownership -/// of the module. -ExecutionEngine *ExecutionEngine::createJIT(Module *M, - std::string *ErrorStr, - JITMemoryManager *JMM, - CodeGenOpt::Level OL, - bool GVsWithCode, - Reloc::Model RM, - CodeModel::Model CMM) { - if (ExecutionEngine::JITCtor == 0) { - if (ErrorStr) - *ErrorStr = "JIT has not been linked in."; - return 0; - } - - // Use the defaults for extra parameters. Users can use EngineBuilder to - // set them. - EngineBuilder EB(M); - EB.setEngineKind(EngineKind::JIT); - EB.setErrorStr(ErrorStr); - EB.setRelocationModel(RM); - EB.setCodeModel(CMM); - EB.setAllocateGVsWithCode(GVsWithCode); - EB.setOptLevel(OL); - EB.setJITMemoryManager(JMM); - - // TODO: permit custom TargetOptions here - TargetMachine *TM = EB.selectTarget(); - if (!TM || (ErrorStr && ErrorStr->length() > 0)) return 0; - - return ExecutionEngine::JITCtor(M, ErrorStr, JMM, GVsWithCode, TM); +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; + +// IR module verification is enabled by default in debug builds, and disabled +// by default in release builds. +#ifndef NDEBUG + VerifyModules = true; +#else + VerifyModules = false; +#endif } ExecutionEngine *EngineBuilder::create(TargetMachine *TM) { - OwningPtr TheTM(TM); // Take ownership. + std::unique_ptr TheTM(TM); // Take ownership. // Make sure we can resolve symbols in the program as well. The zero arg // to the function tells DynamicLibrary to load the program, not a library. - if (sys::DynamicLibrary::LoadLibraryPermanently(0, ErrorStr)) - return 0; + 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) { + if (JMM || MCJMM) { if (WhichEngine & EngineKind::JIT) WhichEngine = EngineKind::JIT; else { if (ErrorStr) *ErrorStr = "Cannot create an interpreter with a memory manager."; - return 0; + 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. @@ -478,16 +472,17 @@ ExecutionEngine *EngineBuilder::create(TargetMachine *TM) { << " a different -march switch.\n"; } - if (UseMCJIT && ExecutionEngine::MCJITCtor) { - ExecutionEngine *EE = - ExecutionEngine::MCJITCtor(M, ErrorStr, JMM, - AllocateGVsWithCode, TheTM.take()); - if (EE) return EE; - } else if (ExecutionEngine::JITCtor) { - ExecutionEngine *EE = - ExecutionEngine::JITCtor(M, ErrorStr, JMM, - AllocateGVsWithCode, TheTM.take()); - if (EE) return EE; + 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 (EE) { + EE->setVerifyModules(VerifyModules); + return EE; } } @@ -498,16 +493,16 @@ ExecutionEngine *EngineBuilder::create(TargetMachine *TM) { return ExecutionEngine::InterpCtor(M, ErrorStr); if (ErrorStr) *ErrorStr = "Interpreter has not been linked in."; - return 0; + return nullptr; } - if ((WhichEngine & EngineKind::JIT) && ExecutionEngine::JITCtor == 0 && - ExecutionEngine::MCJITCtor == 0) { + if ((WhichEngine & EngineKind::JIT) && !ExecutionEngine::JITCtor && + !ExecutionEngine::MCJITCtor) { if (ErrorStr) *ErrorStr = "JIT has not been linked in."; } - return 0; + return nullptr; } void *ExecutionEngine::getPointerToGlobal(const GlobalValue *GV) { @@ -515,7 +510,7 @@ void *ExecutionEngine::getPointerToGlobal(const GlobalValue *GV) { return getPointerToFunction(F); MutexGuard locked(lock); - if (void *P = EEState.getGlobalAddressMap(locked)[GV]) + if (void *P = EEState.getGlobalAddressMap()[GV]) return P; // Global variable might have been added since interpreter started. @@ -525,7 +520,7 @@ void *ExecutionEngine::getPointerToGlobal(const GlobalValue *GV) { else llvm_unreachable("Global hasn't had an address allocated yet!"); - return EEState.getGlobalAddressMap(locked)[GV]; + return EEState.getGlobalAddressMap()[GV]; } /// \brief Converts a Constant* into a GenericValue, including handling of @@ -545,6 +540,24 @@ GenericValue ExecutionEngine::getConstantValue(const Constant *C) { // with the correct bit width. Result.IntVal = APInt(C->getType()->getPrimitiveSizeInBits(), 0); break; + case Type::StructTyID: { + // if the whole struct is 'undef' just reserve memory for the value. + if(StructType *STy = dyn_cast(C->getType())) { + unsigned int elemNum = STy->getNumElements(); + Result.AggregateVal.resize(elemNum); + for (unsigned int i = 0; i < elemNum; ++i) { + Type *ElemTy = STy->getElementType(i); + if (ElemTy->isIntegerTy()) + Result.AggregateVal[i].IntVal = + APInt(ElemTy->getPrimitiveSizeInBits(), 0); + else if (ElemTy->isAggregateType()) { + const Constant *ElemUndef = UndefValue::get(ElemTy); + Result.AggregateVal[i] = getConstantValue(ElemUndef); + } + } + } + } + break; case Type::VectorTyID: // if the whole vector is 'undef' just reserve memory for the value. const VectorType* VTy = dyn_cast(C->getType()); @@ -553,7 +566,7 @@ GenericValue ExecutionEngine::getConstantValue(const Constant *C) { Result.AggregateVal.resize(elemNum); if (ElemTy->isIntegerTy()) for (unsigned int i = 0; i < elemNum; ++i) - Result.AggregateVal[i].IntVal = + Result.AggregateVal[i].IntVal = APInt(ElemTy->getPrimitiveSizeInBits(), 0); break; } @@ -567,8 +580,8 @@ GenericValue ExecutionEngine::getConstantValue(const Constant *C) { case Instruction::GetElementPtr: { // Compute the index GenericValue Result = getConstantValue(Op0); - APInt Offset(TD->getPointerSizeInBits(), 0); - cast(CE)->accumulateConstantOffset(*TD, Offset); + APInt Offset(DL->getPointerSizeInBits(), 0); + cast(CE)->accumulateConstantOffset(*DL, Offset); char* tmp = (char*) Result.PointerVal; Result = PTOGV(tmp + Offset.getSExtValue()); @@ -655,16 +668,16 @@ GenericValue ExecutionEngine::getConstantValue(const Constant *C) { } case Instruction::PtrToInt: { GenericValue GV = getConstantValue(Op0); - uint32_t PtrWidth = TD->getTypeSizeInBits(Op0->getType()); + uint32_t PtrWidth = DL->getTypeSizeInBits(Op0->getType()); assert(PtrWidth <= 64 && "Bad pointer width"); GV.IntVal = APInt(PtrWidth, uintptr_t(GV.PointerVal)); - uint32_t IntWidth = TD->getTypeSizeInBits(CE->getType()); + uint32_t IntWidth = DL->getTypeSizeInBits(CE->getType()); GV.IntVal = GV.IntVal.zextOrTrunc(IntWidth); return GV; } case Instruction::IntToPtr: { GenericValue GV = getConstantValue(Op0); - uint32_t PtrWidth = TD->getTypeSizeInBits(CE->getType()); + uint32_t PtrWidth = DL->getTypeSizeInBits(CE->getType()); GV.IntVal = GV.IntVal.zextOrTrunc(PtrWidth); assert(GV.IntVal.getBitWidth() <= 64 && "Bad pointer width"); GV.PointerVal = PointerTy(uintptr_t(GV.IntVal.getZExtValue())); @@ -825,7 +838,7 @@ GenericValue ExecutionEngine::getConstantValue(const Constant *C) { break; case Type::PointerTyID: if (isa(C)) - Result.PointerVal = 0; + Result.PointerVal = nullptr; else if (const Function *F = dyn_cast(C)) Result = PTOGV(getPointerToFunctionOrStub(const_cast(F))); else if (const GlobalVariable *GV = dyn_cast(C)) @@ -1170,33 +1183,29 @@ void ExecutionEngine::emitGlobals() { if (Modules.size() != 1) { for (unsigned m = 0, e = Modules.size(); m != e; ++m) { Module &M = *Modules[m]; - for (Module::const_global_iterator I = M.global_begin(), - E = M.global_end(); I != E; ++I) { - const GlobalValue *GV = I; - if (GV->hasLocalLinkage() || GV->isDeclaration() || - GV->hasAppendingLinkage() || !GV->hasName()) + for (const auto &GV : M.globals()) { + if (GV.hasLocalLinkage() || GV.isDeclaration() || + GV.hasAppendingLinkage() || !GV.hasName()) continue;// Ignore external globals and globals with internal linkage. const GlobalValue *&GVEntry = - LinkedGlobalsMap[std::make_pair(GV->getName(), GV->getType())]; + LinkedGlobalsMap[std::make_pair(GV.getName(), GV.getType())]; // If this is the first time we've seen this global, it is the canonical // version. if (!GVEntry) { - GVEntry = GV; + GVEntry = &GV; continue; } // If the existing global is strong, never replace it. - if (GVEntry->hasExternalLinkage() || - GVEntry->hasDLLImportLinkage() || - GVEntry->hasDLLExportLinkage()) + if (GVEntry->hasExternalLinkage()) continue; // Otherwise, we know it's linkonce/weak, replace it if this is a strong // symbol. FIXME is this right for common? - if (GV->hasExternalLinkage() || GVEntry->hasExternalWeakLinkage()) - GVEntry = GV; + if (GV.hasExternalLinkage() || GVEntry->hasExternalWeakLinkage()) + GVEntry = &GV; } } } @@ -1204,31 +1213,30 @@ void ExecutionEngine::emitGlobals() { std::vector NonCanonicalGlobals; for (unsigned m = 0, e = Modules.size(); m != e; ++m) { Module &M = *Modules[m]; - for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); - I != E; ++I) { + for (const auto &GV : M.globals()) { // In the multi-module case, see what this global maps to. if (!LinkedGlobalsMap.empty()) { if (const GlobalValue *GVEntry = - LinkedGlobalsMap[std::make_pair(I->getName(), I->getType())]) { + LinkedGlobalsMap[std::make_pair(GV.getName(), GV.getType())]) { // If something else is the canonical global, ignore this one. - if (GVEntry != &*I) { - NonCanonicalGlobals.push_back(I); + if (GVEntry != &GV) { + NonCanonicalGlobals.push_back(&GV); continue; } } } - if (!I->isDeclaration()) { - addGlobalMapping(I, getMemoryForGV(I)); + if (!GV.isDeclaration()) { + addGlobalMapping(&GV, getMemoryForGV(&GV)); } else { // External variable reference. Try to use the dynamic loader to // get a pointer to it. if (void *SymAddr = - sys::DynamicLibrary::SearchForAddressOfSymbol(I->getName())) - addGlobalMapping(I, SymAddr); + sys::DynamicLibrary::SearchForAddressOfSymbol(GV.getName())) + addGlobalMapping(&GV, SymAddr); else { report_fatal_error("Could not resolve external global address: " - +I->getName()); + +GV.getName()); } } } @@ -1248,16 +1256,15 @@ void ExecutionEngine::emitGlobals() { // Now that all of the globals are set up in memory, loop through them all // and initialize their contents. - for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); - I != E; ++I) { - if (!I->isDeclaration()) { + for (const auto &GV : M.globals()) { + if (!GV.isDeclaration()) { if (!LinkedGlobalsMap.empty()) { if (const GlobalValue *GVEntry = - LinkedGlobalsMap[std::make_pair(I->getName(), I->getType())]) - if (GVEntry != &*I) // Not the canonical variable. + LinkedGlobalsMap[std::make_pair(GV.getName(), GV.getType())]) + if (GVEntry != &GV) // Not the canonical variable. continue; } - EmitGlobalVariable(I); + EmitGlobalVariable(&GV); } } } @@ -1269,9 +1276,13 @@ void ExecutionEngine::emitGlobals() { void ExecutionEngine::EmitGlobalVariable(const GlobalVariable *GV) { void *GA = getPointerToGlobalIfAvailable(GV); - if (GA == 0) { + if (!GA) { // If it's not already specified, allocate memory for the global. GA = getMemoryForGV(GV); + + // If we failed to allocate memory for this global, return. + if (!GA) return; + addGlobalMapping(GV, GA); }