From 9896d761e84947e4042c00cf5a49169e660ac840 Mon Sep 17 00:00:00 2001 From: Hiroshi Yamauchi Date: Thu, 21 May 2020 13:28:24 -0700 Subject: [PATCH] [ThinLTO] Compute the basic block count across modules. Summary: Count the per-module number of basic blocks when the module summary is computed and sum them up during Thin LTO indexing. This is used to estimate the working set size under the partial sample PGO. This is split off of D79831. Reviewers: davidxl, espindola Subscribers: emaste, inglorion, hiraditya, MaskRay, steven_wu, dexonsmith, arphaman, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D80403 --- include/llvm/Bitcode/LLVMBitCodes.h | 2 ++ include/llvm/IR/ModuleSummaryIndex.h | 12 ++++++++++-- lib/Analysis/ModuleSummaryAnalysis.cpp | 1 + lib/AsmParser/LLLexer.cpp | 1 + lib/AsmParser/LLParser.cpp | 18 ++++++++++++++++++ lib/AsmParser/LLParser.h | 1 + lib/AsmParser/LLToken.h | 1 + lib/Bitcode/Reader/BitcodeAnalyzer.cpp | 1 + lib/Bitcode/Reader/BitcodeReader.cpp | 3 +++ lib/Bitcode/Writer/BitcodeWriter.cpp | 6 ++++++ lib/IR/AsmWriter.cpp | 7 ++++++- test/Assembler/thinlto-vtable-summary.ll | 1 + test/Bitcode/thinlto-alias.ll | 4 ++++ test/Bitcode/thinlto-alias2.ll | 1 + .../thinlto-function-summary-callgraph-cast.ll | 1 + .../thinlto-function-summary-callgraph-pgo.ll | 2 ++ ...nction-summary-callgraph-profile-summary.ll | 6 ++++-- ...thinlto-function-summary-callgraph-relbf.ll | 1 + ...summary-callgraph-sample-profile-summary.ll | 6 ++++-- .../thinlto-function-summary-callgraph.ll | 2 ++ .../thinlto-function-summary-originalnames.ll | 1 + test/Bitcode/thinlto-function-summary.ll | 1 + test/ThinLTO/X86/distributed_indexes.ll | 2 ++ test/tools/llvm-lto/thinlto.ll | 1 + 24 files changed, 75 insertions(+), 7 deletions(-) diff --git a/include/llvm/Bitcode/LLVMBitCodes.h b/include/llvm/Bitcode/LLVMBitCodes.h index e0093a12a7f..4de7a152fa6 100644 --- a/include/llvm/Bitcode/LLVMBitCodes.h +++ b/include/llvm/Bitcode/LLVMBitCodes.h @@ -290,6 +290,8 @@ enum GlobalValueSummarySymtabCodes { // numrefs, numrefs x valueid, // n x (valueid, offset)] FS_PERMODULE_VTABLE_GLOBALVAR_INIT_REFS = 23, + // The total number of basic blocks in the module. + FS_BLOCK_COUNT = 24, }; enum MetadataCodes { diff --git a/include/llvm/IR/ModuleSummaryIndex.h b/include/llvm/IR/ModuleSummaryIndex.h index 8259df10117..7a7ca7f76ae 100644 --- a/include/llvm/IR/ModuleSummaryIndex.h +++ b/include/llvm/IR/ModuleSummaryIndex.h @@ -1007,6 +1007,10 @@ private: StringSaver Saver; BumpPtrAllocator Alloc; + // The total number of basic blocks in the module in the per-module summary or + // the total number of basic blocks in the LTO unit in the combined index. + uint64_t BlockCount; + // YAML I/O support. friend yaml::MappingTraits; @@ -1019,8 +1023,8 @@ private: public: // See HaveGVs variable comment. ModuleSummaryIndex(bool HaveGVs, bool EnableSplitLTOUnit = false) - : HaveGVs(HaveGVs), EnableSplitLTOUnit(EnableSplitLTOUnit), Saver(Alloc) { - } + : HaveGVs(HaveGVs), EnableSplitLTOUnit(EnableSplitLTOUnit), Saver(Alloc), + BlockCount(0) {} // Current version for the module summary in bitcode files. // The BitcodeSummaryVersion should be bumped whenever we introduce changes @@ -1039,6 +1043,10 @@ public: uint64_t getFlags() const; void setFlags(uint64_t Flags); + uint64_t getBlockCount() const { return BlockCount; } + void addBlockCount(uint64_t C) { BlockCount += C; } + void setBlockCount(uint64_t C) { BlockCount = C; } + gvsummary_iterator begin() { return GlobalValueMap.begin(); } const_gvsummary_iterator begin() const { return GlobalValueMap.begin(); } gvsummary_iterator end() { return GlobalValueMap.end(); } diff --git a/lib/Analysis/ModuleSummaryAnalysis.cpp b/lib/Analysis/ModuleSummaryAnalysis.cpp index b900a38fdc0..c5e5e32b6d6 100644 --- a/lib/Analysis/ModuleSummaryAnalysis.cpp +++ b/lib/Analysis/ModuleSummaryAnalysis.cpp @@ -390,6 +390,7 @@ static void computeFunctionSummary(ModuleSummaryIndex &Index, const Module &M, .updateHotness(getHotness(Candidate.Count, PSI)); } } + Index.addBlockCount(F.size()); std::vector Refs; if (IsThinLTO) { diff --git a/lib/AsmParser/LLLexer.cpp b/lib/AsmParser/LLLexer.cpp index 71cf22ca475..eb1209ad9c6 100644 --- a/lib/AsmParser/LLLexer.cpp +++ b/lib/AsmParser/LLLexer.cpp @@ -741,6 +741,7 @@ lltok::Kind LLLexer::LexIdentifier() { KEYWORD(name); KEYWORD(summaries); KEYWORD(flags); + KEYWORD(blockcount); KEYWORD(linkage); KEYWORD(notEligibleToImport); KEYWORD(live); diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index a2c1b3f632a..fb6e61ffce4 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -853,6 +853,9 @@ bool LLParser::ParseSummaryEntry() { case lltok::kw_flags: result = ParseSummaryIndexFlags(); break; + case lltok::kw_blockcount: + result = ParseBlockCount(); + break; default: result = Error(Lex.getLoc(), "unexpected summary kind"); break; @@ -8111,6 +8114,21 @@ bool LLParser::ParseSummaryIndexFlags() { return false; } +/// ParseBlockCount +/// ::= 'blockcount' ':' UInt64 +bool LLParser::ParseBlockCount() { + assert(Lex.getKind() == lltok::kw_blockcount); + Lex.Lex(); + + if (ParseToken(lltok::colon, "expected ':' here")) + return true; + uint64_t BlockCount; + if (ParseUInt64(BlockCount)) + return true; + Index->setBlockCount(BlockCount); + return false; +} + /// ParseGVEntry /// ::= 'gv' ':' '(' ('name' ':' STRINGCONSTANT | 'guid' ':' UInt64) /// [',' 'summaries' ':' Summary[',' Summary]* ]? ')' diff --git a/lib/AsmParser/LLParser.h b/lib/AsmParser/LLParser.h index 894e23b6840..be23ba43637 100644 --- a/lib/AsmParser/LLParser.h +++ b/lib/AsmParser/LLParser.h @@ -341,6 +341,7 @@ namespace llvm { bool ParseModuleReference(StringRef &ModulePath); bool ParseGVReference(ValueInfo &VI, unsigned &GVId); bool ParseSummaryIndexFlags(); + bool ParseBlockCount(); bool ParseGVEntry(unsigned ID); bool ParseFunctionSummary(std::string Name, GlobalValue::GUID, unsigned ID); bool ParseVariableSummary(std::string Name, GlobalValue::GUID, unsigned ID); diff --git a/lib/AsmParser/LLToken.h b/lib/AsmParser/LLToken.h index 201ba04025a..a8b4ad963f0 100644 --- a/lib/AsmParser/LLToken.h +++ b/lib/AsmParser/LLToken.h @@ -374,6 +374,7 @@ enum Kind { kw_name, kw_summaries, kw_flags, + kw_blockcount, kw_linkage, kw_notEligibleToImport, kw_live, diff --git a/lib/Bitcode/Reader/BitcodeAnalyzer.cpp b/lib/Bitcode/Reader/BitcodeAnalyzer.cpp index 69ab822a74b..a72a33a1911 100644 --- a/lib/Bitcode/Reader/BitcodeAnalyzer.cpp +++ b/lib/Bitcode/Reader/BitcodeAnalyzer.cpp @@ -305,6 +305,7 @@ static Optional GetCodeName(unsigned CodeID, unsigned BlockID, STRINGIFY_CODE(FS, CFI_FUNCTION_DECLS) STRINGIFY_CODE(FS, TYPE_ID) STRINGIFY_CODE(FS, TYPE_ID_METADATA) + STRINGIFY_CODE(FS, BLOCK_COUNT) } case bitc::METADATA_ATTACHMENT_ID: switch (CodeID) { diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index 4bad2b55bf9..615b6465e98 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -6239,6 +6239,9 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) { case bitc::FS_TYPE_ID_METADATA: parseTypeIdCompatibleVtableSummaryRecord(Record); break; + + case bitc::FS_BLOCK_COUNT: + TheIndex.addBlockCount(Record[0]); } } llvm_unreachable("Exit infinite loop"); diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp index a46339a4ec1..992cdfc851f 100644 --- a/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -3906,6 +3906,9 @@ void ModuleBitcodeWriterBase::writePerModuleGlobalValueSummary() { NameVals.clear(); } + Stream.EmitRecord(bitc::FS_BLOCK_COUNT, + ArrayRef{Index->getBlockCount()}); + Stream.ExitBlock(); } @@ -4189,6 +4192,9 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() { } } + Stream.EmitRecord(bitc::FS_BLOCK_COUNT, + ArrayRef{Index.getBlockCount()}); + Stream.ExitBlock(); } diff --git a/lib/IR/AsmWriter.cpp b/lib/IR/AsmWriter.cpp index 68edb6bad93..0fc7d66d9fa 100644 --- a/lib/IR/AsmWriter.cpp +++ b/lib/IR/AsmWriter.cpp @@ -2822,8 +2822,13 @@ void AssemblyWriter::printModuleSummaryIndex() { } // Don't emit flags when it's not really needed (value is zero by default). - if (TheIndex->getFlags()) + if (TheIndex->getFlags()) { Out << "^" << NumSlots << " = flags: " << TheIndex->getFlags() << "\n"; + ++NumSlots; + } + + Out << "^" << NumSlots << " = blockcount: " << TheIndex->getBlockCount() + << "\n"; } static const char * diff --git a/test/Assembler/thinlto-vtable-summary.ll b/test/Assembler/thinlto-vtable-summary.ll index 67e7a2f1c93..fff1ce7931b 100644 --- a/test/Assembler/thinlto-vtable-summary.ll +++ b/test/Assembler/thinlto-vtable-summary.ll @@ -36,3 +36,4 @@ declare i32 @_ZN1C1fEi(%struct.C*, i32) ^6 = typeidCompatibleVTable: (name: "_ZTS1A", summary: ((offset: 16, ^2), (offset: 16, ^4))) ; guid = 7004155349499253778 ^7 = typeidCompatibleVTable: (name: "_ZTS1B", summary: ((offset: 16, ^2))) ; guid = 6203814149063363976 ^8 = typeidCompatibleVTable: (name: "_ZTS1C", summary: ((offset: 16, ^4))) ; guid = 1884921850105019584 +^9 = blockcount: 0 diff --git a/test/Bitcode/thinlto-alias.ll b/test/Bitcode/thinlto-alias.ll index a1412f5269e..7e8213ec0ca 100644 --- a/test/Bitcode/thinlto-alias.ll +++ b/test/Bitcode/thinlto-alias.ll @@ -22,6 +22,7 @@ ; See if the call to func is registered. ; The value id 1 matches the second FUNCTION record above. ; CHECK-NEXT: +; CHECK-NEXT: ; CHECK-NEXT: ; CHECK: ; COMBINED-NEXT: ; COMBINED-NEXT: ; CHECK-NEXT: +; CHECK-NEXT: ; CHECK-NEXT: ; ModuleID = 'thinlto-alias2.ll' diff --git a/test/Bitcode/thinlto-function-summary-callgraph-cast.ll b/test/Bitcode/thinlto-function-summary-callgraph-cast.ll index e6fc9392745..a0cd958eeaa 100644 --- a/test/Bitcode/thinlto-function-summary-callgraph-cast.ll +++ b/test/Bitcode/thinlto-function-summary-callgraph-cast.ll @@ -12,6 +12,7 @@ ; CHECK-NEXT: ; CHECK-NEXT: +; CHECK-NEXT: ; CHECK-NEXT: ; ModuleID = 'thinlto-function-summary-callgraph-cast.ll' diff --git a/test/Bitcode/thinlto-function-summary-callgraph-pgo.ll b/test/Bitcode/thinlto-function-summary-callgraph-pgo.ll index 2bbab0c6bb0..c353b0a8b83 100644 --- a/test/Bitcode/thinlto-function-summary-callgraph-pgo.ll +++ b/test/Bitcode/thinlto-function-summary-callgraph-pgo.ll @@ -19,6 +19,7 @@ ; CHECK-NEXT: +; CHECK-NEXT: ; CHECK-NEXT: ; CHECK: +; COMBINED-NEXT: ; COMBINED-NEXT: ; ModuleID = 'thinlto-function-summary-callgraph.ll' diff --git a/test/Bitcode/thinlto-function-summary-callgraph-profile-summary.ll b/test/Bitcode/thinlto-function-summary-callgraph-profile-summary.ll index d444ee7c01f..e13e42d8a56 100644 --- a/test/Bitcode/thinlto-function-summary-callgraph-profile-summary.ll +++ b/test/Bitcode/thinlto-function-summary-callgraph-profile-summary.ll @@ -50,6 +50,7 @@ ; CHECK-NEXT: ; op4=hot1 op6=cold op8=hot2 op10=hot4 op12=none1 op14=hot3 op16=none2 op18=none3 op20=123 ; CHECK-NEXT: +; CHECK-NEXT: ; CHECK-NEXT: ; CHECK: -; COMBINED_NEXT: +; COMBINED-NEXT: +; COMBINED-NEXT: ; ModuleID = 'thinlto-function-summary-callgraph.ll' diff --git a/test/Bitcode/thinlto-function-summary-callgraph-relbf.ll b/test/Bitcode/thinlto-function-summary-callgraph-relbf.ll index 7d13ae43b50..94d409b1b81 100644 --- a/test/Bitcode/thinlto-function-summary-callgraph-relbf.ll +++ b/test/Bitcode/thinlto-function-summary-callgraph-relbf.ll @@ -15,6 +15,7 @@ ; CHECK-NEXT: ; CHECK-NEXT: ; CHECK: ; op4=none1 op6=hot1 op8=cold1 op10=none2 op12=hot2 op14=cold2 op16=none3 op18=hot3 op20=cold3 op22=123 ; CHECK-NEXT: +; CHECK-NEXT: ; CHECK-NEXT: ; CHECK: -; COMBINED_NEXT: +; COMBINED-NEXT: +; COMBINED-NEXT: ; ModuleID = 'thinlto-function-summary-callgraph.ll' diff --git a/test/Bitcode/thinlto-function-summary-callgraph.ll b/test/Bitcode/thinlto-function-summary-callgraph.ll index 765efcf7b82..19cfbf7931a 100644 --- a/test/Bitcode/thinlto-function-summary-callgraph.ll +++ b/test/Bitcode/thinlto-function-summary-callgraph.ll @@ -20,6 +20,7 @@ ; CHECK-NEXT: ; CHECK-NEXT: ; CHECK: +; COMBINED-NEXT: ; COMBINED-NEXT: ; ModuleID = 'thinlto-function-summary-callgraph.ll' diff --git a/test/Bitcode/thinlto-function-summary-originalnames.ll b/test/Bitcode/thinlto-function-summary-originalnames.ll index 4d840d1f8ec..208ded58d68 100644 --- a/test/Bitcode/thinlto-function-summary-originalnames.ll +++ b/test/Bitcode/thinlto-function-summary-originalnames.ll @@ -15,6 +15,7 @@ ; COMBINED-DAG: ; COMBINED-DAG: +; COMBINED-NEXT: ; COMBINED-NEXT: source_filename = "/path/to/source.c" diff --git a/test/Bitcode/thinlto-function-summary.ll b/test/Bitcode/thinlto-function-summary.ll index 67c50379e7a..c9a64018f9d 100644 --- a/test/Bitcode/thinlto-function-summary.ll +++ b/test/Bitcode/thinlto-function-summary.ll @@ -25,6 +25,7 @@ ; BC-NEXT: ; BC-NEXT: ; BACKEND1-NEXT: ; BACKEND2-NEXT: ; COMBINED-NEXT: