mirror of
https://github.com/intel/llvm.git
synced 2026-01-24 08:30:34 +08:00
[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.
This commit is contained in:
@@ -22,6 +22,6 @@ SWITCHES-LABEL: Functions shown: 1
|
||||
CHECK-LABEL: Total functions: 12
|
||||
CHECK-NEXT: Maximum function count: 1
|
||||
CHECK-NEXT: Maximum internal block count: 100
|
||||
TOPN: boolean_operators, max count = 100
|
||||
TOPN-NEXT: simple_loops, max count = 100
|
||||
TOPN-NEXT: conditionals, max count = 100
|
||||
TOPN: simple_loops, max count = 100
|
||||
TOPN-NEXT: conditionals, max count = 100
|
||||
TOPN-NEXT: boolean_operators, max count = 100
|
||||
|
||||
35
llvm/test/tools/llvm-profdata/show-hot.proftext
Normal file
35
llvm/test/tools/llvm-profdata/show-hot.proftext
Normal file
@@ -0,0 +1,35 @@
|
||||
# RUN: llvm-profdata show %s --hot-func-list | FileCheck %s
|
||||
|
||||
# CHECK: # Hot count threshold: 101
|
||||
# CHECK: hot_b
|
||||
# CHECK: hot_a
|
||||
# CHECK: hot_c
|
||||
|
||||
:ir
|
||||
hot_a
|
||||
# Func Hash:
|
||||
0x1234
|
||||
# Num Counters:
|
||||
1
|
||||
# Counter Values:
|
||||
101
|
||||
|
||||
hot_b
|
||||
0x5678
|
||||
1
|
||||
202
|
||||
|
||||
hot_c
|
||||
0x5678
|
||||
1
|
||||
101
|
||||
|
||||
cold_d
|
||||
0xabcd
|
||||
1
|
||||
1
|
||||
|
||||
cold_e
|
||||
0xefff
|
||||
1
|
||||
0
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user