From b348bb81253a1105d23ab1a1771f8d2a6546aa1b Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Fri, 18 May 2007 04:02:46 +0000 Subject: [PATCH] Fix PR1434 and test/Linker/link-archive.ll, this is a regression from 1.9. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@37204 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Bitcode/Reader/BitcodeReader.cpp | 135 ++++++++++++++++----------- lib/Bitcode/Reader/BitcodeReader.h | 10 +- 2 files changed, 91 insertions(+), 54 deletions(-) diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index 3ee046b440a..7408580b23c 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -24,8 +24,15 @@ #include "llvm/Support/MemoryBuffer.h" using namespace llvm; -BitcodeReader::~BitcodeReader() { +void BitcodeReader::FreeState() { delete Buffer; + Buffer = 0; + std::vector().swap(TypeList); + ValueList.clear(); + std::vector().swap(ParamAttrs); + std::vector().swap(FunctionBBs); + std::vector().swap(FunctionsWithBodies); + DeferredFunctionInfo.clear(); } //===----------------------------------------------------------------------===// @@ -1102,53 +1109,6 @@ bool BitcodeReader::ParseBitcode() { } -bool BitcodeReader::materializeFunction(Function *F, std::string *ErrInfo) { - // If it already is material, ignore the request. - if (!F->hasNotBeenReadFromBytecode()) return false; - - DenseMap >::iterator DFII = - DeferredFunctionInfo.find(F); - assert(DFII != DeferredFunctionInfo.end() && "Deferred function not found!"); - - // Move the bit stream to the saved position of the deferred function body and - // restore the real linkage type for the function. - Stream.JumpToBit(DFII->second.first); - F->setLinkage((GlobalValue::LinkageTypes)DFII->second.second); - - if (ParseFunctionBody(F)) { - if (ErrInfo) *ErrInfo = ErrorString; - return true; - } - - return false; -} - -void BitcodeReader::dematerializeFunction(Function *F) { - // If this function isn't materialized, or if it is a proto, this is a noop. - if (F->hasNotBeenReadFromBytecode() || F->isDeclaration()) - return; - - assert(DeferredFunctionInfo.count(F) && "No info to read function later?"); - - // Just forget the function body, we can remat it later. - F->deleteBody(); - F->setLinkage(GlobalValue::GhostLinkage); -} - - -Module *BitcodeReader::materializeModule(std::string *ErrInfo) { - for (DenseMap >::iterator I = - DeferredFunctionInfo.begin(), E = DeferredFunctionInfo.end(); I != E; - ++I) { - Function *F = I->first; - if (F->hasNotBeenReadFromBytecode() && - materializeFunction(F, ErrInfo)) - return 0; - } - return TheModule; -} - - /// ParseFunctionBody - Lazily parse the specified function body block. bool BitcodeReader::ParseFunctionBody(Function *F) { if (Stream.EnterSubBlock(bitc::FUNCTION_BLOCK_ID)) @@ -1597,6 +1557,69 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { return false; } +//===----------------------------------------------------------------------===// +// ModuleProvider implementation +//===----------------------------------------------------------------------===// + + +bool BitcodeReader::materializeFunction(Function *F, std::string *ErrInfo) { + // If it already is material, ignore the request. + if (!F->hasNotBeenReadFromBytecode()) return false; + + DenseMap >::iterator DFII = + DeferredFunctionInfo.find(F); + assert(DFII != DeferredFunctionInfo.end() && "Deferred function not found!"); + + // Move the bit stream to the saved position of the deferred function body and + // restore the real linkage type for the function. + Stream.JumpToBit(DFII->second.first); + F->setLinkage((GlobalValue::LinkageTypes)DFII->second.second); + + if (ParseFunctionBody(F)) { + if (ErrInfo) *ErrInfo = ErrorString; + return true; + } + + return false; +} + +void BitcodeReader::dematerializeFunction(Function *F) { + // If this function isn't materialized, or if it is a proto, this is a noop. + if (F->hasNotBeenReadFromBytecode() || F->isDeclaration()) + return; + + assert(DeferredFunctionInfo.count(F) && "No info to read function later?"); + + // Just forget the function body, we can remat it later. + F->deleteBody(); + F->setLinkage(GlobalValue::GhostLinkage); +} + + +Module *BitcodeReader::materializeModule(std::string *ErrInfo) { + for (DenseMap >::iterator I = + DeferredFunctionInfo.begin(), E = DeferredFunctionInfo.end(); I != E; + ++I) { + Function *F = I->first; + if (F->hasNotBeenReadFromBytecode() && + materializeFunction(F, ErrInfo)) + return 0; + } + return TheModule; +} + + +/// This method is provided by the parent ModuleProvde class and overriden +/// here. It simply releases the module from its provided and frees up our +/// state. +/// @brief Release our hold on the generated module +Module *BitcodeReader::releaseModule(std::string *ErrInfo) { + // Since we're losing control of this Module, we must hand it back complete + Module *M = ModuleProvider::releaseModule(ErrInfo); + FreeState(); + return M; +} + //===----------------------------------------------------------------------===// // External interface @@ -1626,12 +1649,18 @@ Module *llvm::ParseBitcodeFile(MemoryBuffer *Buffer, std::string *ErrMsg){ R = static_cast(getBitcodeModuleProvider(Buffer, ErrMsg)); if (!R) return 0; - // Read the whole module, get a pointer to it, tell ModuleProvider not to - // delete it when its dtor is run. - Module *M = R->releaseModule(ErrMsg); - - // Don't let the BitcodeReader dtor delete 'Buffer'. + // Read in the entire module. + Module *M = R->materializeModule(ErrMsg); + + // Don't let the BitcodeReader dtor delete 'Buffer', regardless of whether + // there was an error. R->releaseMemoryBuffer(); + + // If there was no error, tell ModuleProvider not to delete it when its dtor + // is run. + if (M) + M = R->releaseModule(ErrMsg); + delete R; return M; } diff --git a/lib/Bitcode/Reader/BitcodeReader.h b/lib/Bitcode/Reader/BitcodeReader.h index 3e0f807d9d2..2f61b06c601 100644 --- a/lib/Bitcode/Reader/BitcodeReader.h +++ b/lib/Bitcode/Reader/BitcodeReader.h @@ -39,6 +39,10 @@ public: ++NumOperands; } + void clear() { + std::vector().swap(Uses); + } + Value *operator[](unsigned i) const { return getOperand(i); } Value *back() const { return Uses.back(); } @@ -111,8 +115,11 @@ public: BitcodeReader(MemoryBuffer *buffer) : Buffer(buffer), ErrorString(0) { HasReversedFunctionsWithBodies = false; } - ~BitcodeReader(); + ~BitcodeReader() { + FreeState(); + } + void FreeState(); /// releaseMemoryBuffer - This causes the reader to completely forget about /// the memory buffer it contains, which prevents the buffer from being @@ -124,6 +131,7 @@ public: virtual bool materializeFunction(Function *F, std::string *ErrInfo = 0); virtual Module *materializeModule(std::string *ErrInfo = 0); virtual void dematerializeFunction(Function *F); + virtual Module *releaseModule(std::string *ErrInfo = 0); bool Error(const char *Str) { ErrorString = Str; -- 2.34.1