diff options
author | rdivacky <rdivacky@FreeBSD.org> | 2010-01-01 10:31:22 +0000 |
---|---|---|
committer | rdivacky <rdivacky@FreeBSD.org> | 2010-01-01 10:31:22 +0000 |
commit | a16c51cee9225a354c999dd1076d5dba2aa79807 (patch) | |
tree | dba00119388b84f9f44e6ec5e9129f807fd79ca3 /lib/ExecutionEngine | |
parent | 40a6fcdb85efd93fe0e36c9552cfb0b18b5eacd6 (diff) | |
download | FreeBSD-src-a16c51cee9225a354c999dd1076d5dba2aa79807.zip FreeBSD-src-a16c51cee9225a354c999dd1076d5dba2aa79807.tar.gz |
Update LLVM to 92395.
Diffstat (limited to 'lib/ExecutionEngine')
-rw-r--r-- | lib/ExecutionEngine/JIT/JIT.cpp | 72 | ||||
-rw-r--r-- | lib/ExecutionEngine/JIT/JIT.h | 6 | ||||
-rw-r--r-- | lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp | 9 | ||||
-rw-r--r-- | lib/ExecutionEngine/JIT/JITEmitter.cpp | 81 |
4 files changed, 106 insertions, 62 deletions
diff --git a/lib/ExecutionEngine/JIT/JIT.cpp b/lib/ExecutionEngine/JIT/JIT.cpp index 26afa54..ebc2567 100644 --- a/lib/ExecutionEngine/JIT/JIT.cpp +++ b/lib/ExecutionEngine/JIT/JIT.cpp @@ -366,6 +366,32 @@ void JIT::deleteModuleProvider(ModuleProvider *MP, std::string *E) { } } +/// materializeFunction - make sure the given function is fully read. If the +/// module is corrupt, this returns true and fills in the optional string with +/// information about the problem. If successful, this returns false. +bool JIT::materializeFunction(Function *F, std::string *ErrInfo) { + // Read in the function if it exists in this Module. + if (F->hasNotBeenReadFromBitcode()) { + // Determine the module provider this function is provided by. + Module *M = F->getParent(); + ModuleProvider *MP = 0; + for (unsigned i = 0, e = Modules.size(); i != e; ++i) { + if (Modules[i]->getModule() == M) { + MP = Modules[i]; + break; + } + } + if (MP) + return MP->materializeFunction(F, ErrInfo); + + if (ErrInfo) + *ErrInfo = "Function isn't in a module we know about!"; + return true; + } + // Succeed if the function is already read. + return false; +} + /// run - Start execution with the specified function and arguments. /// GenericValue JIT::runFunction(Function *F, @@ -585,11 +611,13 @@ void JIT::runJITOnFunction(Function *F, MachineCodeInfo *MCI) { } }; MCIListener MCIL(MCI); - RegisterJITEventListener(&MCIL); + if (MCI) + RegisterJITEventListener(&MCIL); runJITOnFunctionUnlocked(F, locked); - UnregisterJITEventListener(&MCIL); + if (MCI) + UnregisterJITEventListener(&MCIL); } void JIT::runJITOnFunctionUnlocked(Function *F, const MutexGuard &locked) { @@ -607,6 +635,9 @@ void JIT::runJITOnFunctionUnlocked(Function *F, const MutexGuard &locked) { Function *PF = jitstate->getPendingFunctions(locked).back(); jitstate->getPendingFunctions(locked).pop_back(); + assert(!PF->hasAvailableExternallyLinkage() && + "Externally-defined function should not be in pending list."); + // JIT the function isAlreadyCodeGenerating = true; jitstate->getPM(locked).run(*PF); @@ -627,36 +658,19 @@ void *JIT::getPointerToFunction(Function *F) { return Addr; // Check if function already code gen'd MutexGuard locked(lock); - - // Now that this thread owns the lock, check if another thread has already - // code gen'd the function. - if (void *Addr = getPointerToGlobalIfAvailable(F)) - return Addr; - // Make sure we read in the function if it exists in this Module. - if (F->hasNotBeenReadFromBitcode()) { - // Determine the module provider this function is provided by. - Module *M = F->getParent(); - ModuleProvider *MP = 0; - for (unsigned i = 0, e = Modules.size(); i != e; ++i) { - if (Modules[i]->getModule() == M) { - MP = Modules[i]; - break; - } - } - assert(MP && "Function isn't in a module we know about!"); - - std::string ErrorMsg; - if (MP->materializeFunction(F, &ErrorMsg)) { - llvm_report_error("Error reading function '" + F->getName()+ - "' from bitcode file: " + ErrorMsg); - } - - // Now retry to get the address. - if (void *Addr = getPointerToGlobalIfAvailable(F)) - return Addr; + // Now that this thread owns the lock, make sure we read in the function if it + // exists in this Module. + std::string ErrorMsg; + if (materializeFunction(F, &ErrorMsg)) { + llvm_report_error("Error reading function '" + F->getName()+ + "' from bitcode file: " + ErrorMsg); } + // ... and check if another thread has already code gen'd the function. + if (void *Addr = getPointerToGlobalIfAvailable(F)) + return Addr; + if (F->isDeclaration() || F->hasAvailableExternallyLinkage()) { bool AbortOnFailure = !F->hasExternalWeakLinkage(); void *Addr = getPointerToNamedFunction(F->getName(), AbortOnFailure); diff --git a/lib/ExecutionEngine/JIT/JIT.h b/lib/ExecutionEngine/JIT/JIT.h index f165bd6..b6f74ff 100644 --- a/lib/ExecutionEngine/JIT/JIT.h +++ b/lib/ExecutionEngine/JIT/JIT.h @@ -104,6 +104,12 @@ public: /// the underlying module. virtual void deleteModuleProvider(ModuleProvider *P,std::string *ErrInfo = 0); + /// materializeFunction - make sure the given function is fully read. If the + /// module is corrupt, this returns true and fills in the optional string with + /// information about the problem. If successful, this returns false. + /// + bool materializeFunction(Function *F, std::string *ErrInfo = 0); + /// runFunction - Start execution with the specified function and arguments. /// virtual GenericValue runFunction(Function *F, diff --git a/lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp b/lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp index 0193486..c1051a9 100644 --- a/lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp +++ b/lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp @@ -429,13 +429,12 @@ unsigned char* JITDwarfEmitter::EmitExceptionTable(MachineFunction* MF, // Asm->EOL("Region start"); - if (!S.EndLabel) { + if (!S.EndLabel) EndLabelPtr = (intptr_t)EndFunction; - JCE->emitInt32((intptr_t)EndFunction - BeginLabelPtr); - } else { + else EndLabelPtr = JCE->getLabelAddress(S.EndLabel); - JCE->emitInt32(EndLabelPtr - BeginLabelPtr); - } + + JCE->emitInt32(EndLabelPtr - BeginLabelPtr); //Asm->EOL("Region length"); if (!S.PadLabel) { diff --git a/lib/ExecutionEngine/JIT/JITEmitter.cpp b/lib/ExecutionEngine/JIT/JITEmitter.cpp index bbac762..ef323b5 100644 --- a/lib/ExecutionEngine/JIT/JITEmitter.cpp +++ b/lib/ExecutionEngine/JIT/JITEmitter.cpp @@ -59,6 +59,12 @@ STATISTIC(NumRetries, "Number of retries with more memory"); static JIT *TheJIT = 0; +// A declaration may stop being a declaration once it's fully read from bitcode. +// This function returns true if F is fully read and is still a declaration. +static bool isNonGhostDeclaration(const Function *F) { + return F->isDeclaration() && !F->hasNotBeenReadFromBitcode(); +} + //===----------------------------------------------------------------------===// // JIT lazy compilation code. // @@ -271,6 +277,10 @@ namespace { class JITEmitter : public JITCodeEmitter { JITMemoryManager *MemMgr; + // When outputting a function stub in the context of some other function, we + // save BufferBegin/BufferEnd/CurBufferPtr here. + uint8_t *SavedBufferBegin, *SavedBufferEnd, *SavedCurBufferPtr; + // When reattempting to JIT a function after running out of space, we store // the estimated size of the function we're trying to JIT here, so we can // ask the memory manager for at least this much space. When we @@ -396,11 +406,13 @@ namespace { void initJumpTableInfo(MachineJumpTableInfo *MJTI); void emitJumpTableInfo(MachineJumpTableInfo *MJTI); - virtual void startGVStub(BufferState &BS, const GlobalValue* GV, - unsigned StubSize, unsigned Alignment = 1); - virtual void startGVStub(BufferState &BS, void *Buffer, - unsigned StubSize); - virtual void* finishGVStub(BufferState &BS); + void startGVStub(const GlobalValue* GV, + unsigned StubSize, unsigned Alignment = 1); + void startGVStub(void *Buffer, unsigned StubSize); + void finishGVStub(); + virtual void *allocIndirectGV(const GlobalValue *GV, + const uint8_t *Buffer, size_t Size, + unsigned Alignment); /// allocateSpace - Reserves space in the current block if any, or /// allocate a new one of the given size. @@ -513,7 +525,7 @@ void *JITResolver::getLazyFunctionStub(Function *F) { // If this is an external declaration, attempt to resolve the address now // to place in the stub. - if (F->isDeclaration() && !F->hasNotBeenReadFromBitcode()) { + if (isNonGhostDeclaration(F) || F->hasAvailableExternallyLinkage()) { Actual = TheJIT->getPointerToFunction(F); // If we resolved the symbol to a null address (eg. a weak external) @@ -521,13 +533,12 @@ void *JITResolver::getLazyFunctionStub(Function *F) { if (!Actual) return 0; } - MachineCodeEmitter::BufferState BS; TargetJITInfo::StubLayout SL = TheJIT->getJITInfo().getStubLayout(); - JE.startGVStub(BS, F, SL.Size, SL.Alignment); + JE.startGVStub(F, SL.Size, SL.Alignment); // Codegen a new stub, calling the lazy resolver or the actual address of the // external function, if it was resolved. Stub = TheJIT->getJITInfo().emitFunctionStub(F, Actual, JE); - JE.finishGVStub(BS); + JE.finishGVStub(); if (Actual != (void*)(intptr_t)LazyResolverFn) { // If we are getting the stub for an external function, we really want the @@ -547,7 +558,7 @@ void *JITResolver::getLazyFunctionStub(Function *F) { // exist yet, add it to the JIT's work list so that we can fill in the stub // address later. if (!Actual && !TheJIT->isCompilingLazily()) - if (!F->isDeclaration() || F->hasNotBeenReadFromBitcode()) + if (!isNonGhostDeclaration(F) && !F->hasAvailableExternallyLinkage()) TheJIT->addPendingFunction(F); return Stub; @@ -579,11 +590,10 @@ void *JITResolver::getExternalFunctionStub(void *FnAddr) { void *&Stub = ExternalFnToStubMap[FnAddr]; if (Stub) return Stub; - MachineCodeEmitter::BufferState BS; TargetJITInfo::StubLayout SL = TheJIT->getJITInfo().getStubLayout(); - JE.startGVStub(BS, 0, SL.Size, SL.Alignment); + JE.startGVStub(0, SL.Size, SL.Alignment); Stub = TheJIT->getJITInfo().emitFunctionStub(0, FnAddr, JE); - JE.finishGVStub(BS); + JE.finishGVStub(); DEBUG(errs() << "JIT: Stub emitted at [" << Stub << "] for external function at '" << FnAddr << "'\n"); @@ -753,7 +763,7 @@ void *JITEmitter::getPointerToGlobal(GlobalValue *V, void *Reference, // If this is an external function pointer, we can force the JIT to // 'compile' it, which really just adds it to the map. - if (F->isDeclaration() && !F->hasNotBeenReadFromBitcode()) + if (isNonGhostDeclaration(F) || F->hasAvailableExternallyLinkage()) return TheJIT->getPointerToFunction(F); } @@ -1215,8 +1225,9 @@ bool JITEmitter::finishFunction(MachineFunction &F) { if (DwarfExceptionHandling || JITEmitDebugInfo) { uintptr_t ActualSize = 0; - BufferState BS; - SaveStateTo(BS); + SavedBufferBegin = BufferBegin; + SavedBufferEnd = BufferEnd; + SavedCurBufferPtr = CurBufferPtr; if (MemMgr->NeedsExactSize()) { ActualSize = DE->GetDwarfTableSizeInBytes(F, *this, FnStart, FnEnd); @@ -1232,7 +1243,9 @@ bool JITEmitter::finishFunction(MachineFunction &F) { MemMgr->endExceptionTable(F.getFunction(), BufferBegin, CurBufferPtr, FrameRegister); uint8_t *EhEnd = CurBufferPtr; - RestoreStateFrom(BS); + BufferBegin = SavedBufferBegin; + BufferEnd = SavedBufferEnd; + CurBufferPtr = SavedCurBufferPtr; if (DwarfExceptionHandling) { TheJIT->RegisterTable(FrameRegister); @@ -1438,27 +1451,39 @@ void JITEmitter::emitJumpTableInfo(MachineJumpTableInfo *MJTI) { } } -void JITEmitter::startGVStub(BufferState &BS, const GlobalValue* GV, +void JITEmitter::startGVStub(const GlobalValue* GV, unsigned StubSize, unsigned Alignment) { - SaveStateTo(BS); + SavedBufferBegin = BufferBegin; + SavedBufferEnd = BufferEnd; + SavedCurBufferPtr = CurBufferPtr; BufferBegin = CurBufferPtr = MemMgr->allocateStub(GV, StubSize, Alignment); BufferEnd = BufferBegin+StubSize+1; } -void JITEmitter::startGVStub(BufferState &BS, void *Buffer, unsigned StubSize) { - SaveStateTo(BS); +void JITEmitter::startGVStub(void *Buffer, unsigned StubSize) { + SavedBufferBegin = BufferBegin; + SavedBufferEnd = BufferEnd; + SavedCurBufferPtr = CurBufferPtr; BufferBegin = CurBufferPtr = (uint8_t *)Buffer; BufferEnd = BufferBegin+StubSize+1; } -void *JITEmitter::finishGVStub(BufferState &BS) { +void JITEmitter::finishGVStub() { assert(CurBufferPtr != BufferEnd && "Stub overflowed allocated space."); NumBytes += getCurrentPCOffset(); - void *Result = BufferBegin; - RestoreStateFrom(BS); - return Result; + BufferBegin = SavedBufferBegin; + BufferEnd = SavedBufferEnd; + CurBufferPtr = SavedCurBufferPtr; +} + +void *JITEmitter::allocIndirectGV(const GlobalValue *GV, + const uint8_t *Buffer, size_t Size, + unsigned Alignment) { + uint8_t *IndGV = MemMgr->allocateStub(GV, Size, Alignment); + memcpy(IndGV, Buffer, Size); + return IndGV; } // getConstantPoolEntryAddress - Return the address of the 'ConstantNum' entry @@ -1543,14 +1568,14 @@ void JIT::updateFunctionStub(Function *F) { JITEmitter *JE = cast<JITEmitter>(getCodeEmitter()); void *Stub = JE->getJITResolver().getLazyFunctionStub(F); void *Addr = getPointerToGlobalIfAvailable(F); + assert(Addr != Stub && "Function must have non-stub address to be updated."); // Tell the target jit info to rewrite the stub at the specified address, // rather than creating a new one. - MachineCodeEmitter::BufferState BS; TargetJITInfo::StubLayout layout = getJITInfo().getStubLayout(); - JE->startGVStub(BS, Stub, layout.Size); + JE->startGVStub(Stub, layout.Size); getJITInfo().emitFunctionStub(F, Addr, *getCodeEmitter()); - JE->finishGVStub(BS); + JE->finishGVStub(); } /// freeMachineCodeForFunction - release machine code memory for given Function. |