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: