Index: include/llvm/Bitcode/LLVMBitCodes.h =================================================================== --- include/llvm/Bitcode/LLVMBitCodes.h +++ include/llvm/Bitcode/LLVMBitCodes.h @@ -195,11 +195,12 @@ // PERMODULE_CALLS_PROFILE: [valueid, linkage, instcount, // n x (valueid, callsitecount, profilecount)] FS_PERMODULE_CALLS_PROFILE = 3, - // COMBINED_NOCALLS: [modid, linkage, instcount] + // COMBINED_NOCALLS: [modid, linkage, callcount, instcount] FS_COMBINED_NOCALLS = 4, - // COMBINED_CALLS: [modid, linkage, instcount, n x (valueid, callsitecount)] + // COMBINED_CALLS: [modid, linkage, callcount, instcount, + // n x (valueid, callsitecount)] FS_COMBINED_CALLS = 5, - // COMBINED_CALLS_PROFILE: [modid, linkage, instcount, + // COMBINED_CALLS_PROFILE: [modid, linkage, callcount, instcount, // n x (valueid, callsitecount, profilecount)] FS_COMBINED_CALLS_PROFILE = 6, }; Index: include/llvm/IR/FunctionInfo.h =================================================================== --- include/llvm/IR/FunctionInfo.h +++ include/llvm/IR/FunctionInfo.h @@ -76,13 +76,17 @@ /// during the initial compile step when the function index is first built. unsigned InstCount; + /// Static number of call sites found via call graph edges in the combined + /// index. Saturates at 3. + unsigned CallCount; + /// List of call edge pairs from this function. std::vector CallGraphEdgeList; public: /// Summary constructors. - FunctionSummary() : InstCount(0) {} - FunctionSummary(unsigned NumInsts) : InstCount(NumInsts) {} + FunctionSummary() : InstCount(0), CallCount(0) {} + FunctionSummary(unsigned NumInsts) : InstCount(NumInsts), CallCount(0) {} /// Set the path to the module containing this function, for use in /// the combined index. @@ -107,6 +111,12 @@ /// Get the instruction count recorded for this function. unsigned instCount() const { return InstCount; } + /// Set the call count for this function. + void setCallCount(unsigned NumCalls) { CallCount = NumCalls; } + + /// Get the call count recorded for this function. + unsigned callCount() const { return CallCount; } + /// Record a call graph edge from this function to the function identified /// by \p CalleeGUID, with \p CalleeInfo including the cumulative profile /// count (across all calls from this function) or 0 if no FDO. @@ -208,6 +218,8 @@ /// Holds strings for combined index, mapping to the corresponding module ID. ModulePathStringTableTy ModulePathStringTable; + std::map GUIDToNameMap; + public: FunctionInfoIndex() = default; @@ -234,12 +246,23 @@ /// Add a function info for a function of the given name. void addFunctionInfo(StringRef FuncName, std::unique_ptr Info) { FunctionMap[Function::getGUID(FuncName)].push_back(std::move(Info)); + addName(FuncName); } void addFunctionInfo(uint64_t FuncGUID, std::unique_ptr Info) { FunctionMap[FuncGUID].push_back(std::move(Info)); } + void addName(StringRef FuncName) { + GUIDToNameMap[Function::getGUID(FuncName)] = FuncName.str(); + } + + std::string getName(uint64_t FuncGUID) const { + auto I = GUIDToNameMap.find(FuncGUID); + assert(I != GUIDToNameMap.end()); + return I->second; + } + /// Iterator to allow writer to walk through table during emission. iterator_range::const_iterator> modPathStringEntries() const { Index: lib/Bitcode/Reader/BitcodeReader.cpp =================================================================== --- lib/Bitcode/Reader/BitcodeReader.cpp +++ lib/Bitcode/Reader/BitcodeReader.cpp @@ -5715,21 +5715,23 @@ } break; } - // FS_COMBINED_NOCALLS: [modid, linkage, instcount] - // FS_COMBINED_CALLS: [modid, linkage, instcount, + // FS_COMBINED_NOCALLS: [modid, linkage, callcount, instcount] + // FS_COMBINED_CALLS: [modid, linkage, callcount, instcount, // n x (valueid, callsitecount)] - // FS_COMBINED_CALLS_PROFILE: [modid, linkage, instcount, + // FS_COMBINED_CALLS_PROFILE: [modid, linkage, callcount, instcount, // n x (valueid, callsitecount, profilecount)] case bitc::FS_COMBINED_NOCALLS: case bitc::FS_COMBINED_CALLS: case bitc::FS_COMBINED_CALLS_PROFILE: { uint64_t ModuleId = Record[0]; uint64_t RawLinkage = Record[1]; - unsigned InstCount = Record[2]; + unsigned CallCount = Record[2]; // Saturates at 3. + unsigned InstCount = Record[3]; std::unique_ptr FS = llvm::make_unique(InstCount); FS->setFunctionLinkage(getDecodedLinkage(RawLinkage)); FS->setModulePath(ModuleIdMap[ModuleId]); + FS->setCallCount(CallCount); FunctionSummaryIOHelper &BitcodeSummary = SummaryMap[CurRecordBit]; BitcodeSummary.setFunctionSummary(std::move(FS)); bool HasProfile = (BitCode == bitc::FS_COMBINED_CALLS_PROFILE); @@ -5738,7 +5740,7 @@ // on the summary helper object. After reading the VST this will // be transferred into the function summary in the index, using the // callee GUID instead. - static int CallGraphEdgeStartIndex = 3; + static int CallGraphEdgeStartIndex = 4; for (unsigned I = CallGraphEdgeStartIndex, E = Record.size(); I != E; ++I) { unsigned CalleeValueId = Record[I]; Index: lib/Bitcode/Writer/BitcodeWriter.cpp =================================================================== --- lib/Bitcode/Writer/BitcodeWriter.cpp +++ lib/Bitcode/Writer/BitcodeWriter.cpp @@ -2978,6 +2978,7 @@ Abbv->Add(BitCodeAbbrevOp(bitc::FS_COMBINED_NOCALLS)); Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // modid Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 5)); // linkage + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // callcount (saturates at 3) Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // instcount unsigned FSNoCallsAbbrev = Stream.EmitAbbrev(Abbv); @@ -2986,6 +2987,7 @@ Abbv->Add(BitCodeAbbrevOp(bitc::FS_COMBINED_CALLS)); Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // modid Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 5)); // linkage + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // callcount (saturates at 3) Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // instcount Abbv->Add( BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); // valueid/callsitecount pairs @@ -2997,12 +2999,31 @@ Abbv->Add(BitCodeAbbrevOp(bitc::FS_COMBINED_CALLS_PROFILE)); Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // modid Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 5)); // linkage + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // callcount (saturates at 3) Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // instcount Abbv->Add(BitCodeAbbrevOp( BitCodeAbbrevOp::Array)); // valueid/callsitecount/profilecount triples Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); unsigned FSCallsProfileAbbrev = Stream.EmitAbbrev(Abbv); + std::map ValueIdToCallCountMap; + for (const auto &FII : I) { + for (auto &FI : FII.second) { + FunctionSummary *FS = FI->functionSummary(); + assert(FS); + for (auto &EI : FS->edges()) { + const auto &VMI = GUIDToValueIdMap.find(EI.first); + // If this GUID doesn't have an entry, it doesn't have a function + // summary and we don't need to record any calls to it. + if (VMI == GUIDToValueIdMap.end()) + continue; + ValueIdToCallCountMap[VMI->second] += EI.second.CallsiteCount; + } + } + } + + unsigned TotalSummaries = 0; + unsigned CallCounts[4] = {0}; SmallVector NameVals; for (const auto &FII : I) { for (auto &FI : FII.second) { @@ -3011,6 +3032,21 @@ NameVals.push_back(I.getModuleId(FS->modulePath())); NameVals.push_back(getEncodedLinkage(FS->getFunctionLinkage())); + + const auto &VMI = GUIDToValueIdMap.find(FII.first); + assert(VMI != GUIDToValueIdMap.end()); + const auto &VCI = ValueIdToCallCountMap.find(VMI->second); + unsigned CallCount = 0; + if (VCI != ValueIdToCallCountMap.end()) { + assert(VCI->second > 0 && "Expected at least 1 call in map"); + // Saturate call count at 3 + CallCount = VCI->second > 3 ? 3 : VCI->second; + } + NameVals.push_back(CallCount); + TotalSummaries++; + CallCounts[CallCount]++; + errs() << "CC " << I.getName(FII.first) << " : " << VCI->second << "\n"; + NameVals.push_back(FS->instCount()); bool HasProfileData = false; @@ -3053,6 +3089,10 @@ NameVals.clear(); } } + errs() << "TotalSummaries: " << TotalSummaries << " CallCounts:"; + for (unsigned i=0; i<4; i++) + errs() << " " << i << ": " << CallCounts[i]; + errs() << "\n"; Stream.ExitBlock(); } Index: lib/IR/FunctionInfo.cpp =================================================================== --- lib/IR/FunctionInfo.cpp +++ lib/IR/FunctionInfo.cpp @@ -53,5 +53,6 @@ // combining FunctionMap entries, due to COMDAT functions. Any local // functions were given unique global IDs. addFunctionInfo(FuncGUID, std::move(Info)); + addName(Other->getName(FuncGUID)); } }