Skip to content

Commit fb5c94e

Browse files
authored
[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.
1 parent 004c67e commit fb5c94e

File tree

3 files changed

+60
-31
lines changed

3 files changed

+60
-31
lines changed

llvm/test/tools/llvm-profdata/c-general.test

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,6 @@ SWITCHES-LABEL: Functions shown: 1
2222
CHECK-LABEL: Total functions: 12
2323
CHECK-NEXT: Maximum function count: 1
2424
CHECK-NEXT: Maximum internal block count: 100
25-
TOPN: boolean_operators, max count = 100
26-
TOPN-NEXT: simple_loops, max count = 100
27-
TOPN-NEXT: conditionals, max count = 100
25+
TOPN: simple_loops, max count = 100
26+
TOPN-NEXT: conditionals, max count = 100
27+
TOPN-NEXT: boolean_operators, max count = 100
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# RUN: llvm-profdata show %s --hot-func-list | FileCheck %s
2+
3+
# CHECK: # Hot count threshold: 101
4+
# CHECK: hot_b
5+
# CHECK: hot_a
6+
# CHECK: hot_c
7+
8+
:ir
9+
hot_a
10+
# Func Hash:
11+
0x1234
12+
# Num Counters:
13+
1
14+
# Counter Values:
15+
101
16+
17+
hot_b
18+
0x5678
19+
1
20+
202
21+
22+
hot_c
23+
0x5678
24+
1
25+
101
26+
27+
cold_d
28+
0xabcd
29+
1
30+
1
31+
32+
cold_e
33+
0xefff
34+
1
35+
0

llvm/tools/llvm-profdata/llvm-profdata.cpp

Lines changed: 22 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@
4646
#include <algorithm>
4747
#include <cmath>
4848
#include <optional>
49-
#include <queue>
5049

5150
using namespace llvm;
5251
using ProfCorrelatorKind = InstrProfCorrelator::ProfCorrelatorKind;
@@ -2846,9 +2845,8 @@ static int showInstrProfile(ShowFormat SFormat, raw_fd_ostream &OS) {
28462845
auto FS = vfs::getRealFileSystem();
28472846
auto ReaderOrErr = InstrProfReader::create(Filename, *FS);
28482847
std::vector<uint32_t> Cutoffs = std::move(DetailedSummaryCutoffs);
2849-
if (ShowDetailedSummary && Cutoffs.empty()) {
2848+
if (Cutoffs.empty() && (ShowDetailedSummary || ShowHotFuncList))
28502849
Cutoffs = ProfileSummaryBuilder::DefaultCutoffs;
2851-
}
28522850
InstrProfSummaryBuilder Builder(std::move(Cutoffs));
28532851
if (Error E = ReaderOrErr.takeError())
28542852
exitWithError(std::move(E), Filename);
@@ -2860,15 +2858,7 @@ static int showInstrProfile(ShowFormat SFormat, raw_fd_ostream &OS) {
28602858
int NumVPKind = IPVK_Last - IPVK_First + 1;
28612859
std::vector<ValueSitesStats> VPStats(NumVPKind);
28622860

2863-
auto MinCmp = [](const std::pair<std::string, uint64_t> &v1,
2864-
const std::pair<std::string, uint64_t> &v2) {
2865-
return v1.second > v2.second;
2866-
};
2867-
2868-
std::priority_queue<std::pair<std::string, uint64_t>,
2869-
std::vector<std::pair<std::string, uint64_t>>,
2870-
decltype(MinCmp)>
2871-
HottestFuncs(MinCmp);
2861+
std::vector<std::pair<StringRef, uint64_t>> NameAndMaxCount;
28722862

28732863
if (!TextFormat && OnlyListBelow) {
28742864
OS << "The list of functions with the maximum counter less than "
@@ -2942,15 +2932,8 @@ static int showInstrProfile(ShowFormat SFormat, raw_fd_ostream &OS) {
29422932
if (OnlyListBelow)
29432933
continue;
29442934

2945-
if (TopNFunctions) {
2946-
if (HottestFuncs.size() == TopNFunctions) {
2947-
if (HottestFuncs.top().second < FuncMax) {
2948-
HottestFuncs.pop();
2949-
HottestFuncs.emplace(std::make_pair(std::string(Func.Name), FuncMax));
2950-
}
2951-
} else
2952-
HottestFuncs.emplace(std::make_pair(std::string(Func.Name), FuncMax));
2953-
}
2935+
if (TopNFunctions || ShowHotFuncList)
2936+
NameAndMaxCount.emplace_back(Func.Name, FuncMax);
29542937

29552938
if (Show) {
29562939
if (!ShownFunctions)
@@ -3029,16 +3012,27 @@ static int showInstrProfile(ShowFormat SFormat, raw_fd_ostream &OS) {
30293012
<< "): " << PS->getNumFunctions() - BelowCutoffFunctions << "\n";
30303013
}
30313014

3015+
// Sort by MaxCount in decreasing order
3016+
llvm::stable_sort(NameAndMaxCount, [](const auto &L, const auto &R) {
3017+
return L.second > R.second;
3018+
});
30323019
if (TopNFunctions) {
3033-
std::vector<std::pair<std::string, uint64_t>> SortedHottestFuncs;
3034-
while (!HottestFuncs.empty()) {
3035-
SortedHottestFuncs.emplace_back(HottestFuncs.top());
3036-
HottestFuncs.pop();
3037-
}
30383020
OS << "Top " << TopNFunctions
30393021
<< " functions with the largest internal block counts: \n";
3040-
for (auto &hotfunc : llvm::reverse(SortedHottestFuncs))
3041-
OS << " " << hotfunc.first << ", max count = " << hotfunc.second << "\n";
3022+
auto TopFuncs = ArrayRef(NameAndMaxCount).take_front(TopNFunctions);
3023+
for (auto [Name, MaxCount] : TopFuncs)
3024+
OS << " " << Name << ", max count = " << MaxCount << "\n";
3025+
}
3026+
3027+
if (ShowHotFuncList) {
3028+
auto HotCountThreshold =
3029+
ProfileSummaryBuilder::getHotCountThreshold(PS->getDetailedSummary());
3030+
OS << "# Hot count threshold: " << HotCountThreshold << "\n";
3031+
for (auto [Name, MaxCount] : NameAndMaxCount) {
3032+
if (MaxCount < HotCountThreshold)
3033+
break;
3034+
OS << Name << "\n";
3035+
}
30423036
}
30433037

30443038
if (ShownFunctions && ShowIndirectCallTargets) {

0 commit comments

Comments
 (0)