mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-26 14:16:12 +00:00
[ProfileData] Add new option to dump topn hottest functions
Differential Revision: http://reviews.llvm.org/D35155 llvm-svn: 307702
This commit is contained in:
parent
699e10e5f9
commit
db38bdb5c8
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user