[ProfileData] Add new option to dump topn hottest functions

Differential Revision: http://reviews.llvm.org/D35155

llvm-svn: 307702
This commit is contained in:
Xinliang David Li 2017-07-11 20:30:43 +00:00
parent 699e10e5f9
commit db38bdb5c8
3 changed files with 56 additions and 6 deletions

View File

@ -192,6 +192,12 @@ OPTIONS
information is dumped in a more human readable form (also in text) with
annotations.
.. option:: -topn=n
Instruct the profile dumper to show the top ``n`` functions with the
hottest basic blocks in the summary section. By default, the topn functions
are not dumped.
.. option:: -sample
Specify that the input profile is a sample-based profile.

View File

@ -10,6 +10,7 @@ REGENERATE: $ clang -o a.out -fprofile-instr-generate $CFE_TESTDIR/c-general.c
REGENERATE: $ LLVM_PROFILE_FILE=$TESTDIR/Inputs/c-general.profraw ./a.out
RUN: llvm-profdata show %p/Inputs/c-general.profraw -o - | FileCheck %s
RUN: llvm-profdata show %p/Inputs/c-general.profraw --topn=3 -o - | FileCheck %s --check-prefix=TOPN
RUN: llvm-profdata show %p/Inputs/c-general.profraw -o - --function=switches | FileCheck %s -check-prefix=SWITCHES -check-prefix=CHECK
SWITCHES-LABEL: Counters:
@ -22,3 +23,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

View File

@ -512,8 +512,8 @@ static void showValueSitesStats(raw_fd_ostream &OS, uint32_t VK,
}
static int showInstrProfile(const std::string &Filename, bool ShowCounts,
bool ShowIndirectCallTargets, bool ShowMemOPSizes,
bool ShowDetailedSummary,
uint32_t TopN, bool ShowIndirectCallTargets,
bool ShowMemOPSizes, bool ShowDetailedSummary,
std::vector<uint32_t> DetailedSummaryCutoffs,
bool ShowAllFunctions,
const std::string &ShowFunction, bool TextFormat,
@ -532,6 +532,17 @@ static int showInstrProfile(const std::string &Filename, bool ShowCounts,
size_t ShownFunctions = 0;
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);
for (const auto &Func : *Reader) {
bool Show =
ShowAllFunctions || (!ShowFunction.empty() &&
@ -549,6 +560,20 @@ static int showInstrProfile(const std::string &Filename, bool ShowCounts,
assert(Func.Counts.size() > 0 && "function missing entry counter");
Builder.addRecord(Func);
if (TopN) {
uint64_t FuncMax = 0;
for (size_t I = 0, E = Func.Counts.size(); I < E; ++I)
FuncMax = std::max(FuncMax, Func.Counts[I]);
if (HottestFuncs.size() == TopN) {
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 (Show) {
if (!ShownFunctions)
@ -606,6 +631,18 @@ static int showInstrProfile(const std::string &Filename, bool ShowCounts,
OS << "Maximum function count: " << PS->getMaxFunctionCount() << "\n";
OS << "Maximum internal block count: " << PS->getMaxInternalCount() << "\n";
if (TopN) {
std::vector<std::pair<std::string, uint64_t>> SortedHottestFuncs;
while (!HottestFuncs.empty()) {
SortedHottestFuncs.emplace_back(HottestFuncs.top());
HottestFuncs.pop();
}
OS << "Top " << TopN
<< " functions with the largest internal block counts: \n";
for (auto &hotfunc : llvm::reverse(SortedHottestFuncs))
OS << " " << hotfunc.first << ", max count = " << hotfunc.second << "\n";
}
if (ShownFunctions && ShowIndirectCallTargets) {
OS << "Statistics for indirect call sites profile:\n";
showValueSitesStats(OS, IPVK_IndirectCallTarget,
@ -689,6 +726,9 @@ static int show_main(int argc, const char *argv[]) {
cl::desc("Profile kind:"), cl::init(instr),
cl::values(clEnumVal(instr, "Instrumentation profile (default)"),
clEnumVal(sample, "Sample profile")));
cl::opt<uint32_t> TopNFunctions(
"topn", cl::init(0),
cl::desc("Show the list of functions with the largest internal counts"));
cl::ParseCommandLineOptions(argc, argv, "LLVM profile data summary\n");
@ -706,10 +746,10 @@ static int show_main(int argc, const char *argv[]) {
std::vector<uint32_t> Cutoffs(DetailedSummaryCutoffs.begin(),
DetailedSummaryCutoffs.end());
if (ProfileKind == instr)
return showInstrProfile(Filename, ShowCounts, ShowIndirectCallTargets,
ShowMemOPSizes, ShowDetailedSummary,
DetailedSummaryCutoffs, ShowAllFunctions,
ShowFunction, TextFormat, OS);
return showInstrProfile(Filename, ShowCounts, TopNFunctions,
ShowIndirectCallTargets, ShowMemOPSizes,
ShowDetailedSummary, DetailedSummaryCutoffs,
ShowAllFunctions, ShowFunction, TextFormat, OS);
else
return showSampleProfile(Filename, ShowCounts, ShowAllFunctions,
ShowFunction, OS);