Index: llvm/trunk/include/llvm/Bitcode/BitcodeReader.h =================================================================== --- llvm/trunk/include/llvm/Bitcode/BitcodeReader.h +++ llvm/trunk/include/llvm/Bitcode/BitcodeReader.h @@ -93,6 +93,10 @@ /// Parse the specified bitcode buffer, returning the module summary index. Expected> getSummary(); + + /// Parse the specified bitcode buffer and merge its module summary index + /// into CombinedIndex. + Error readSummary(ModuleSummaryIndex &CombinedIndex, unsigned ModuleId); }; /// Returns a list of modules in the specified bitcode buffer. @@ -141,6 +145,11 @@ Expected> getModuleSummaryIndex(MemoryBufferRef Buffer); + /// Parse the specified bitcode buffer and merge the index into CombinedIndex. + Error readModuleSummaryIndex(MemoryBufferRef Buffer, + ModuleSummaryIndex &CombinedIndex, + unsigned ModuleId); + /// Parse the module summary index out of an IR file and return the module /// summary index object if found, or an empty summary if not. If Path refers /// to an empty file and the -ignore-empty-index-file cl::opt flag is passed Index: llvm/trunk/include/llvm/IR/ModuleSummaryIndex.h =================================================================== --- llvm/trunk/include/llvm/IR/ModuleSummaryIndex.h +++ llvm/trunk/include/llvm/IR/ModuleSummaryIndex.h @@ -644,13 +644,6 @@ return It->second.second; } - /// Add the given per-module index into this module index/summary, - /// assigning it the given module ID. Each module merged in should have - /// a unique ID, necessary for consistent renaming of promoted - /// static (local) variables. - void mergeFrom(std::unique_ptr Other, - uint64_t NextModuleId); - /// Convenience method for creating a promoted global name /// for the given value name of a local, and its original module's ID. static std::string getGlobalNameForLocal(StringRef Name, ModuleHash ModHash) { Index: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp =================================================================== --- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp +++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp @@ -713,11 +713,20 @@ /// Original source file name recorded in a bitcode record. std::string SourceFileName; + /// The string identifier given to this module by the client, normally the + /// path to the bitcode file. + StringRef ModulePath; + + /// For per-module summary indexes, the unique numerical identifier given to + /// this module by the client. + unsigned ModuleId; + public: ModuleSummaryIndexBitcodeReader(BitstreamCursor Stream, StringRef Strtab, - ModuleSummaryIndex &TheIndex); + ModuleSummaryIndex &TheIndex, + StringRef ModulePath, unsigned ModuleId); - Error parseModule(StringRef ModulePath); + Error parseModule(); private: void setValueGUID(uint64_t ValueID, StringRef ValueName, @@ -730,11 +739,13 @@ std::vector makeCallList(ArrayRef Record, bool IsOldProfileFormat, bool HasProfile); - Error parseEntireSummary(StringRef ModulePath); + Error parseEntireSummary(); Error parseModuleStringTable(); std::pair getGUIDFromValueId(unsigned ValueId); + + ModulePathStringTableTy::iterator addThisModulePath(); }; } // end anonymous namespace @@ -4676,8 +4687,15 @@ } ModuleSummaryIndexBitcodeReader::ModuleSummaryIndexBitcodeReader( - BitstreamCursor Cursor, StringRef Strtab, ModuleSummaryIndex &TheIndex) - : BitcodeReaderBase(std::move(Cursor), Strtab), TheIndex(TheIndex) {} + BitstreamCursor Cursor, StringRef Strtab, ModuleSummaryIndex &TheIndex, + StringRef ModulePath, unsigned ModuleId) + : BitcodeReaderBase(std::move(Cursor), Strtab), TheIndex(TheIndex), + ModulePath(ModulePath), ModuleId(ModuleId) {} + +ModulePathStringTableTy::iterator +ModuleSummaryIndexBitcodeReader::addThisModulePath() { + return TheIndex.addModulePath(ModulePath, ModuleId); +} std::pair ModuleSummaryIndexBitcodeReader::getGUIDFromValueId(unsigned ValueId) { @@ -4787,7 +4805,7 @@ // Parse just the blocks needed for building the index out of the module. // At the end of this routine the module Index is populated with a map // from global value id to GlobalValueSummary objects. -Error ModuleSummaryIndexBitcodeReader::parseModule(StringRef ModulePath) { +Error ModuleSummaryIndexBitcodeReader::parseModule() { if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID)) return error("Invalid record"); @@ -4838,7 +4856,7 @@ SeenValueSymbolTable = true; } SeenGlobalValSummary = true; - if (Error Err = parseEntireSummary(ModulePath)) + if (Error Err = parseEntireSummary()) return Err; break; case bitc::MODULE_STRTAB_BLOCK_ID: @@ -4871,12 +4889,7 @@ case bitc::MODULE_CODE_HASH: { if (Record.size() != 5) return error("Invalid hash length " + Twine(Record.size()).str()); - if (TheIndex.modulePaths().empty()) - // We always seed the index with the module. - TheIndex.addModulePath(ModulePath, 0); - if (TheIndex.modulePaths().size() != 1) - return error("Don't expect multiple modules defined?"); - auto &Hash = TheIndex.modulePaths().begin()->second.second; + auto &Hash = addThisModulePath()->second.second; int Pos = 0; for (auto &Val : Record) { assert(!(Val >> 32) && "Unexpected high bits set"); @@ -4951,8 +4964,7 @@ // Eagerly parse the entire summary block. This populates the GlobalValueSummary // objects in the index. -Error ModuleSummaryIndexBitcodeReader::parseEntireSummary( - StringRef ModulePath) { +Error ModuleSummaryIndexBitcodeReader::parseEntireSummary() { if (Stream.EnterSubBlock(bitc::GLOBALVAL_SUMMARY_BLOCK_ID)) return error("Invalid record"); SmallVector Record; @@ -5057,7 +5069,7 @@ PendingTypeTestAssumeConstVCalls.clear(); PendingTypeCheckedLoadConstVCalls.clear(); auto GUID = getGUIDFromValueId(ValueID); - FS->setModulePath(TheIndex.addModulePath(ModulePath, 0)->first()); + FS->setModulePath(addThisModulePath()->first()); FS->setOriginalName(GUID.second); TheIndex.addGlobalValueSummary(GUID.first, std::move(FS)); break; @@ -5077,13 +5089,14 @@ // string table section in the per-module index, we create a single // module path string table entry with an empty (0) ID to take // ownership. - AS->setModulePath(TheIndex.addModulePath(ModulePath, 0)->first()); + AS->setModulePath(addThisModulePath()->first()); GlobalValue::GUID AliaseeGUID = getGUIDFromValueId(AliaseeID).first; - auto *AliaseeSummary = TheIndex.getGlobalValueSummary(AliaseeGUID); - if (!AliaseeSummary) + auto AliaseeInModule = + TheIndex.findSummaryInModule(AliaseeGUID, ModulePath); + if (!AliaseeInModule) return error("Alias expects aliasee summary to be parsed"); - AS->setAliasee(AliaseeSummary); + AS->setAliasee(AliaseeInModule); auto GUID = getGUIDFromValueId(ValueID); AS->setOriginalName(GUID.second); @@ -5098,7 +5111,7 @@ std::vector Refs = makeRefList(ArrayRef(Record).slice(2)); auto FS = llvm::make_unique(Flags, std::move(Refs)); - FS->setModulePath(TheIndex.addModulePath(ModulePath, 0)->first()); + FS->setModulePath(addThisModulePath()->first()); auto GUID = getGUIDFromValueId(ValueID); FS->setOriginalName(GUID.second); TheIndex.addGlobalValueSummary(GUID.first, std::move(FS)); @@ -5482,15 +5495,31 @@ return getModuleImpl(Context, false, ShouldLazyLoadMetadata, IsImporting); } +// Parse the specified bitcode buffer and merge the index into CombinedIndex. +Error BitcodeModule::readSummary(ModuleSummaryIndex &CombinedIndex, + unsigned ModuleId) { + BitstreamCursor Stream(Buffer); + Stream.JumpToBit(ModuleBit); + + ModuleSummaryIndexBitcodeReader R(std::move(Stream), Strtab, CombinedIndex, + ModuleIdentifier, ModuleId); + + if (Error Err = R.parseModule()) + return std::move(Err); + + return Error::success(); +} + // Parse the specified bitcode buffer, returning the function info index. Expected> BitcodeModule::getSummary() { BitstreamCursor Stream(Buffer); Stream.JumpToBit(ModuleBit); auto Index = llvm::make_unique(); - ModuleSummaryIndexBitcodeReader R(std::move(Stream), Strtab, *Index); + ModuleSummaryIndexBitcodeReader R(std::move(Stream), Strtab, *Index, + ModuleIdentifier, 0); - if (Error Err = R.parseModule(ModuleIdentifier)) + if (Error Err = R.parseModule()) return std::move(Err); return std::move(Index); @@ -5600,6 +5629,16 @@ return readIdentificationCode(*StreamOrErr); } +Error llvm::readModuleSummaryIndex(MemoryBufferRef Buffer, + ModuleSummaryIndex &CombinedIndex, + unsigned ModuleId) { + Expected BM = getSingleModule(Buffer); + if (!BM) + return BM.takeError(); + + return BM->readSummary(CombinedIndex, ModuleId); +} + Expected> llvm::getModuleSummaryIndex(MemoryBufferRef Buffer) { Expected BM = getSingleModule(Buffer); Index: llvm/trunk/lib/IR/ModuleSummaryIndex.cpp =================================================================== --- llvm/trunk/lib/IR/ModuleSummaryIndex.cpp +++ llvm/trunk/lib/IR/ModuleSummaryIndex.cpp @@ -16,42 +16,6 @@ #include "llvm/ADT/StringMap.h" using namespace llvm; -// Create the combined module index/summary from multiple -// per-module instances. -void ModuleSummaryIndex::mergeFrom(std::unique_ptr Other, - uint64_t NextModuleId) { - if (Other->modulePaths().empty()) - return; - - assert(Other->modulePaths().size() == 1 && - "Can only merge from an single-module index at that time"); - - StringRef OtherModPath = Other->modulePaths().begin()->first(); - StringRef ModPath = addModulePath(OtherModPath, NextModuleId, - Other->getModuleHash(OtherModPath)) - ->first(); - - for (auto &OtherGlobalValSummaryLists : *Other) { - GlobalValue::GUID ValueGUID = OtherGlobalValSummaryLists.first; - GlobalValueSummaryList &List = OtherGlobalValSummaryLists.second; - - // Assert that the value summary list only has one entry, since we shouldn't - // have duplicate names within a single per-module index. - assert(List.size() == 1); - std::unique_ptr Summary = std::move(List.front()); - - // Note the module path string ref was copied above and is still owned by - // the original per-module index. Reset it to the new module path - // string reference owned by the combined index. - Summary->setModulePath(ModPath); - - // Add new value summary to existing list. There may be duplicates when - // combining GlobalValueMap entries, due to COMDAT values. Any local - // values were given unique global IDs. - addGlobalValueSummary(ValueGUID, std::move(Summary)); - } -} - // Collect for the given module the list of function it defines // (GUID -> Summary). void ModuleSummaryIndex::collectDefinedFunctionsForModule( Index: llvm/trunk/lib/LTO/LTO.cpp =================================================================== --- llvm/trunk/lib/LTO/LTO.cpp +++ llvm/trunk/lib/LTO/LTO.cpp @@ -591,11 +591,9 @@ ArrayRef Syms, const SymbolResolution *&ResI, const SymbolResolution *ResE) { - Expected> SummaryOrErr = BM.getSummary(); - if (!SummaryOrErr) - return SummaryOrErr.takeError(); - ThinLTO.CombinedIndex.mergeFrom(std::move(*SummaryOrErr), - ThinLTO.ModuleMap.size()); + if (Error Err = + BM.readSummary(ThinLTO.CombinedIndex, ThinLTO.ModuleMap.size())) + return Err; for (const InputFile::Symbol &Sym : Syms) { assert(ResI != ResE); Index: llvm/trunk/lib/LTO/ThinLTOCodeGenerator.cpp =================================================================== --- llvm/trunk/lib/LTO/ThinLTOCodeGenerator.cpp +++ llvm/trunk/lib/LTO/ThinLTOCodeGenerator.cpp @@ -565,23 +565,18 @@ * "thin-link". */ std::unique_ptr ThinLTOCodeGenerator::linkCombinedIndex() { - std::unique_ptr CombinedIndex; + std::unique_ptr CombinedIndex = + llvm::make_unique(); uint64_t NextModuleId = 0; for (auto &ModuleBuffer : Modules) { - Expected> IndexOrErr = - getModuleSummaryIndex(ModuleBuffer.getMemBuffer()); - if (!IndexOrErr) { + if (Error Err = readModuleSummaryIndex(ModuleBuffer.getMemBuffer(), + *CombinedIndex, NextModuleId++)) { // FIXME diagnose logAllUnhandledErrors( - IndexOrErr.takeError(), errs(), + std::move(Err), errs(), "error: can't create module summary index for buffer: "); return nullptr; } - if (CombinedIndex) { - CombinedIndex->mergeFrom(std::move(*IndexOrErr), ++NextModuleId); - } else { - CombinedIndex = std::move(*IndexOrErr); - } } return CombinedIndex; } Index: llvm/trunk/tools/llvm-lto/llvm-lto.cpp =================================================================== --- llvm/trunk/tools/llvm-lto/llvm-lto.cpp +++ llvm/trunk/tools/llvm-lto/llvm-lto.cpp @@ -331,12 +331,9 @@ uint64_t NextModuleId = 0; for (auto &Filename : InputFilenames) { ExitOnError ExitOnErr("llvm-lto: error loading file '" + Filename + "': "); - std::unique_ptr Index = - ExitOnErr(llvm::getModuleSummaryIndexForFile(Filename)); - // Skip files without a module summary. - if (!Index) - continue; - CombinedIndex.mergeFrom(std::move(Index), ++NextModuleId); + std::unique_ptr MB = + ExitOnErr(errorOrToExpected(MemoryBuffer::getFileOrSTDIN(Filename))); + ExitOnErr(readModuleSummaryIndex(*MB, CombinedIndex, ++NextModuleId)); } std::error_code EC; assert(!OutputFilename.empty());