diff --git a/lld/test/COFF/thinlto-index-only.ll b/lld/test/COFF/thinlto-index-only.ll --- a/lld/test/COFF/thinlto-index-only.ll +++ b/lld/test/COFF/thinlto-index-only.ll @@ -39,6 +39,7 @@ ; BACKEND2-NEXT: ; BACKEND2-NEXT: ; BACKEND2-NEXT: ; @@ -1019,15 +1022,15 @@ 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 // in the way some record are interpreted, like flags for instance. // Note that incrementing this may require changes in both BitcodeReader.cpp // and BitcodeWriter.cpp. - static constexpr uint64_t BitcodeSummaryVersion = 8; + static constexpr uint64_t BitcodeSummaryVersion = 9; // Regular LTO module name for ASM writer static constexpr const char *getRegularLTOModuleName() { @@ -1039,6 +1042,10 @@ 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/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp b/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp --- a/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp +++ b/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp @@ -249,6 +249,7 @@ assert(F.hasName()); unsigned NumInsts = 0; + uint64_t NumBlocks = 0; // Map from callee ValueId to profile count. Used to accumulate profile // counts for all static calls to a given callee. MapVector CallGraphEdges; @@ -268,7 +269,8 @@ std::vector NonVolatileStores; bool HasInlineAsmMaybeReferencingInternal = false; - for (const BasicBlock &BB : F) + for (const BasicBlock &BB : F) { + ++NumBlocks; for (const Instruction &I : BB) { if (isa(I)) continue; @@ -390,6 +392,8 @@ .updateHotness(getHotness(Candidate.Count, PSI)); } } + } + Index.addBlockCount(NumBlocks); std::vector Refs; if (IsThinLTO) { diff --git a/llvm/lib/AsmParser/LLLexer.cpp b/llvm/lib/AsmParser/LLLexer.cpp --- a/llvm/lib/AsmParser/LLLexer.cpp +++ b/llvm/lib/AsmParser/LLLexer.cpp @@ -741,6 +741,7 @@ KEYWORD(name); KEYWORD(summaries); KEYWORD(flags); + KEYWORD(blockcount); KEYWORD(linkage); KEYWORD(notEligibleToImport); KEYWORD(live); diff --git a/llvm/lib/AsmParser/LLParser.h b/llvm/lib/AsmParser/LLParser.h --- a/llvm/lib/AsmParser/LLParser.h +++ b/llvm/lib/AsmParser/LLParser.h @@ -341,6 +341,7 @@ 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/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -853,6 +853,9 @@ case lltok::kw_flags: result = ParseSummaryIndexFlags(); break; + case lltok::kw_blockcount: + result = ParseBlockCount(); + break; default: result = Error(Lex.getLoc(), "unexpected summary kind"); break; @@ -8091,6 +8094,21 @@ 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/llvm/lib/AsmParser/LLToken.h b/llvm/lib/AsmParser/LLToken.h --- a/llvm/lib/AsmParser/LLToken.h +++ b/llvm/lib/AsmParser/LLToken.h @@ -374,6 +374,7 @@ kw_name, kw_summaries, kw_flags, + kw_blockcount, kw_linkage, kw_notEligibleToImport, kw_live, diff --git a/llvm/lib/Bitcode/Reader/BitcodeAnalyzer.cpp b/llvm/lib/Bitcode/Reader/BitcodeAnalyzer.cpp --- a/llvm/lib/Bitcode/Reader/BitcodeAnalyzer.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeAnalyzer.cpp @@ -305,6 +305,7 @@ 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/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -6239,6 +6239,10 @@ case bitc::FS_TYPE_ID_METADATA: parseTypeIdCompatibleVtableSummaryRecord(Record); break; + + case bitc::FS_BLOCK_COUNT: + // TheIndex.setBlockCount(Record[0]); + TheIndex.addBlockCount(Record[0]); } } llvm_unreachable("Exit infinite loop"); diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -3909,6 +3909,9 @@ NameVals.clear(); } + Stream.EmitRecord(bitc::FS_BLOCK_COUNT, + ArrayRef{Index->getBlockCount()}); + Stream.ExitBlock(); } @@ -4192,6 +4195,9 @@ } } + Stream.EmitRecord(bitc::FS_BLOCK_COUNT, + ArrayRef{Index.getBlockCount()}); + Stream.ExitBlock(); } diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -2797,8 +2797,13 @@ } // 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/llvm/test/Assembler/thinlto-vtable-summary.ll b/llvm/test/Assembler/thinlto-vtable-summary.ll --- a/llvm/test/Assembler/thinlto-vtable-summary.ll +++ b/llvm/test/Assembler/thinlto-vtable-summary.ll @@ -36,3 +36,4 @@ ^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/llvm/test/Bitcode/summary_version.ll b/llvm/test/Bitcode/summary_version.ll --- a/llvm/test/Bitcode/summary_version.ll +++ b/llvm/test/Bitcode/summary_version.ll @@ -2,7 +2,7 @@ ; RUN: opt -module-summary %s -o - | llvm-bcanalyzer -dump | FileCheck %s ; CHECK: +; CHECK: diff --git a/llvm/test/Bitcode/thinlto-alias.ll b/llvm/test/Bitcode/thinlto-alias.ll --- a/llvm/test/Bitcode/thinlto-alias.ll +++ b/llvm/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/llvm/test/Bitcode/thinlto-function-summary-callgraph-cast.ll b/llvm/test/Bitcode/thinlto-function-summary-callgraph-cast.ll --- a/llvm/test/Bitcode/thinlto-function-summary-callgraph-cast.ll +++ b/llvm/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/llvm/test/Bitcode/thinlto-function-summary-callgraph-pgo.ll b/llvm/test/Bitcode/thinlto-function-summary-callgraph-pgo.ll --- a/llvm/test/Bitcode/thinlto-function-summary-callgraph-pgo.ll +++ b/llvm/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/llvm/test/Bitcode/thinlto-function-summary-callgraph-profile-summary.ll b/llvm/test/Bitcode/thinlto-function-summary-callgraph-profile-summary.ll --- a/llvm/test/Bitcode/thinlto-function-summary-callgraph-profile-summary.ll +++ b/llvm/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/llvm/test/Bitcode/thinlto-function-summary-callgraph-relbf.ll b/llvm/test/Bitcode/thinlto-function-summary-callgraph-relbf.ll --- a/llvm/test/Bitcode/thinlto-function-summary-callgraph-relbf.ll +++ b/llvm/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/llvm/test/Bitcode/thinlto-function-summary-callgraph.ll b/llvm/test/Bitcode/thinlto-function-summary-callgraph.ll --- a/llvm/test/Bitcode/thinlto-function-summary-callgraph.ll +++ b/llvm/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/llvm/test/Bitcode/thinlto-function-summary-originalnames.ll b/llvm/test/Bitcode/thinlto-function-summary-originalnames.ll --- a/llvm/test/Bitcode/thinlto-function-summary-originalnames.ll +++ b/llvm/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/llvm/test/Bitcode/thinlto-function-summary.ll b/llvm/test/Bitcode/thinlto-function-summary.ll --- a/llvm/test/Bitcode/thinlto-function-summary.ll +++ b/llvm/test/Bitcode/thinlto-function-summary.ll @@ -25,6 +25,7 @@ ; BC-NEXT: ; BC-NEXT: ; BACKEND1-NEXT: ; BACKEND2-NEXT: ; COMBINED-NEXT: