Index: cfe/trunk/lib/CodeGen/CodeGenAction.cpp =================================================================== --- cfe/trunk/lib/CodeGen/CodeGenAction.cpp +++ cfe/trunk/lib/CodeGen/CodeGenAction.cpp @@ -772,7 +772,7 @@ } ErrorOr> ModuleOrErr = - getLazyBitcodeModule(std::move(*BCBuf), *VMContext); + getOwningLazyBitcodeModule(std::move(*BCBuf), *VMContext); if (std::error_code EC = ModuleOrErr.getError()) { CI.getDiagnostics().Report(diag::err_cannot_open_file) << LinkBCFile << EC.message(); Index: llvm/trunk/include/llvm/Bitcode/ReaderWriter.h =================================================================== --- llvm/trunk/include/llvm/Bitcode/ReaderWriter.h +++ llvm/trunk/include/llvm/Bitcode/ReaderWriter.h @@ -39,13 +39,19 @@ /// Read the header of the specified bitcode buffer and prepare for lazy /// deserialization of function bodies. If ShouldLazyLoadMetadata is true, - /// lazily load metadata as well. If successful, this moves Buffer. On - /// error, this *does not* move Buffer. + /// lazily load metadata as well. ErrorOr> - getLazyBitcodeModule(std::unique_ptr &&Buffer, - LLVMContext &Context, + getLazyBitcodeModule(MemoryBufferRef Buffer, LLVMContext &Context, bool ShouldLazyLoadMetadata = false); + /// Like getLazyBitcodeModule, except that the module takes ownership of + /// the memory buffer if successful. If successful, this moves Buffer. On + /// error, this *does not* move Buffer. + ErrorOr> + getOwningLazyBitcodeModule(std::unique_ptr &&Buffer, + LLVMContext &Context, + bool ShouldLazyLoadMetadata = false); + /// Read the header of the specified bitcode buffer and extract just the /// triple information. If successful, this returns a string. On error, this /// returns "". Index: llvm/trunk/include/llvm/IR/Module.h =================================================================== --- llvm/trunk/include/llvm/IR/Module.h +++ llvm/trunk/include/llvm/IR/Module.h @@ -33,6 +33,7 @@ class FunctionType; class GVMaterializer; class LLVMContext; +class MemoryBuffer; class RandomNumberGenerator; class StructType; template class SmallPtrSetImpl; @@ -158,6 +159,9 @@ std::string GlobalScopeAsm; ///< Inline Asm at global scope. ValueSymbolTable *ValSymTab; ///< Symbol table for values ComdatSymTabType ComdatSymTab; ///< Symbol table for COMDATs + std::unique_ptr + OwnedMemoryBuffer; ///< Memory buffer directly owned by this + ///< module, for legacy clients only. std::unique_ptr Materializer; ///< Used to materialize GlobalValues std::string ModuleID; ///< Human readable identifier for the module @@ -802,6 +806,9 @@ /// \brief Returns profile summary metadata Metadata *getProfileSummary(); /// @} + + /// Take ownership of the given memory buffer. + void setOwnedMemoryBuffer(std::unique_ptr MB); }; /// \brief Given "llvm.used" or "llvm.compiler.used" as a global name, collect Index: llvm/trunk/lib/Bitcode/Reader/BitReader.cpp =================================================================== --- llvm/trunk/lib/Bitcode/Reader/BitReader.cpp +++ llvm/trunk/lib/Bitcode/Reader/BitReader.cpp @@ -101,7 +101,7 @@ std::unique_ptr Owner(unwrap(MemBuf)); ErrorOr> ModuleOrErr = - getLazyBitcodeModule(std::move(Owner), Ctx); + getOwningLazyBitcodeModule(std::move(Owner), Ctx); Owner.release(); Ctx.setDiagnosticHandler(OldDiagnosticHandler, OldDiagnosticContext, true); @@ -124,7 +124,7 @@ std::unique_ptr Owner(unwrap(MemBuf)); ErrorOr> ModuleOrErr = - getLazyBitcodeModule(std::move(Owner), Ctx); + getOwningLazyBitcodeModule(std::move(Owner), Ctx); Owner.release(); if (ModuleOrErr.getError()) { Index: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp =================================================================== --- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp +++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp @@ -230,9 +230,9 @@ class BitcodeReaderBase { protected: - BitcodeReaderBase(MemoryBuffer *Buffer) : Buffer(Buffer) {} + BitcodeReaderBase(MemoryBufferRef Buffer) : Buffer(Buffer) {} - std::unique_ptr Buffer; + MemoryBufferRef Buffer; BitstreamBlockInfo BlockInfo; BitstreamCursor Stream; @@ -244,10 +244,10 @@ }; std::error_code BitcodeReaderBase::initStream() { - const unsigned char *BufPtr = (const unsigned char*)Buffer->getBufferStart(); - const unsigned char *BufEnd = BufPtr+Buffer->getBufferSize(); + const unsigned char *BufPtr = (const unsigned char*)Buffer.getBufferStart(); + const unsigned char *BufEnd = BufPtr+Buffer.getBufferSize(); - if (Buffer->getBufferSize() & 3) + if (Buffer.getBufferSize() & 3) return error("Invalid bitcode signature"); // If we have a wrapper header, parse it and ignore the non-bc file contents. @@ -360,15 +360,10 @@ std::error_code error(BitcodeError E, const Twine &Message); std::error_code error(const Twine &Message) override; - BitcodeReader(MemoryBuffer *Buffer, LLVMContext &Context); - ~BitcodeReader() override { freeState(); } + BitcodeReader(MemoryBufferRef Buffer, LLVMContext &Context); std::error_code materializeForwardReferencedFunctions(); - void freeState(); - - void releaseBuffer(); - std::error_code materialize(GlobalValue *GV) override; std::error_code materializeModule() override; std::vector getIdentifiedStructTypes() const override; @@ -585,13 +580,8 @@ std::error_code error(const Twine &Message); ModuleSummaryIndexBitcodeReader( - MemoryBuffer *Buffer, DiagnosticHandlerFunction DiagnosticHandler, + MemoryBufferRef Buffer, DiagnosticHandlerFunction DiagnosticHandler, bool CheckGlobalValSummaryPresenceOnly = false); - ~ModuleSummaryIndexBitcodeReader() { freeState(); } - - void freeState(); - - void releaseBuffer(); /// Check if the parser has encountered a summary section. bool foundGlobalValSummary() { return SeenGlobalValSummary; } @@ -661,7 +651,7 @@ Message); } -BitcodeReader::BitcodeReader(MemoryBuffer *Buffer, LLVMContext &Context) +BitcodeReader::BitcodeReader(MemoryBufferRef Buffer, LLVMContext &Context) : BitcodeReaderBase(Buffer), Context(Context), ValueList(Context), MetadataList(Context) {} @@ -698,24 +688,6 @@ return std::error_code(); } -void BitcodeReader::freeState() { - Buffer = nullptr; - std::vector().swap(TypeList); - ValueList.clear(); - MetadataList.clear(); - std::vector().swap(ComdatList); - - std::vector().swap(MAttributes); - std::vector().swap(FunctionBBs); - std::vector().swap(FunctionsWithBodies); - DeferredFunctionInfo.clear(); - DeferredMetadataInfo.clear(); - MDKindMap.clear(); - - assert(BasicBlockFwdRefs.empty() && "Unresolved blockaddress fwd references"); - BasicBlockFwdRefQueue.clear(); -} - //===----------------------------------------------------------------------===// // Helper functions to implement forward reference resolution, etc. //===----------------------------------------------------------------------===// @@ -5887,8 +5859,6 @@ // GVMaterializer implementation //===----------------------------------------------------------------------===// -void BitcodeReader::releaseBuffer() { Buffer.release(); } - std::error_code BitcodeReader::materialize(GlobalValue *GV) { Function *F = dyn_cast(GV); // If it's not a function or is already material, ignore the request. @@ -6006,16 +5976,12 @@ } ModuleSummaryIndexBitcodeReader::ModuleSummaryIndexBitcodeReader( - MemoryBuffer *Buffer, DiagnosticHandlerFunction DiagnosticHandler, + MemoryBufferRef Buffer, DiagnosticHandlerFunction DiagnosticHandler, bool CheckGlobalValSummaryPresenceOnly) : BitcodeReaderBase(Buffer), DiagnosticHandler(std::move(DiagnosticHandler)), CheckGlobalValSummaryPresenceOnly(CheckGlobalValSummaryPresenceOnly) {} -void ModuleSummaryIndexBitcodeReader::freeState() { Buffer = nullptr; } - -void ModuleSummaryIndexBitcodeReader::releaseBuffer() { Buffer.release(); } - std::pair ModuleSummaryIndexBitcodeReader::getGUIDFromValueId(unsigned ValueId) { auto VGI = ValueIdToCallGraphGUIDMap.find(ValueId); @@ -6219,7 +6185,7 @@ break; if (TheIndex->modulePaths().empty()) // We always seed the index with the module. - TheIndex->addModulePath(Buffer->getBufferIdentifier(), 0); + TheIndex->addModulePath(Buffer.getBufferIdentifier(), 0); if (TheIndex->modulePaths().size() != 1) return error("Don't expect multiple modules defined?"); auto &Hash = TheIndex->modulePaths().begin()->second.second; @@ -6359,7 +6325,7 @@ // module path string table entry with an empty (0) ID to take // ownership. FS->setModulePath( - TheIndex->addModulePath(Buffer->getBufferIdentifier(), 0)->first()); + TheIndex->addModulePath(Buffer.getBufferIdentifier(), 0)->first()); static int RefListStartIndex = 4; int CallGraphEdgeStartIndex = RefListStartIndex + NumRefs; assert(Record.size() >= RefListStartIndex + NumRefs && @@ -6398,7 +6364,7 @@ // module path string table entry with an empty (0) ID to take // ownership. AS->setModulePath( - TheIndex->addModulePath(Buffer->getBufferIdentifier(), 0)->first()); + TheIndex->addModulePath(Buffer.getBufferIdentifier(), 0)->first()); GlobalValue::GUID AliaseeGUID = getGUIDFromValueId(AliaseeID).first; auto *AliaseeSummary = TheIndex->getGlobalValueSummary(AliaseeGUID); @@ -6419,7 +6385,7 @@ std::unique_ptr FS = llvm::make_unique(Flags); FS->setModulePath( - TheIndex->addModulePath(Buffer->getBufferIdentifier(), 0)->first()); + TheIndex->addModulePath(Buffer.getBufferIdentifier(), 0)->first()); for (unsigned I = 2, E = Record.size(); I != E; ++I) { unsigned RefValueId = Record[I]; GlobalValue::GUID RefGUID = getGUIDFromValueId(RefValueId).first; @@ -6677,77 +6643,68 @@ // External interface //===----------------------------------------------------------------------===// +/// \brief Get a lazy one-at-time loading module from bitcode. +/// +/// This isn't always used in a lazy context. In particular, it's also used by +/// \a parseBitcodeFile(). If this is truly lazy, then we need to eagerly pull +/// in forward-referenced functions from block address references. +/// +/// \param[in] MaterializeAll Set to \c true if we should materialize +/// everything. static ErrorOr> -getBitcodeModuleImpl(StringRef Name, BitcodeReader *R, LLVMContext &Context, - bool MaterializeAll, bool ShouldLazyLoadMetadata) { - std::unique_ptr M = llvm::make_unique(Name, Context); - M->setMaterializer(R); +getLazyBitcodeModuleImpl(MemoryBufferRef Buffer, LLVMContext &Context, + bool MaterializeAll, + bool ShouldLazyLoadMetadata = false) { + BitcodeReader *R = new BitcodeReader(Buffer, Context); - auto cleanupOnError = [&](std::error_code EC) { - R->releaseBuffer(); // Never take ownership on error. - return EC; - }; + std::unique_ptr M = + llvm::make_unique(Buffer.getBufferIdentifier(), Context); + M->setMaterializer(R); // Delay parsing Metadata if ShouldLazyLoadMetadata is true. if (std::error_code EC = R->parseBitcodeInto(M.get(), ShouldLazyLoadMetadata)) - return cleanupOnError(EC); + return EC; if (MaterializeAll) { // Read in the entire module, and destroy the BitcodeReader. if (std::error_code EC = M->materializeAll()) - return cleanupOnError(EC); + return EC; } else { // Resolve forward references from blockaddresses. if (std::error_code EC = R->materializeForwardReferencedFunctions()) - return cleanupOnError(EC); + return EC; } return std::move(M); } -/// \brief Get a lazy one-at-time loading module from bitcode. -/// -/// This isn't always used in a lazy context. In particular, it's also used by -/// \a parseBitcodeFile(). If this is truly lazy, then we need to eagerly pull -/// in forward-referenced functions from block address references. -/// -/// \param[in] MaterializeAll Set to \c true if we should materialize -/// everything. -static ErrorOr> -getLazyBitcodeModuleImpl(std::unique_ptr &&Buffer, - LLVMContext &Context, bool MaterializeAll, - bool ShouldLazyLoadMetadata = false) { - BitcodeReader *R = new BitcodeReader(Buffer.get(), Context); - - ErrorOr> Ret = - getBitcodeModuleImpl(Buffer->getBufferIdentifier(), R, Context, - MaterializeAll, ShouldLazyLoadMetadata); - if (!Ret) - return Ret; - - Buffer.release(); // The BitcodeReader owns it now. - return Ret; -} - ErrorOr> -llvm::getLazyBitcodeModule(std::unique_ptr &&Buffer, +llvm::getLazyBitcodeModule(MemoryBufferRef Buffer, LLVMContext &Context, bool ShouldLazyLoadMetadata) { - return getLazyBitcodeModuleImpl(std::move(Buffer), Context, false, + return getLazyBitcodeModuleImpl(Buffer, Context, false, ShouldLazyLoadMetadata); } +ErrorOr> +llvm::getOwningLazyBitcodeModule(std::unique_ptr &&Buffer, + LLVMContext &Context, + bool ShouldLazyLoadMetadata) { + auto MOrErr = getLazyBitcodeModule(*Buffer, Context, ShouldLazyLoadMetadata); + if (MOrErr) + (*MOrErr)->setOwnedMemoryBuffer(std::move(Buffer)); + return MOrErr; +} + ErrorOr> llvm::parseBitcodeFile(MemoryBufferRef Buffer, LLVMContext &Context) { - std::unique_ptr Buf = MemoryBuffer::getMemBuffer(Buffer, false); - return getLazyBitcodeModuleImpl(std::move(Buf), Context, true); + return getLazyBitcodeModuleImpl(Buffer, Context, true); // TODO: Restore the use-lists to the in-memory state when the bitcode was // written. We must defer until the Module has been fully materialized. } std::string llvm::getBitcodeTargetTriple(MemoryBufferRef Buffer, LLVMContext &Context) { - std::unique_ptr Buf = MemoryBuffer::getMemBuffer(Buffer, false); - auto R = llvm::make_unique(Buf.release(), Context); - ErrorOr Triple = R->parseTriple(); + BitcodeReader R(Buffer, Context); + ErrorOr Triple = R.parseTriple(); if (Triple.getError()) return ""; return Triple.get(); @@ -6755,9 +6712,8 @@ bool llvm::isBitcodeContainingObjCCategory(MemoryBufferRef Buffer, LLVMContext &Context) { - std::unique_ptr Buf = MemoryBuffer::getMemBuffer(Buffer, false); - auto R = llvm::make_unique(Buf.release(), Context); - ErrorOr hasObjCCategory = R->hasObjCCategory(); + BitcodeReader R(Buffer, Context); + ErrorOr hasObjCCategory = R.hasObjCCategory(); if (hasObjCCategory.getError()) return false; return hasObjCCategory.get(); @@ -6765,8 +6721,7 @@ std::string llvm::getBitcodeProducerString(MemoryBufferRef Buffer, LLVMContext &Context) { - std::unique_ptr Buf = MemoryBuffer::getMemBuffer(Buffer, false); - BitcodeReader R(Buf.release(), Context); + BitcodeReader R(Buffer, Context); ErrorOr ProducerString = R.parseIdentificationBlock(); if (ProducerString.getError()) return ""; @@ -6777,20 +6732,13 @@ ErrorOr> llvm::getModuleSummaryIndex( MemoryBufferRef Buffer, const DiagnosticHandlerFunction &DiagnosticHandler) { - std::unique_ptr Buf = MemoryBuffer::getMemBuffer(Buffer, false); - ModuleSummaryIndexBitcodeReader R(Buf.get(), DiagnosticHandler); + ModuleSummaryIndexBitcodeReader R(Buffer, DiagnosticHandler); auto Index = llvm::make_unique(); - auto cleanupOnError = [&](std::error_code EC) { - R.releaseBuffer(); // Never take ownership on error. - return EC; - }; - if (std::error_code EC = R.parseSummaryIndexInto(Index.get())) - return cleanupOnError(EC); + return EC; - Buf.release(); // The ModuleSummaryIndexBitcodeReader owns it now. return std::move(Index); } @@ -6798,17 +6746,10 @@ bool llvm::hasGlobalValueSummary( MemoryBufferRef Buffer, const DiagnosticHandlerFunction &DiagnosticHandler) { - std::unique_ptr Buf = MemoryBuffer::getMemBuffer(Buffer, false); - ModuleSummaryIndexBitcodeReader R(Buf.get(), DiagnosticHandler, true); + ModuleSummaryIndexBitcodeReader R(Buffer, DiagnosticHandler, true); - auto cleanupOnError = [&](std::error_code EC) { - R.releaseBuffer(); // Never take ownership on error. + if (R.parseSummaryIndexInto(nullptr)) return false; - }; - - if (std::error_code EC = R.parseSummaryIndexInto(nullptr)) - return cleanupOnError(EC); - Buf.release(); // The ModuleSummaryIndexBitcodeReader owns it now. return R.foundGlobalValSummary(); } Index: llvm/trunk/lib/IR/Module.cpp =================================================================== --- llvm/trunk/lib/IR/Module.cpp +++ llvm/trunk/lib/IR/Module.cpp @@ -25,6 +25,7 @@ #include "llvm/IR/LLVMContext.h" #include "llvm/IR/TypeFinder.h" #include "llvm/Support/Dwarf.h" +#include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" #include "llvm/Support/RandomNumberGenerator.h" #include @@ -519,6 +520,10 @@ return getModuleFlag("ProfileSummary"); } +void Module::setOwnedMemoryBuffer(std::unique_ptr MB) { + OwnedMemoryBuffer = std::move(MB); +} + GlobalVariable *llvm::collectUsedGlobalVariables( const Module &M, SmallPtrSetImpl &Set, bool CompilerUsed) { const char *Name = CompilerUsed ? "llvm.compiler.used" : "llvm.used"; Index: llvm/trunk/lib/IRReader/IRReader.cpp =================================================================== --- llvm/trunk/lib/IRReader/IRReader.cpp +++ llvm/trunk/lib/IRReader/IRReader.cpp @@ -34,7 +34,7 @@ LLVMContext &Context, bool ShouldLazyLoadMetadata) { if (isBitcode((const unsigned char *)Buffer->getBufferStart(), (const unsigned char *)Buffer->getBufferEnd())) { - ErrorOr> ModuleOrErr = getLazyBitcodeModule( + ErrorOr> ModuleOrErr = getOwningLazyBitcodeModule( std::move(Buffer), Context, ShouldLazyLoadMetadata); if (std::error_code EC = ModuleOrErr.getError()) { Err = SMDiagnostic(Buffer->getBufferIdentifier(), SourceMgr::DK_Error, Index: llvm/trunk/lib/LTO/LTO.cpp =================================================================== --- llvm/trunk/lib/LTO/LTO.cpp +++ llvm/trunk/lib/LTO/LTO.cpp @@ -105,9 +105,8 @@ SMDiagnostic Err; ErrorOr> ModuleOrErr(nullptr); if (Lazy) { - ModuleOrErr = - getLazyBitcodeModule(MemoryBuffer::getMemBuffer(Buffer, false), Context, - /* ShouldLazyLoadMetadata */ Lazy); + ModuleOrErr = getLazyBitcodeModule(Buffer, Context, + /* ShouldLazyLoadMetadata */ Lazy); } else { ModuleOrErr = parseBitcodeFile(Buffer, Context); } Index: llvm/trunk/lib/LTO/LTOBackend.cpp =================================================================== --- llvm/trunk/lib/LTO/LTOBackend.cpp +++ llvm/trunk/lib/LTO/LTOBackend.cpp @@ -352,8 +352,7 @@ auto ModuleLoader = [&](StringRef Identifier) { assert(Mod.getContext().isODRUniquingDebugTypes() && "ODR Type uniquing should be enabled on the context"); - return std::move(getLazyBitcodeModule(MemoryBuffer::getMemBuffer( - ModuleMap[Identifier], false), + return std::move(getLazyBitcodeModule(ModuleMap[Identifier], Mod.getContext(), /*ShouldLazyLoadMetadata=*/true) .get()); Index: llvm/trunk/lib/LTO/LTOModule.cpp =================================================================== --- llvm/trunk/lib/LTO/LTOModule.cpp +++ llvm/trunk/lib/LTO/LTOModule.cpp @@ -185,10 +185,8 @@ } // Parse lazily. - std::unique_ptr LightweightBuf = - MemoryBuffer::getMemBuffer(*MBOrErr, false); - ErrorOr> M = getLazyBitcodeModule( - std::move(LightweightBuf), Context, true /*ShouldLazyLoadMetadata*/); + ErrorOr> M = + getLazyBitcodeModule(*MBOrErr, Context, true /*ShouldLazyLoadMetadata*/); if (std::error_code EC = M.getError()) return EC; return std::move(*M); Index: llvm/trunk/lib/Object/IRObjectFile.cpp =================================================================== --- llvm/trunk/lib/Object/IRObjectFile.cpp +++ llvm/trunk/lib/Object/IRObjectFile.cpp @@ -317,11 +317,8 @@ if (!BCOrErr) return BCOrErr.getError(); - std::unique_ptr Buff = - MemoryBuffer::getMemBuffer(BCOrErr.get(), false); - ErrorOr> MOrErr = - getLazyBitcodeModule(std::move(Buff), Context, + getLazyBitcodeModule(*BCOrErr, Context, /*ShouldLazyLoadMetadata*/ true); if (std::error_code EC = MOrErr.getError()) return EC; Index: llvm/trunk/tools/llvm-dis/llvm-dis.cpp =================================================================== --- llvm/trunk/tools/llvm-dis/llvm-dis.cpp +++ llvm/trunk/tools/llvm-dis/llvm-dis.cpp @@ -143,8 +143,8 @@ if (!MBOrErr) return errorCodeToError(MBOrErr.getError()); ErrorOr> MOrErr = - getLazyBitcodeModule(std::move(*MBOrErr), Context, - /*ShouldLazyLoadMetadata=*/true); + getOwningLazyBitcodeModule(std::move(*MBOrErr), Context, + /*ShouldLazyLoadMetadata=*/true); if (!MOrErr) return errorCodeToError(MOrErr.getError()); if (MaterializeMetadata) Index: llvm/trunk/unittests/Bitcode/BitReaderTest.cpp =================================================================== --- llvm/trunk/unittests/Bitcode/BitReaderTest.cpp +++ llvm/trunk/unittests/Bitcode/BitReaderTest.cpp @@ -53,10 +53,8 @@ SmallString<1024> &Mem, const char *Assembly) { writeModuleToBuffer(parseAssembly(Context, Assembly), Mem); - std::unique_ptr Buffer = - MemoryBuffer::getMemBuffer(Mem.str(), "test", false); ErrorOr> ModuleOrErr = - getLazyBitcodeModule(std::move(Buffer), Context); + getLazyBitcodeModule(MemoryBufferRef(Mem.str(), "test"), Context); return std::move(ModuleOrErr.get()); }