Index: include/llvm/Bitcode/BitcodeWriter.h =================================================================== --- include/llvm/Bitcode/BitcodeWriter.h +++ include/llvm/Bitcode/BitcodeWriter.h @@ -102,6 +102,7 @@ void writeIndex( const ModuleSummaryIndex *Index, + const TypeIdSummariesByGuidTy *TypeIdSummariesByGuid, const std::map *ModuleToSummariesForIndex); }; @@ -146,11 +147,13 @@ /// Write the specified module summary index to the given raw output stream, /// where it will be written in a new bitcode block. This is used when /// writing the combined index file for ThinLTO. When writing a subset of the - /// index for a distributed backend, provide the \p ModuleToSummariesForIndex - /// map. - void WriteIndexToFile(const ModuleSummaryIndex &Index, raw_ostream &Out, - const std::map - *ModuleToSummariesForIndex = nullptr); + /// index for a distributed backend, provide the \p TypeIdSummariesByGuid and + /// \p ModuleToSummariesForIndex maps. + void WriteIndexToFile( + const ModuleSummaryIndex &Index, raw_ostream &Out, + const TypeIdSummariesByGuidTy *TypeIdSummariesByGuid = nullptr, + const std::map *ModuleToSummariesForIndex = + nullptr); } // end namespace llvm Index: include/llvm/IR/ModuleSummaryIndex.h =================================================================== --- include/llvm/IR/ModuleSummaryIndex.h +++ include/llvm/IR/ModuleSummaryIndex.h @@ -23,6 +23,7 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/TinyPtrVector.h" #include "llvm/IR/GlobalValue.h" #include "llvm/IR/Module.h" #include "llvm/Support/Allocator.h" @@ -737,6 +738,11 @@ std::map WPDRes; }; +/// Map type to enable fast lookup of TypeIdSummary by GUID. +using TypeIdSummariesByGuidTy = DenseMap< + GlobalValue::GUID, + TinyPtrVector *>>; + /// 160 bits SHA1 using ModuleHash = std::array; Index: lib/Bitcode/Writer/BitcodeWriter.cpp =================================================================== --- lib/Bitcode/Writer/BitcodeWriter.cpp +++ lib/Bitcode/Writer/BitcodeWriter.cpp @@ -397,6 +397,11 @@ /// The combined index to write to bitcode. const ModuleSummaryIndex &Index; + /// Mapping from type identifier GUIDs to type identifier summaries. + /// Used when writing per-module indexes for efficiency when determining + /// which type id records to write based on uses in that module. + const TypeIdSummariesByGuidTy *TypeIdSummariesByGuid; + /// When writing a subset of the index for distributed backends, client /// provides a map of modules to the corresponding GUIDs/summaries to write. const std::map *ModuleToSummariesForIndex; @@ -411,13 +416,21 @@ public: /// Constructs a IndexBitcodeWriter object for the given combined index, /// writing to the provided \p Buffer. When writing a subset of the index - /// for a distributed backend, provide a \p ModuleToSummariesForIndex map. + /// for a distributed backend, provide the \p TypeIdSummariesByGuid and + /// \p ModuleToSummariesForIndex maps. IndexBitcodeWriter(BitstreamWriter &Stream, StringTableBuilder &StrtabBuilder, const ModuleSummaryIndex &Index, + const TypeIdSummariesByGuidTy *TypeIdSummariesByGuid, const std::map *ModuleToSummariesForIndex = nullptr) : BitcodeWriterBase(Stream, StrtabBuilder), Index(Index), + TypeIdSummariesByGuid(TypeIdSummariesByGuid), ModuleToSummariesForIndex(ModuleToSummariesForIndex) { + // For efficiency, we require passing in a TypeIdSummariesByGuid + // when printing per-module indexes for ThinLTO distributed backends + // (i.e. a non-null ModuleToSummariesForIndex). + assert((TypeIdSummariesByGuid || !ModuleToSummariesForIndex) && + "Require TypeIdSummariesByGuid when printing per-module indexes"); // Assign unique value ids to all summaries to be written, for use // in writing out the call graph edges. Save the mapping from GUID // to the new global value id to use when writing those edges, which @@ -3874,7 +3887,25 @@ NameVals.clear(); } - if (!Index.typeIds().empty()) { + if (TypeIdSummariesByGuid) { + // If we have a mapping from GUID to type id summary, we can + // simply walk the GUIDs that were referenced, and write the + // corresponding type id records. + for (auto &T : ReferencedTypeIds) { + auto S = TypeIdSummariesByGuid->find(T); + if (S == TypeIdSummariesByGuid->end()) + continue; + for (auto &P : S->second) { + writeTypeIdSummaryRecord(NameVals, StrtabBuilder, P->first, P->second); + Stream.EmitRecord(bitc::FS_TYPE_ID, NameVals); + NameVals.clear(); + } + } + } else { + // Don't have a mapping from GUID to type id summary, so we need + // to walk all type ids and check if each is referenced. We should + // only reach here when writing the combined index (which was + // checked in the IndexBitcodeWriter constructor). for (auto &S : Index.typeIds()) { // Skip if not referenced in any GV summary within this index file. if (!ReferencedTypeIds.count(GlobalValue::getGUID(S.first))) @@ -4161,8 +4192,10 @@ void BitcodeWriter::writeIndex( const ModuleSummaryIndex *Index, + const TypeIdSummariesByGuidTy *TypeIdSummariesByGuid, const std::map *ModuleToSummariesForIndex) { IndexBitcodeWriter IndexWriter(*Stream, StrtabBuilder, *Index, + TypeIdSummariesByGuid, ModuleToSummariesForIndex); IndexWriter.write(); } @@ -4214,12 +4247,13 @@ // index for a distributed backend, provide a \p ModuleToSummariesForIndex map. void llvm::WriteIndexToFile( const ModuleSummaryIndex &Index, raw_ostream &Out, + const TypeIdSummariesByGuidTy *TypeIdSummariesByGuid, const std::map *ModuleToSummariesForIndex) { SmallVector Buffer; Buffer.reserve(256 * 1024); BitcodeWriter Writer(Buffer); - Writer.writeIndex(&Index, ModuleToSummariesForIndex); + Writer.writeIndex(&Index, TypeIdSummariesByGuid, ModuleToSummariesForIndex); Writer.writeStrtab(); Out.write((char *)&Buffer.front(), Buffer.size()); Index: lib/LTO/LTO.cpp =================================================================== --- lib/LTO/LTO.cpp +++ lib/LTO/LTO.cpp @@ -56,12 +56,6 @@ DumpThinCGSCCs("dump-thin-cg-sccs", cl::init(false), cl::Hidden, cl::desc("Dump the SCCs in the ThinLTO index's callgraph")); -// The values are (type identifier, summary) pairs. -typedef DenseMap< - GlobalValue::GUID, - TinyPtrVector *>> - TypeIdSummariesByGuidTy; - // Returns a unique hash for the Module considering the current list of // export/import and other global analysis results. // The hash is produced in \p Key. @@ -895,12 +889,20 @@ Config &Conf; ModuleSummaryIndex &CombinedIndex; const StringMap &ModuleToDefinedGVSummaries; + TypeIdSummariesByGuidTy TypeIdSummariesByGuid; public: ThinBackendProc(Config &Conf, ModuleSummaryIndex &CombinedIndex, const StringMap &ModuleToDefinedGVSummaries) : Conf(Conf), CombinedIndex(CombinedIndex), - ModuleToDefinedGVSummaries(ModuleToDefinedGVSummaries) {} + ModuleToDefinedGVSummaries(ModuleToDefinedGVSummaries) { + // Create a mapping from type identifier GUIDs to type identifier summaries. + // This allows backends to use the type identifier GUIDs stored in the + // function summaries to determine which type identifier summaries affect + // each function without needing to compute GUIDs in each backend. + for (auto &TId : CombinedIndex.typeIds()) + TypeIdSummariesByGuid[GlobalValue::getGUID(TId.first)].push_back(&TId); + } virtual ~ThinBackendProc() {} virtual Error start( @@ -917,7 +919,6 @@ ThreadPool BackendThreadPool; AddStreamFn AddStream; NativeObjectCache Cache; - TypeIdSummariesByGuidTy TypeIdSummariesByGuid; std::set CfiFunctionDefs; std::set CfiFunctionDecls; @@ -933,12 +934,6 @@ : ThinBackendProc(Conf, CombinedIndex, ModuleToDefinedGVSummaries), BackendThreadPool(ThinLTOParallelismLevel), AddStream(std::move(AddStream)), Cache(std::move(Cache)) { - // Create a mapping from type identifier GUIDs to type identifier summaries. - // This allows backends to use the type identifier GUIDs stored in the - // function summaries to determine which type identifier summaries affect - // each function without needing to compute GUIDs in each backend. - for (auto &TId : CombinedIndex.typeIds()) - TypeIdSummariesByGuid[GlobalValue::getGUID(TId.first)].push_back(&TId); for (auto &Name : CombinedIndex.cfiFunctionDefs()) CfiFunctionDefs.insert( GlobalValue::getGUID(GlobalValue::dropLLVMManglingEscape(Name))); @@ -1102,7 +1097,8 @@ sys::fs::OpenFlags::F_None); if (EC) return errorCodeToError(EC); - WriteIndexToFile(CombinedIndex, OS, &ModuleToSummariesForIndex); + WriteIndexToFile(CombinedIndex, OS, &TypeIdSummariesByGuid, + &ModuleToSummariesForIndex); if (ShouldEmitImportsFiles) { EC = EmitImportsFiles(ModulePath, NewModulePath + ".imports", Index: tools/llvm-lto/llvm-lto.cpp =================================================================== --- tools/llvm-lto/llvm-lto.cpp +++ tools/llvm-lto/llvm-lto.cpp @@ -571,7 +571,11 @@ std::error_code EC; raw_fd_ostream OS(OutputName, EC, sys::fs::OpenFlags::F_None); error(EC, "error opening the file '" + OutputName + "'"); - WriteIndexToFile(*Index, OS, &ModuleToSummariesForIndex); + TypeIdSummariesByGuidTy TypeIdSummariesByGuid; + for (auto &TId : Index->typeIds()) + TypeIdSummariesByGuid[GlobalValue::getGUID(TId.first)].push_back(&TId); + WriteIndexToFile(*Index, OS, &TypeIdSummariesByGuid, + &ModuleToSummariesForIndex); } }