Skip to content

Commit 801b531

Browse files
committedJul 11, 2017
[ProfileData] Add new option to dump topn hottest functions
Differential Revision: http://reviews.llvm.org/D35155 llvm-svn: 307702
1 parent f84c2fc commit 801b531

File tree

3 files changed

+56
-6
lines changed

3 files changed

+56
-6
lines changed
 

‎llvm/docs/CommandGuide/llvm-profdata.rst

+6
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,12 @@ OPTIONS
192192
information is dumped in a more human readable form (also in text) with
193193
annotations.
194194

195+
.. option:: -topn=n
196+
197+
Instruct the profile dumper to show the top ``n`` functions with the
198+
hottest basic blocks in the summary section. By default, the topn functions
199+
are not dumped.
200+
195201
.. option:: -sample
196202

197203
Specify that the input profile is a sample-based profile.

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

+4
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ REGENERATE: $ clang -o a.out -fprofile-instr-generate $CFE_TESTDIR/c-general.c
1010
REGENERATE: $ LLVM_PROFILE_FILE=$TESTDIR/Inputs/c-general.profraw ./a.out
1111

1212
RUN: llvm-profdata show %p/Inputs/c-general.profraw -o - | FileCheck %s
13+
RUN: llvm-profdata show %p/Inputs/c-general.profraw --topn=3 -o - | FileCheck %s --check-prefix=TOPN
1314
RUN: llvm-profdata show %p/Inputs/c-general.profraw -o - --function=switches | FileCheck %s -check-prefix=SWITCHES -check-prefix=CHECK
1415

1516
SWITCHES-LABEL: Counters:
@@ -22,3 +23,6 @@ SWITCHES-LABEL: Functions shown: 1
2223
CHECK-LABEL: Total functions: 12
2324
CHECK-NEXT: Maximum function count: 1
2425
CHECK-NEXT: Maximum internal block count: 100
26+
TOPN: boolean_operators, max count = 100
27+
TOPN-NEXT: simple_loops, max count = 100
28+
TOPN-NEXT: conditionals, max count = 100

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

+46-6
Original file line numberDiff line numberDiff line change
@@ -512,8 +512,8 @@ static void showValueSitesStats(raw_fd_ostream &OS, uint32_t VK,
512512
}
513513

514514
static int showInstrProfile(const std::string &Filename, bool ShowCounts,
515-
bool ShowIndirectCallTargets, bool ShowMemOPSizes,
516-
bool ShowDetailedSummary,
515+
uint32_t TopN, bool ShowIndirectCallTargets,
516+
bool ShowMemOPSizes, bool ShowDetailedSummary,
517517
std::vector<uint32_t> DetailedSummaryCutoffs,
518518
bool ShowAllFunctions,
519519
const std::string &ShowFunction, bool TextFormat,
@@ -532,6 +532,17 @@ static int showInstrProfile(const std::string &Filename, bool ShowCounts,
532532
size_t ShownFunctions = 0;
533533
int NumVPKind = IPVK_Last - IPVK_First + 1;
534534
std::vector<ValueSitesStats> VPStats(NumVPKind);
535+
536+
auto MinCmp = [](const std::pair<std::string, uint64_t> &v1,
537+
const std::pair<std::string, uint64_t> &v2) {
538+
return v1.second > v2.second;
539+
};
540+
541+
std::priority_queue<std::pair<std::string, uint64_t>,
542+
std::vector<std::pair<std::string, uint64_t>>,
543+
decltype(MinCmp)>
544+
HottestFuncs(MinCmp);
545+
535546
for (const auto &Func : *Reader) {
536547
bool Show =
537548
ShowAllFunctions || (!ShowFunction.empty() &&
@@ -549,6 +560,20 @@ static int showInstrProfile(const std::string &Filename, bool ShowCounts,
549560
assert(Func.Counts.size() > 0 && "function missing entry counter");
550561
Builder.addRecord(Func);
551562

563+
if (TopN) {
564+
uint64_t FuncMax = 0;
565+
for (size_t I = 0, E = Func.Counts.size(); I < E; ++I)
566+
FuncMax = std::max(FuncMax, Func.Counts[I]);
567+
568+
if (HottestFuncs.size() == TopN) {
569+
if (HottestFuncs.top().second < FuncMax) {
570+
HottestFuncs.pop();
571+
HottestFuncs.emplace(std::make_pair(std::string(Func.Name), FuncMax));
572+
}
573+
} else
574+
HottestFuncs.emplace(std::make_pair(std::string(Func.Name), FuncMax));
575+
}
576+
552577
if (Show) {
553578

554579
if (!ShownFunctions)
@@ -606,6 +631,18 @@ static int showInstrProfile(const std::string &Filename, bool ShowCounts,
606631
OS << "Maximum function count: " << PS->getMaxFunctionCount() << "\n";
607632
OS << "Maximum internal block count: " << PS->getMaxInternalCount() << "\n";
608633

634+
if (TopN) {
635+
std::vector<std::pair<std::string, uint64_t>> SortedHottestFuncs;
636+
while (!HottestFuncs.empty()) {
637+
SortedHottestFuncs.emplace_back(HottestFuncs.top());
638+
HottestFuncs.pop();
639+
}
640+
OS << "Top " << TopN
641+
<< " functions with the largest internal block counts: \n";
642+
for (auto &hotfunc : llvm::reverse(SortedHottestFuncs))
643+
OS << " " << hotfunc.first << ", max count = " << hotfunc.second << "\n";
644+
}
645+
609646
if (ShownFunctions && ShowIndirectCallTargets) {
610647
OS << "Statistics for indirect call sites profile:\n";
611648
showValueSitesStats(OS, IPVK_IndirectCallTarget,
@@ -689,6 +726,9 @@ static int show_main(int argc, const char *argv[]) {
689726
cl::desc("Profile kind:"), cl::init(instr),
690727
cl::values(clEnumVal(instr, "Instrumentation profile (default)"),
691728
clEnumVal(sample, "Sample profile")));
729+
cl::opt<uint32_t> TopNFunctions(
730+
"topn", cl::init(0),
731+
cl::desc("Show the list of functions with the largest internal counts"));
692732

693733
cl::ParseCommandLineOptions(argc, argv, "LLVM profile data summary\n");
694734

@@ -706,10 +746,10 @@ static int show_main(int argc, const char *argv[]) {
706746
std::vector<uint32_t> Cutoffs(DetailedSummaryCutoffs.begin(),
707747
DetailedSummaryCutoffs.end());
708748
if (ProfileKind == instr)
709-
return showInstrProfile(Filename, ShowCounts, ShowIndirectCallTargets,
710-
ShowMemOPSizes, ShowDetailedSummary,
711-
DetailedSummaryCutoffs, ShowAllFunctions,
712-
ShowFunction, TextFormat, OS);
749+
return showInstrProfile(Filename, ShowCounts, TopNFunctions,
750+
ShowIndirectCallTargets, ShowMemOPSizes,
751+
ShowDetailedSummary, DetailedSummaryCutoffs,
752+
ShowAllFunctions, ShowFunction, TextFormat, OS);
713753
else
714754
return showSampleProfile(Filename, ShowCounts, ShowAllFunctions,
715755
ShowFunction, OS);

0 commit comments

Comments
 (0)
Please sign in to comment.