diff options
author | Ellis Hoag <ellis.sparky.hoag@gmail.com> | 2025-07-18 14:00:32 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-07-18 14:00:32 -0700 |
commit | fb5c94e712e683e8b7c3cd04b3e47584c226d751 (patch) | |
tree | 30a56537fe5628a353b9801559b6728f9567efbb /llvm/tools/llvm-profdata/llvm-profdata.cpp | |
parent | 004c67ea257039e4e98abc26dd4ac6e8f3d7a171 (diff) | |
download | llvm-fb5c94e712e683e8b7c3cd04b3e47584c226d751.zip llvm-fb5c94e712e683e8b7c3cd04b3e47584c226d751.tar.gz llvm-fb5c94e712e683e8b7c3cd04b3e47584c226d751.tar.bz2 |
[profdata] Use --hot-func-list to show all hot functions (#149428)
The `--hot-func-list` flag is used for sample profiles to dump the list
of hot functions. Add support to dump hot functions for IRPGO profiles
as well.
This also removes a `priority_queue` used for `--topn`. We can instead
store all functions and sort at the end before dumping. Since we are
storing `StringRef`s, I believe this won't consume too much memory.
Diffstat (limited to 'llvm/tools/llvm-profdata/llvm-profdata.cpp')
-rw-r--r-- | llvm/tools/llvm-profdata/llvm-profdata.cpp | 50 |
1 files changed, 22 insertions, 28 deletions
diff --git a/llvm/tools/llvm-profdata/llvm-profdata.cpp b/llvm/tools/llvm-profdata/llvm-profdata.cpp index 5efabd5..96d135b 100644 --- a/llvm/tools/llvm-profdata/llvm-profdata.cpp +++ b/llvm/tools/llvm-profdata/llvm-profdata.cpp @@ -46,7 +46,6 @@ #include <algorithm> #include <cmath> #include <optional> -#include <queue> using namespace llvm; using ProfCorrelatorKind = InstrProfCorrelator::ProfCorrelatorKind; @@ -2846,9 +2845,8 @@ static int showInstrProfile(ShowFormat SFormat, raw_fd_ostream &OS) { auto FS = vfs::getRealFileSystem(); auto ReaderOrErr = InstrProfReader::create(Filename, *FS); std::vector<uint32_t> Cutoffs = std::move(DetailedSummaryCutoffs); - if (ShowDetailedSummary && Cutoffs.empty()) { + if (Cutoffs.empty() && (ShowDetailedSummary || ShowHotFuncList)) Cutoffs = ProfileSummaryBuilder::DefaultCutoffs; - } InstrProfSummaryBuilder Builder(std::move(Cutoffs)); if (Error E = ReaderOrErr.takeError()) exitWithError(std::move(E), Filename); @@ -2860,15 +2858,7 @@ static int showInstrProfile(ShowFormat SFormat, raw_fd_ostream &OS) { int NumVPKind = IPVK_Last - IPVK_First + 1; std::vector<ValueSitesStats> VPStats(NumVPKind); - auto MinCmp = [](const std::pair<std::string, uint64_t> &v1, - const std::pair<std::string, uint64_t> &v2) { - return v1.second > v2.second; - }; - - std::priority_queue<std::pair<std::string, uint64_t>, - std::vector<std::pair<std::string, uint64_t>>, - decltype(MinCmp)> - HottestFuncs(MinCmp); + std::vector<std::pair<StringRef, uint64_t>> NameAndMaxCount; if (!TextFormat && OnlyListBelow) { OS << "The list of functions with the maximum counter less than " @@ -2942,15 +2932,8 @@ static int showInstrProfile(ShowFormat SFormat, raw_fd_ostream &OS) { if (OnlyListBelow) continue; - if (TopNFunctions) { - if (HottestFuncs.size() == TopNFunctions) { - if (HottestFuncs.top().second < FuncMax) { - HottestFuncs.pop(); - HottestFuncs.emplace(std::make_pair(std::string(Func.Name), FuncMax)); - } - } else - HottestFuncs.emplace(std::make_pair(std::string(Func.Name), FuncMax)); - } + if (TopNFunctions || ShowHotFuncList) + NameAndMaxCount.emplace_back(Func.Name, FuncMax); if (Show) { if (!ShownFunctions) @@ -3029,16 +3012,27 @@ static int showInstrProfile(ShowFormat SFormat, raw_fd_ostream &OS) { << "): " << PS->getNumFunctions() - BelowCutoffFunctions << "\n"; } + // Sort by MaxCount in decreasing order + llvm::stable_sort(NameAndMaxCount, [](const auto &L, const auto &R) { + return L.second > R.second; + }); if (TopNFunctions) { - std::vector<std::pair<std::string, uint64_t>> SortedHottestFuncs; - while (!HottestFuncs.empty()) { - SortedHottestFuncs.emplace_back(HottestFuncs.top()); - HottestFuncs.pop(); - } OS << "Top " << TopNFunctions << " functions with the largest internal block counts: \n"; - for (auto &hotfunc : llvm::reverse(SortedHottestFuncs)) - OS << " " << hotfunc.first << ", max count = " << hotfunc.second << "\n"; + auto TopFuncs = ArrayRef(NameAndMaxCount).take_front(TopNFunctions); + for (auto [Name, MaxCount] : TopFuncs) + OS << " " << Name << ", max count = " << MaxCount << "\n"; + } + + if (ShowHotFuncList) { + auto HotCountThreshold = + ProfileSummaryBuilder::getHotCountThreshold(PS->getDetailedSummary()); + OS << "# Hot count threshold: " << HotCountThreshold << "\n"; + for (auto [Name, MaxCount] : NameAndMaxCount) { + if (MaxCount < HotCountThreshold) + break; + OS << Name << "\n"; + } } if (ShownFunctions && ShowIndirectCallTargets) { |