Index: llvm/include/llvm/Bitcode/BitcodeReader.h =================================================================== --- llvm/include/llvm/Bitcode/BitcodeReader.h +++ llvm/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); + /// isBitcodeWrapper - Return true if the given bytes are the magic bytes /// for an LLVM IR bitcode wrapper. /// Index: llvm/include/llvm/IR/ModuleSummaryIndex.h =================================================================== --- llvm/include/llvm/IR/ModuleSummaryIndex.h +++ llvm/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) { @@ -703,13 +696,6 @@ return &I->second; } - /// Remove entries in the GlobalValueMap that have empty summaries due to the - /// eager nature of map entry creation during VST parsing. These would - /// also be suppressed during combined index generation in mergeFrom(), - /// but if there was only one module or this was the first module we might - /// not invoke mergeFrom. - void removeEmptySummaryEntries(); - /// Collect for the given module the list of function it defines /// (GUID -> Summary). void collectDefinedFunctionsForModule(StringRef ModulePath, Index: llvm/lib/Bitcode/Reader/BitcodeReader.cpp =================================================================== --- llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -706,11 +706,15 @@ /// Original source file name recorded in a bitcode record. std::string SourceFileName; + StringRef ModulePath; + 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, @@ -723,11 +727,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 @@ -4666,8 +4672,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) { @@ -4777,7 +4790,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"); @@ -4828,7 +4841,7 @@ SeenValueSymbolTable = true; } SeenGlobalValSummary = true; - if (Error Err = parseEntireSummary(ModulePath)) + if (Error Err = parseEntireSummary()) return Err; break; case bitc::MODULE_STRTAB_BLOCK_ID: @@ -4861,12 +4874,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"); @@ -4941,8 +4949,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; @@ -4985,16 +4992,6 @@ case BitstreamEntry::Error: return error("Malformed block"); case BitstreamEntry::EndBlock: - // For a per-module index, remove any entries that still have empty - // summaries. The VST parsing creates entries eagerly for all symbols, - // but not all have associated summaries (e.g. it doesn't know how to - // distinguish between VST_CODE_ENTRY for function declarations vs global - // variables with initializers that end up with a summary). Remove those - // entries now so that we don't need to rely on the combined index merger - // to clean them up (especially since that may not run for the first - // module's index if we merge into that). - if (!Combined) - TheIndex.removeEmptySummaryEntries(); return Error::success(); case BitstreamEntry::Record: // The interesting case. @@ -5058,7 +5055,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; @@ -5078,13 +5075,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); @@ -5099,7 +5097,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)); @@ -5487,14 +5485,30 @@ } // Parse the specified bitcode buffer, returning the function info index. -Expected> BitcodeModule::getSummary() { +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(); +} + +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); @@ -5604,6 +5618,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/lib/IR/ModuleSummaryIndex.cpp =================================================================== --- llvm/lib/IR/ModuleSummaryIndex.cpp +++ llvm/lib/IR/ModuleSummaryIndex.cpp @@ -16,54 +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)); - } -} - -void ModuleSummaryIndex::removeEmptySummaryEntries() { - for (auto MI = begin(), MIE = end(); MI != MIE;) { - // Only expect this to be called on a per-module index, which has a single - // entry per value entry list. - assert(MI->second.size() == 1); - if (!MI->second[0]) - MI = GlobalValueMap.erase(MI); - else - ++MI; - } -} - // Collect for the given module the list of function it defines // (GUID -> Summary). void ModuleSummaryIndex::collectDefinedFunctionsForModule( Index: llvm/lib/LTO/LTO.cpp =================================================================== --- llvm/lib/LTO/LTO.cpp +++ llvm/lib/LTO/LTO.cpp @@ -590,11 +590,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/lib/LTO/ThinLTOCodeGenerator.cpp =================================================================== --- llvm/lib/LTO/ThinLTOCodeGenerator.cpp +++ llvm/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/tools/llvm-lto/llvm-lto.cpp =================================================================== --- llvm/tools/llvm-lto/llvm-lto.cpp +++ llvm/tools/llvm-lto/llvm-lto.cpp @@ -335,12 +335,7 @@ ExitOnError ExitOnErr("llvm-lto: error loading file '" + Filename + "': "); std::unique_ptr MB = ExitOnErr(errorOrToExpected(MemoryBuffer::getFileOrSTDIN(Filename))); - std::unique_ptr Index = - ExitOnErr(getModuleSummaryIndex(*MB)); - // Skip files without a module summary. - if (!Index) - continue; - CombinedIndex.mergeFrom(std::move(Index), ++NextModuleId); + ExitOnErr(readModuleSummaryIndex(*MB, CombinedIndex, ++NextModuleId)); } std::error_code EC; assert(!OutputFilename.empty());