[llvm] [nfc][llvm-profdata]Refactor llvm-profdata show* code, by moving function-scope options to a show_llvmprofdata namespace (PR #71328)
Mingming Liu via llvm-commits
llvm-commits at lists.llvm.org
Tue Nov 7 22:03:39 PST 2023
https://github.com/minglotus-6 updated https://github.com/llvm/llvm-project/pull/71328
>From e9b590a65994c8e8a4bcd02859a9e7a17fd657b1 Mon Sep 17 00:00:00 2001
From: Mingming Liu <mingmingl at google.com>
Date: Tue, 7 Nov 2023 12:02:10 -0800
Subject: [PATCH 1/2] [nfc][llvm-profdata] Move show options to its namespace
---
llvm/tools/llvm-profdata/llvm-profdata.cpp | 252 ++++++++++-----------
1 file changed, 115 insertions(+), 137 deletions(-)
diff --git a/llvm/tools/llvm-profdata/llvm-profdata.cpp b/llvm/tools/llvm-profdata/llvm-profdata.cpp
index e7e7f8228d7d9c3..f8e6bf5dd9b99e5 100644
--- a/llvm/tools/llvm-profdata/llvm-profdata.cpp
+++ b/llvm/tools/llvm-profdata/llvm-profdata.cpp
@@ -2387,6 +2387,7 @@ static int overlap_main(int argc, const char *argv[]) {
return 0;
}
+namespace show_llvmprofdata {
namespace {
struct ValueSitesStats {
ValueSitesStats()
@@ -2447,14 +2448,101 @@ static void showValueSitesStats(raw_fd_ostream &OS, uint32_t VK,
}
}
-static int showInstrProfile(
- const std::string &Filename, bool ShowCounts, uint32_t TopN,
- bool ShowIndirectCallTargets, bool ShowMemOPSizes, bool ShowDetailedSummary,
- std::vector<uint32_t> DetailedSummaryCutoffs, bool ShowAllFunctions,
- bool ShowCS, uint64_t ValueCutoff, bool OnlyListBelow,
- const std::string &ShowFunction, bool TextFormat, bool ShowBinaryIds,
- bool ShowCovered, bool ShowProfileVersion, bool ShowTemporalProfTraces,
- ShowFormat SFormat, raw_fd_ostream &OS) {
+cl::opt<std::string> Filename(cl::Positional, cl::desc("<profdata-file>"));
+
+cl::opt<bool> ShowCounts("counts", cl::init(false),
+ cl::desc("Show counter values for shown functions"));
+cl::opt<ShowFormat>
+ SFormat("show-format", cl::init(ShowFormat::Text),
+ cl::desc("Emit output in the selected format if supported"),
+ cl::values(clEnumValN(ShowFormat::Text, "text",
+ "emit normal text output (default)"),
+ clEnumValN(ShowFormat::Json, "json", "emit JSON"),
+ clEnumValN(ShowFormat::Yaml, "yaml", "emit YAML")));
+// TODO: Consider replacing this with `--show-format=text-encoding`.
+cl::opt<bool>
+ TextFormat("text", cl::init(false),
+ cl::desc("Show instr profile data in text dump format"));
+cl::opt<bool>
+ JsonFormat("json", cl::desc("Show sample profile data in the JSON format "
+ "(deprecated, please use --show-format=json)"));
+cl::opt<bool> ShowIndirectCallTargets(
+ "ic-targets", cl::init(false),
+ cl::desc("Show indirect call site target values for shown functions"));
+cl::opt<bool> ShowMemOPSizes(
+ "memop-sizes", cl::init(false),
+ cl::desc("Show the profiled sizes of the memory intrinsic calls "
+ "for shown functions"));
+cl::opt<bool> ShowDetailedSummary("detailed-summary", cl::init(false),
+ cl::desc("Show detailed profile summary"));
+cl::list<uint32_t> DetailedSummaryCutoffs(
+ cl::CommaSeparated, "detailed-summary-cutoffs",
+ cl::desc(
+ "Cutoff percentages (times 10000) for generating detailed summary"),
+ cl::value_desc("800000,901000,999999"));
+cl::opt<bool> ShowHotFuncList(
+ "hot-func-list", cl::init(false),
+ cl::desc("Show profile summary of a list of hot functions"));
+cl::opt<bool> ShowAllFunctions("all-functions", cl::init(false),
+ cl::desc("Details for every function"));
+cl::opt<bool> ShowCS("showcs", cl::init(false),
+ cl::desc("Show context sensitive counts"));
+cl::opt<std::string> ShowFunction("function",
+ cl::desc("Details for matching functions"));
+
+cl::opt<std::string> OutputFilename("output", cl::value_desc("output"),
+ cl::init("-"), cl::desc("Output file"));
+cl::alias OutputFilenameA("o", cl::desc("Alias for --output"),
+ cl::aliasopt(OutputFilename));
+cl::opt<ProfileKinds> ProfileKind(
+ cl::desc("Profile kind:"), cl::init(instr),
+ cl::values(clEnumVal(instr, "Instrumentation profile (default)"),
+ clEnumVal(sample, "Sample profile"),
+ clEnumVal(memory, "MemProf memory access profile")));
+cl::opt<uint32_t> TopNFunctions(
+ "topn", cl::init(0),
+ cl::desc("Show the list of functions with the largest internal counts"));
+cl::opt<uint32_t> ValueCutoff(
+ "value-cutoff", cl::init(0),
+ cl::desc("Set the count value cutoff. Functions with the maximum count "
+ "less than this value will not be printed out. (Default is 0)"));
+cl::opt<bool> OnlyListBelow(
+ "list-below-cutoff", cl::init(false),
+ cl::desc("Only output names of functions whose max count values are "
+ "below the cutoff value"));
+cl::opt<bool> ShowProfileSymbolList(
+ "show-prof-sym-list", cl::init(false),
+ cl::desc("Show profile symbol list if it exists in the profile. "));
+cl::opt<bool> ShowSectionInfoOnly(
+ "show-sec-info-only", cl::init(false),
+ cl::desc("Show the information of each section in the sample profile. "
+ "The flag is only usable when the sample profile is in "
+ "extbinary format"));
+cl::opt<bool> ShowBinaryIds("binary-ids", cl::init(false),
+ cl::desc("Show binary ids in the profile. "));
+cl::opt<bool> ShowTemporalProfTraces(
+ "temporal-profile-traces",
+ cl::desc("Show temporal profile traces in the profile."));
+cl::opt<std::string> DebugInfoFilename(
+ "debug-info", cl::init(""),
+ cl::desc("Read and extract profile metadata from debug info and show "
+ "the functions it found."));
+cl::opt<unsigned> MaxDbgCorrelationWarnings(
+ "max-debug-info-correlation-warnings",
+ cl::desc("The maximum number of warnings to emit when correlating "
+ "profile from debug info (0 = no limit)"),
+ cl::init(5));
+cl::opt<bool>
+ ShowCovered("covered", cl::init(false),
+ cl::desc("Show only the functions that have been executed."));
+cl::opt<std::string> ProfiledBinary(
+ "profiled-binary", cl::init(""),
+ cl::desc("Path to binary from which the profile was collected."));
+cl::opt<bool> ShowProfileVersion("profile-version", cl::init(false),
+ cl::desc("Show profile version. "));
+
+static int showInstrProfile(const std::string &Filename, ShowFormat SFormat,
+ raw_fd_ostream &OS) {
if (SFormat == ShowFormat::Json)
exitWithError("JSON output is not supported for instr profiles");
if (SFormat == ShowFormat::Yaml)
@@ -2559,8 +2647,8 @@ static int showInstrProfile(
} else if (OnlyListBelow)
continue;
- if (TopN) {
- if (HottestFuncs.size() == TopN) {
+ if (TopNFunctions) {
+ if (HottestFuncs.size() == TopNFunctions) {
if (HottestFuncs.top().second < FuncMax) {
HottestFuncs.pop();
HottestFuncs.emplace(std::make_pair(std::string(Func.Name), FuncMax));
@@ -2636,13 +2724,13 @@ static int showInstrProfile(
OS << "Maximum function count: " << PS->getMaxFunctionCount() << "\n";
OS << "Maximum internal block count: " << PS->getMaxInternalCount() << "\n";
- if (TopN) {
+ if (TopNFunctions) {
std::vector<std::pair<std::string, uint64_t>> SortedHottestFuncs;
while (!HottestFuncs.empty()) {
SortedHottestFuncs.emplace_back(HottestFuncs.top());
HottestFuncs.pop();
}
- OS << "Top " << TopN
+ 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";
@@ -2832,13 +2920,8 @@ static int showHotFunctionList(const sampleprof::SampleProfileMap &Profiles,
return 0;
}
-static int showSampleProfile(const std::string &Filename, bool ShowCounts,
- uint32_t TopN, bool ShowAllFunctions,
- bool ShowDetailedSummary,
- const std::string &ShowFunction,
- bool ShowProfileSymbolList,
- bool ShowSectionInfoOnly, bool ShowHotFuncList,
- ShowFormat SFormat, raw_fd_ostream &OS) {
+static int showSampleProfile(const std::string &Filename, ShowFormat SFormat,
+ raw_fd_ostream &OS) {
if (SFormat == ShowFormat::Yaml)
exitWithError("YAML output is not supported for sample profiles");
using namespace sampleprof;
@@ -2886,15 +2969,14 @@ static int showSampleProfile(const std::string &Filename, bool ShowCounts,
PS.printDetailedSummary(OS);
}
- if (ShowHotFuncList || TopN)
- showHotFunctionList(Reader->getProfiles(), Reader->getSummary(), TopN, OS);
+ if (ShowHotFuncList || TopNFunctions)
+ showHotFunctionList(Reader->getProfiles(), Reader->getSummary(),
+ TopNFunctions, OS);
return 0;
}
-static int showMemProfProfile(const std::string &Filename,
- const std::string &ProfiledBinary,
- ShowFormat SFormat, raw_fd_ostream &OS) {
+static int showMemProfProfile(const std::string &Filename, raw_fd_ostream &OS) {
if (SFormat == ShowFormat::Json)
exitWithError("JSON output is not supported for MemProf");
auto ReaderOr = llvm::memprof::RawMemProfReader::create(
@@ -2913,10 +2995,7 @@ static int showMemProfProfile(const std::string &Filename,
}
static int showDebugInfoCorrelation(const std::string &Filename,
- bool ShowDetailedSummary,
- bool ShowProfileSymbolList,
- int MaxDbgCorrelationWarnings,
- ShowFormat SFormat, raw_fd_ostream &OS) {
+ raw_fd_ostream &OS) {
if (SFormat == ShowFormat::Json)
exitWithError("JSON output is not supported for debug info correlation");
std::unique_ptr<InstrProfCorrelator> Correlator;
@@ -2950,101 +3029,8 @@ static int showDebugInfoCorrelation(const std::string &Filename,
return 0;
}
-static int show_main(int argc, const char *argv[]) {
- cl::opt<std::string> Filename(cl::Positional, cl::desc("<profdata-file>"));
-
- cl::opt<bool> ShowCounts("counts", cl::init(false),
- cl::desc("Show counter values for shown functions"));
- cl::opt<ShowFormat> SFormat(
- "show-format", cl::init(ShowFormat::Text),
- cl::desc("Emit output in the selected format if supported"),
- cl::values(clEnumValN(ShowFormat::Text, "text",
- "emit normal text output (default)"),
- clEnumValN(ShowFormat::Json, "json", "emit JSON"),
- clEnumValN(ShowFormat::Yaml, "yaml", "emit YAML")));
- // TODO: Consider replacing this with `--show-format=text-encoding`.
- cl::opt<bool> TextFormat(
- "text", cl::init(false),
- cl::desc("Show instr profile data in text dump format"));
- cl::opt<bool> JsonFormat(
- "json", cl::desc("Show sample profile data in the JSON format "
- "(deprecated, please use --show-format=json)"));
- cl::opt<bool> ShowIndirectCallTargets(
- "ic-targets", cl::init(false),
- cl::desc("Show indirect call site target values for shown functions"));
- cl::opt<bool> ShowMemOPSizes(
- "memop-sizes", cl::init(false),
- cl::desc("Show the profiled sizes of the memory intrinsic calls "
- "for shown functions"));
- cl::opt<bool> ShowDetailedSummary("detailed-summary", cl::init(false),
- cl::desc("Show detailed profile summary"));
- cl::list<uint32_t> DetailedSummaryCutoffs(
- cl::CommaSeparated, "detailed-summary-cutoffs",
- cl::desc(
- "Cutoff percentages (times 10000) for generating detailed summary"),
- cl::value_desc("800000,901000,999999"));
- cl::opt<bool> ShowHotFuncList(
- "hot-func-list", cl::init(false),
- cl::desc("Show profile summary of a list of hot functions"));
- cl::opt<bool> ShowAllFunctions("all-functions", cl::init(false),
- cl::desc("Details for every function"));
- cl::opt<bool> ShowCS("showcs", cl::init(false),
- cl::desc("Show context sensitive counts"));
- cl::opt<std::string> ShowFunction("function",
- cl::desc("Details for matching functions"));
-
- cl::opt<std::string> OutputFilename("output", cl::value_desc("output"),
- cl::init("-"), cl::desc("Output file"));
- cl::alias OutputFilenameA("o", cl::desc("Alias for --output"),
- cl::aliasopt(OutputFilename));
- cl::opt<ProfileKinds> ProfileKind(
- cl::desc("Profile kind:"), cl::init(instr),
- cl::values(clEnumVal(instr, "Instrumentation profile (default)"),
- clEnumVal(sample, "Sample profile"),
- clEnumVal(memory, "MemProf memory access profile")));
- cl::opt<uint32_t> TopNFunctions(
- "topn", cl::init(0),
- cl::desc("Show the list of functions with the largest internal counts"));
- cl::opt<uint32_t> ValueCutoff(
- "value-cutoff", cl::init(0),
- cl::desc("Set the count value cutoff. Functions with the maximum count "
- "less than this value will not be printed out. (Default is 0)"));
- cl::opt<bool> OnlyListBelow(
- "list-below-cutoff", cl::init(false),
- cl::desc("Only output names of functions whose max count values are "
- "below the cutoff value"));
- cl::opt<bool> ShowProfileSymbolList(
- "show-prof-sym-list", cl::init(false),
- cl::desc("Show profile symbol list if it exists in the profile. "));
- cl::opt<bool> ShowSectionInfoOnly(
- "show-sec-info-only", cl::init(false),
- cl::desc("Show the information of each section in the sample profile. "
- "The flag is only usable when the sample profile is in "
- "extbinary format"));
- cl::opt<bool> ShowBinaryIds("binary-ids", cl::init(false),
- cl::desc("Show binary ids in the profile. "));
- cl::opt<bool> ShowTemporalProfTraces(
- "temporal-profile-traces",
- cl::desc("Show temporal profile traces in the profile."));
- cl::opt<std::string> DebugInfoFilename(
- "debug-info", cl::init(""),
- cl::desc("Read and extract profile metadata from debug info and show "
- "the functions it found."));
- cl::opt<unsigned> MaxDbgCorrelationWarnings(
- "max-debug-info-correlation-warnings",
- cl::desc("The maximum number of warnings to emit when correlating "
- "profile from debug info (0 = no limit)"),
- cl::init(5));
- cl::opt<bool> ShowCovered(
- "covered", cl::init(false),
- cl::desc("Show only the functions that have been executed."));
- cl::opt<std::string> ProfiledBinary(
- "profiled-binary", cl::init(""),
- cl::desc("Path to binary from which the profile was collected."));
- cl::opt<bool> ShowProfileVersion("profile-version", cl::init(false),
- cl::desc("Show profile version. "));
+static int main(int argc, const char *argv[]) {
cl::ParseCommandLineOptions(argc, argv, "LLVM profile data summary\n");
-
if (Filename.empty() && DebugInfoFilename.empty())
exitWithError(
"the positional argument '<profdata-file>' is required unless '--" +
@@ -3067,25 +3053,17 @@ static int show_main(int argc, const char *argv[]) {
WithColor::warning() << "-function argument ignored: showing all functions\n";
if (!DebugInfoFilename.empty())
- return showDebugInfoCorrelation(DebugInfoFilename, ShowDetailedSummary,
- ShowProfileSymbolList,
- MaxDbgCorrelationWarnings, SFormat, OS);
+ return showDebugInfoCorrelation(DebugInfoFilename, OS);
if (ProfileKind == instr)
- return showInstrProfile(
- Filename, ShowCounts, TopNFunctions, ShowIndirectCallTargets,
- ShowMemOPSizes, ShowDetailedSummary, DetailedSummaryCutoffs,
- ShowAllFunctions, ShowCS, ValueCutoff, OnlyListBelow, ShowFunction,
- TextFormat, ShowBinaryIds, ShowCovered, ShowProfileVersion,
- ShowTemporalProfTraces, SFormat, OS);
+ return showInstrProfile(Filename, SFormat, OS);
if (ProfileKind == sample)
- return showSampleProfile(Filename, ShowCounts, TopNFunctions,
- ShowAllFunctions, ShowDetailedSummary,
- ShowFunction, ShowProfileSymbolList,
- ShowSectionInfoOnly, ShowHotFuncList, SFormat, OS);
- return showMemProfProfile(Filename, ProfiledBinary, SFormat, OS);
+ return showSampleProfile(Filename, SFormat, OS);
+ return showMemProfProfile(Filename, SFormat, OS);
}
+} // namespace show_llvmprofdata
+
static int order_main(int argc, const char *argv[]) {
cl::opt<std::string> Filename(cl::Positional, cl::desc("<profdata-file>"));
cl::opt<std::string> OutputFilename("output", cl::value_desc("output"),
@@ -3130,7 +3108,7 @@ typedef int (*llvm_profdata_subcommand)(int, const char *[]);
static std::tuple<StringRef, llvm_profdata_subcommand>
llvm_profdata_subcommands[] = {
{"merge", merge_main},
- {"show", show_main},
+ {"show", show_llvmprofdata::main},
{"order", order_main},
{"overlap", overlap_main},
};
>From 02a0de693395c5de06678acf54d52b9e3af2477c Mon Sep 17 00:00:00 2001
From: Mingming Liu <mingmingl at google.com>
Date: Tue, 7 Nov 2023 17:52:18 -0800
Subject: [PATCH 2/2] Add show_options namespace and move show_options from
function scope to namespace. - The change uses cl::SubCommand feature that
allow to register options under a subcommand. - Without using
cl::SubCommand, the options in the show name namespace will take a
registered name as global variables, causing runtime errors when a
function-scope static option tries to add a function of a same name. - Make
changes in the CommandLine library accordingly.
---
llvm/include/llvm/Support/CommandLine.h | 2 +-
llvm/lib/Support/CommandLine.cpp | 7 +
llvm/tools/llvm-profdata/llvm-profdata.cpp | 293 +++++++++++++--------
3 files changed, 185 insertions(+), 117 deletions(-)
diff --git a/llvm/include/llvm/Support/CommandLine.h b/llvm/include/llvm/Support/CommandLine.h
index 58ef176551b6852..ab62607b2a307e5 100644
--- a/llvm/include/llvm/Support/CommandLine.h
+++ b/llvm/include/llvm/Support/CommandLine.h
@@ -481,7 +481,7 @@ struct sub {
sub(SubCommand &S) : Sub(S) {}
- template <class Opt> void apply(Opt &O) const { O.addSubCommand(Sub); }
+ void apply(Option &O) const { O.addSubCommand(Sub); }
};
// Specify a callback function to be called when an option is seen.
diff --git a/llvm/lib/Support/CommandLine.cpp b/llvm/lib/Support/CommandLine.cpp
index 55633d7cafa4791..a7e0cae8b855d7c 100644
--- a/llvm/lib/Support/CommandLine.cpp
+++ b/llvm/lib/Support/CommandLine.cpp
@@ -1667,6 +1667,13 @@ bool CommandLineParser::ParseCommandLineOptions(int argc,
Handler = LookupLongOption(*ChosenSubCommand, ArgName, Value,
LongOptionsUseDoubleDash, HaveDoubleDash);
+ // If Handler is not found in a specialized subcommand, look up handler
+ // in the top-level subcommand.
+ // cl::opt without cl::sub belongs to top-level subcommand.
+ if (!Handler && ChosenSubCommand != &SubCommand::getTopLevel())
+ Handler = LookupLongOption(SubCommand::getTopLevel(), ArgName, Value,
+ LongOptionsUseDoubleDash, HaveDoubleDash);
+
// Check to see if this "option" is really a prefixed or grouped argument.
if (!Handler && !(LongOptionsUseDoubleDash && HaveDoubleDash))
Handler = HandlePrefixedOrGroupedOption(ArgName, Value, ErrorParsing,
diff --git a/llvm/tools/llvm-profdata/llvm-profdata.cpp b/llvm/tools/llvm-profdata/llvm-profdata.cpp
index f8e6bf5dd9b99e5..fd00798b8bc959e 100644
--- a/llvm/tools/llvm-profdata/llvm-profdata.cpp
+++ b/llvm/tools/llvm-profdata/llvm-profdata.cpp
@@ -47,6 +47,8 @@
using namespace llvm;
+cl::SubCommand ShowSubcommand("show", "show profile data");
+
// We use this string to indicate that there are
// multiple static functions map to the same name.
const std::string DuplicateNameStr = "----";
@@ -2387,7 +2389,6 @@ static int overlap_main(int argc, const char *argv[]) {
return 0;
}
-namespace show_llvmprofdata {
namespace {
struct ValueSitesStats {
ValueSitesStats()
@@ -2448,101 +2449,14 @@ static void showValueSitesStats(raw_fd_ostream &OS, uint32_t VK,
}
}
-cl::opt<std::string> Filename(cl::Positional, cl::desc("<profdata-file>"));
-
-cl::opt<bool> ShowCounts("counts", cl::init(false),
- cl::desc("Show counter values for shown functions"));
-cl::opt<ShowFormat>
- SFormat("show-format", cl::init(ShowFormat::Text),
- cl::desc("Emit output in the selected format if supported"),
- cl::values(clEnumValN(ShowFormat::Text, "text",
- "emit normal text output (default)"),
- clEnumValN(ShowFormat::Json, "json", "emit JSON"),
- clEnumValN(ShowFormat::Yaml, "yaml", "emit YAML")));
-// TODO: Consider replacing this with `--show-format=text-encoding`.
-cl::opt<bool>
- TextFormat("text", cl::init(false),
- cl::desc("Show instr profile data in text dump format"));
-cl::opt<bool>
- JsonFormat("json", cl::desc("Show sample profile data in the JSON format "
- "(deprecated, please use --show-format=json)"));
-cl::opt<bool> ShowIndirectCallTargets(
- "ic-targets", cl::init(false),
- cl::desc("Show indirect call site target values for shown functions"));
-cl::opt<bool> ShowMemOPSizes(
- "memop-sizes", cl::init(false),
- cl::desc("Show the profiled sizes of the memory intrinsic calls "
- "for shown functions"));
-cl::opt<bool> ShowDetailedSummary("detailed-summary", cl::init(false),
- cl::desc("Show detailed profile summary"));
-cl::list<uint32_t> DetailedSummaryCutoffs(
- cl::CommaSeparated, "detailed-summary-cutoffs",
- cl::desc(
- "Cutoff percentages (times 10000) for generating detailed summary"),
- cl::value_desc("800000,901000,999999"));
-cl::opt<bool> ShowHotFuncList(
- "hot-func-list", cl::init(false),
- cl::desc("Show profile summary of a list of hot functions"));
-cl::opt<bool> ShowAllFunctions("all-functions", cl::init(false),
- cl::desc("Details for every function"));
-cl::opt<bool> ShowCS("showcs", cl::init(false),
- cl::desc("Show context sensitive counts"));
-cl::opt<std::string> ShowFunction("function",
- cl::desc("Details for matching functions"));
-
-cl::opt<std::string> OutputFilename("output", cl::value_desc("output"),
- cl::init("-"), cl::desc("Output file"));
-cl::alias OutputFilenameA("o", cl::desc("Alias for --output"),
- cl::aliasopt(OutputFilename));
-cl::opt<ProfileKinds> ProfileKind(
- cl::desc("Profile kind:"), cl::init(instr),
- cl::values(clEnumVal(instr, "Instrumentation profile (default)"),
- clEnumVal(sample, "Sample profile"),
- clEnumVal(memory, "MemProf memory access profile")));
-cl::opt<uint32_t> TopNFunctions(
- "topn", cl::init(0),
- cl::desc("Show the list of functions with the largest internal counts"));
-cl::opt<uint32_t> ValueCutoff(
- "value-cutoff", cl::init(0),
- cl::desc("Set the count value cutoff. Functions with the maximum count "
- "less than this value will not be printed out. (Default is 0)"));
-cl::opt<bool> OnlyListBelow(
- "list-below-cutoff", cl::init(false),
- cl::desc("Only output names of functions whose max count values are "
- "below the cutoff value"));
-cl::opt<bool> ShowProfileSymbolList(
- "show-prof-sym-list", cl::init(false),
- cl::desc("Show profile symbol list if it exists in the profile. "));
-cl::opt<bool> ShowSectionInfoOnly(
- "show-sec-info-only", cl::init(false),
- cl::desc("Show the information of each section in the sample profile. "
- "The flag is only usable when the sample profile is in "
- "extbinary format"));
-cl::opt<bool> ShowBinaryIds("binary-ids", cl::init(false),
- cl::desc("Show binary ids in the profile. "));
-cl::opt<bool> ShowTemporalProfTraces(
- "temporal-profile-traces",
- cl::desc("Show temporal profile traces in the profile."));
-cl::opt<std::string> DebugInfoFilename(
- "debug-info", cl::init(""),
- cl::desc("Read and extract profile metadata from debug info and show "
- "the functions it found."));
-cl::opt<unsigned> MaxDbgCorrelationWarnings(
- "max-debug-info-correlation-warnings",
- cl::desc("The maximum number of warnings to emit when correlating "
- "profile from debug info (0 = no limit)"),
- cl::init(5));
-cl::opt<bool>
- ShowCovered("covered", cl::init(false),
- cl::desc("Show only the functions that have been executed."));
-cl::opt<std::string> ProfiledBinary(
- "profiled-binary", cl::init(""),
- cl::desc("Path to binary from which the profile was collected."));
-cl::opt<bool> ShowProfileVersion("profile-version", cl::init(false),
- cl::desc("Show profile version. "));
-
-static int showInstrProfile(const std::string &Filename, ShowFormat SFormat,
- raw_fd_ostream &OS) {
+static int showInstrProfile(
+ const std::string &Filename, bool ShowCounts, uint32_t TopN,
+ bool ShowIndirectCallTargets, bool ShowMemOPSizes, bool ShowDetailedSummary,
+ std::vector<uint32_t> DetailedSummaryCutoffs, bool ShowAllFunctions,
+ bool ShowCS, uint64_t ValueCutoff, bool OnlyListBelow,
+ const std::string &ShowFunction, bool TextFormat, bool ShowBinaryIds,
+ bool ShowCovered, bool ShowProfileVersion, bool ShowTemporalProfTraces,
+ ShowFormat SFormat, raw_fd_ostream &OS) {
if (SFormat == ShowFormat::Json)
exitWithError("JSON output is not supported for instr profiles");
if (SFormat == ShowFormat::Yaml)
@@ -2647,8 +2561,8 @@ static int showInstrProfile(const std::string &Filename, ShowFormat SFormat,
} else if (OnlyListBelow)
continue;
- if (TopNFunctions) {
- if (HottestFuncs.size() == TopNFunctions) {
+ if (TopN) {
+ if (HottestFuncs.size() == TopN) {
if (HottestFuncs.top().second < FuncMax) {
HottestFuncs.pop();
HottestFuncs.emplace(std::make_pair(std::string(Func.Name), FuncMax));
@@ -2724,13 +2638,13 @@ static int showInstrProfile(const std::string &Filename, ShowFormat SFormat,
OS << "Maximum function count: " << PS->getMaxFunctionCount() << "\n";
OS << "Maximum internal block count: " << PS->getMaxInternalCount() << "\n";
- if (TopNFunctions) {
+ if (TopN) {
std::vector<std::pair<std::string, uint64_t>> SortedHottestFuncs;
while (!HottestFuncs.empty()) {
SortedHottestFuncs.emplace_back(HottestFuncs.top());
HottestFuncs.pop();
}
- OS << "Top " << TopNFunctions
+ 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";
@@ -2920,8 +2834,13 @@ static int showHotFunctionList(const sampleprof::SampleProfileMap &Profiles,
return 0;
}
-static int showSampleProfile(const std::string &Filename, ShowFormat SFormat,
- raw_fd_ostream &OS) {
+static int showSampleProfile(const std::string &Filename, bool ShowCounts,
+ uint32_t TopN, bool ShowAllFunctions,
+ bool ShowDetailedSummary,
+ const std::string &ShowFunction,
+ bool ShowProfileSymbolList,
+ bool ShowSectionInfoOnly, bool ShowHotFuncList,
+ ShowFormat SFormat, raw_fd_ostream &OS) {
if (SFormat == ShowFormat::Yaml)
exitWithError("YAML output is not supported for sample profiles");
using namespace sampleprof;
@@ -2969,14 +2888,15 @@ static int showSampleProfile(const std::string &Filename, ShowFormat SFormat,
PS.printDetailedSummary(OS);
}
- if (ShowHotFuncList || TopNFunctions)
- showHotFunctionList(Reader->getProfiles(), Reader->getSummary(),
- TopNFunctions, OS);
+ if (ShowHotFuncList || TopN)
+ showHotFunctionList(Reader->getProfiles(), Reader->getSummary(), TopN, OS);
return 0;
}
-static int showMemProfProfile(const std::string &Filename, raw_fd_ostream &OS) {
+static int showMemProfProfile(const std::string &Filename,
+ const std::string &ProfiledBinary,
+ ShowFormat SFormat, raw_fd_ostream &OS) {
if (SFormat == ShowFormat::Json)
exitWithError("JSON output is not supported for MemProf");
auto ReaderOr = llvm::memprof::RawMemProfReader::create(
@@ -2995,7 +2915,10 @@ static int showMemProfProfile(const std::string &Filename, raw_fd_ostream &OS) {
}
static int showDebugInfoCorrelation(const std::string &Filename,
- raw_fd_ostream &OS) {
+ bool ShowDetailedSummary,
+ bool ShowProfileSymbolList,
+ int MaxDbgCorrelationWarnings,
+ ShowFormat SFormat, raw_fd_ostream &OS) {
if (SFormat == ShowFormat::Json)
exitWithError("JSON output is not supported for debug info correlation");
std::unique_ptr<InstrProfCorrelator> Correlator;
@@ -3029,15 +2952,139 @@ static int showDebugInfoCorrelation(const std::string &Filename,
return 0;
}
-static int main(int argc, const char *argv[]) {
+namespace show_options {
+cl::opt<std::string> Filename(cl::Positional, cl::desc("<profdata-file>"),
+ cl::sub(ShowSubcommand));
+
+cl::opt<bool> ShowCounts("counts", cl::init(false),
+ cl::desc("Show counter values for shown functions"),
+ cl::sub(ShowSubcommand));
+cl::opt<ShowFormat>
+ SFormat("show-format", cl::init(ShowFormat::Text),
+ cl::desc("Emit output in the selected format if supported"),
+ cl::values(clEnumValN(ShowFormat::Text, "text",
+ "emit normal text output (default)"),
+ clEnumValN(ShowFormat::Json, "json", "emit JSON"),
+ clEnumValN(ShowFormat::Yaml, "yaml", "emit YAML")),
+ cl::sub(ShowSubcommand));
+// TODO: Consider replacing this with `--show-format=text-encoding`.
+cl::opt<bool>
+ TextFormat("text", cl::init(false),
+ cl::desc("Show instr profile data in text dump format"),
+ cl::sub(ShowSubcommand));
+cl::opt<bool>
+ JsonFormat("json",
+ cl::desc("Show sample profile data in the JSON format "
+ "(deprecated, please use --show-format=json)"),
+ cl::sub(ShowSubcommand));
+cl::opt<bool> ShowIndirectCallTargets(
+ "ic-targets", cl::init(false),
+ cl::desc("Show indirect call site target values for shown functions"),
+ cl::sub(ShowSubcommand));
+cl::opt<bool> ShowMemOPSizes(
+ "memop-sizes", cl::init(false),
+ cl::desc("Show the profiled sizes of the memory intrinsic calls "
+ "for shown functions"),
+ cl::sub(ShowSubcommand));
+cl::opt<bool> ShowDetailedSummary("detailed-summary", cl::init(false),
+ cl::desc("Show detailed profile summary"),
+ cl::sub(ShowSubcommand));
+cl::list<uint32_t> DetailedSummaryCutoffs(
+ cl::CommaSeparated, "detailed-summary-cutoffs",
+ cl::desc(
+ "Cutoff percentages (times 10000) for generating detailed summary"),
+ cl::value_desc("800000,901000,999999"), cl::sub(ShowSubcommand));
+cl::opt<bool>
+ ShowHotFuncList("hot-func-list", cl::init(false),
+ cl::desc("Show profile summary of a list of hot functions"),
+ cl::sub(ShowSubcommand));
+cl::opt<bool> ShowAllFunctions("all-functions", cl::init(false),
+ cl::desc("Details for each and every function"),
+ cl::sub(ShowSubcommand));
+cl::opt<bool> ShowCS("showcs", cl::init(false),
+ cl::desc("Show context sensitive counts"),
+ cl::sub(ShowSubcommand));
+cl::opt<std::string> ShowFunction("function",
+ cl::desc("Details for matching functions"),
+ cl::sub(ShowSubcommand));
+
+cl::opt<std::string> OutputFilename("output", cl::value_desc("output"),
+ cl::init("-"), cl::desc("Output file"),
+ cl::sub(ShowSubcommand));
+// NOTE: cl::alias must not have cl::sub(), since aliased option's cl::sub()
+// will be used. llvm::cl::alias::done() method asserts this condition.
+cl::alias OutputFilenameA("o", cl::desc("Alias for --output"),
+ cl::aliasopt(OutputFilename));
+cl::opt<ProfileKinds> ProfileKind(
+ cl::desc("Profile kind:"), cl::sub(ShowSubcommand), cl::init(instr),
+ cl::values(clEnumVal(instr, "Instrumentation profile (default)"),
+ clEnumVal(sample, "Sample profile"),
+ clEnumVal(memory, "MemProf memory access profile")));
+cl::opt<uint32_t> TopNFunctions(
+ "topn", cl::init(0),
+ cl::desc("Show the list of functions with the largest internal counts"),
+ cl::sub(ShowSubcommand));
+cl::opt<uint32_t> ValueCutoff(
+ "value-cutoff", cl::init(0),
+ cl::desc("Set the count value cutoff. Functions with the maximum count "
+ "less than this value will not be printed out. (Default is 0)"),
+ cl::sub(ShowSubcommand));
+cl::opt<bool> OnlyListBelow(
+ "list-below-cutoff", cl::init(false),
+ cl::desc("Only output names of functions whose max count values are "
+ "below the cutoff value"),
+ cl::sub(ShowSubcommand));
+cl::opt<bool> ShowProfileSymbolList(
+ "show-prof-sym-list", cl::init(false),
+ cl::desc("Show profile symbol list if it exists in the profile. "),
+ cl::sub(ShowSubcommand));
+cl::opt<bool> ShowSectionInfoOnly(
+ "show-sec-info-only", cl::init(false),
+ cl::desc("Show the information of each section in the sample profile. "
+ "The flag is only usable when the sample profile is in "
+ "extbinary format"),
+ cl::sub(ShowSubcommand));
+cl::opt<bool> ShowBinaryIds("binary-ids", cl::init(false),
+ cl::desc("Show binary ids in the profile. "),
+ cl::sub(ShowSubcommand));
+cl::opt<bool> ShowTemporalProfTraces(
+ "temporal-profile-traces",
+ cl::desc("Show temporal profile traces in the profile."),
+ cl::sub(ShowSubcommand));
+cl::opt<std::string> DebugInfoFilename(
+ "debug-info", cl::init(""),
+ cl::desc("Read and extract profile metadata from debug info and show "
+ "the functions it found."),
+ cl::sub(ShowSubcommand));
+cl::opt<unsigned> MaxDbgCorrelationWarnings(
+ "max-debug-info-correlation-warnings",
+ cl::desc("The maximum number of warnings to emit when correlating "
+ "profile from debug info (0 = no limit)"),
+ cl::init(5), cl::sub(ShowSubcommand));
+cl::opt<bool>
+ ShowCovered("covered", cl::init(false),
+ cl::desc("Show only the functions that have been executed."),
+ cl::sub(ShowSubcommand));
+cl::opt<std::string> ProfiledBinary(
+ "profiled-binary", cl::init(""),
+ cl::desc("Path to binary from which the profile was collected."),
+ cl::sub(ShowSubcommand));
+cl::opt<bool> ShowProfileVersion("profile-version", cl::init(false),
+ cl::desc("Show profile version. "),
+ cl::sub(ShowSubcommand));
+} // namespace show_options
+
+static int show_main(int argc, const char *argv[]) {
+ using namespace show_options;
cl::ParseCommandLineOptions(argc, argv, "LLVM profile data summary\n");
+
if (Filename.empty() && DebugInfoFilename.empty())
exitWithError(
"the positional argument '<profdata-file>' is required unless '--" +
DebugInfoFilename.ArgStr + "' is provided");
if (Filename == OutputFilename) {
- errs() << sys::path::filename(argv[0])
+ errs() << sys::path::filename(argv[0]) << " " << argv[1]
<< ": Input file name cannot be the same as the output file name!\n";
return 1;
}
@@ -3053,17 +3100,25 @@ static int main(int argc, const char *argv[]) {
WithColor::warning() << "-function argument ignored: showing all functions\n";
if (!DebugInfoFilename.empty())
- return showDebugInfoCorrelation(DebugInfoFilename, OS);
+ return showDebugInfoCorrelation(DebugInfoFilename, ShowDetailedSummary,
+ ShowProfileSymbolList,
+ MaxDbgCorrelationWarnings, SFormat, OS);
if (ProfileKind == instr)
- return showInstrProfile(Filename, SFormat, OS);
+ return showInstrProfile(
+ Filename, ShowCounts, TopNFunctions, ShowIndirectCallTargets,
+ ShowMemOPSizes, ShowDetailedSummary, DetailedSummaryCutoffs,
+ ShowAllFunctions, ShowCS, ValueCutoff, OnlyListBelow, ShowFunction,
+ TextFormat, ShowBinaryIds, ShowCovered, ShowProfileVersion,
+ ShowTemporalProfTraces, SFormat, OS);
if (ProfileKind == sample)
- return showSampleProfile(Filename, SFormat, OS);
- return showMemProfProfile(Filename, SFormat, OS);
+ return showSampleProfile(Filename, ShowCounts, TopNFunctions,
+ ShowAllFunctions, ShowDetailedSummary,
+ ShowFunction, ShowProfileSymbolList,
+ ShowSectionInfoOnly, ShowHotFuncList, SFormat, OS);
+ return showMemProfProfile(Filename, ProfiledBinary, SFormat, OS);
}
-} // namespace show_llvmprofdata
-
static int order_main(int argc, const char *argv[]) {
cl::opt<std::string> Filename(cl::Positional, cl::desc("<profdata-file>"));
cl::opt<std::string> OutputFilename("output", cl::value_desc("output"),
@@ -3108,7 +3163,6 @@ typedef int (*llvm_profdata_subcommand)(int, const char *[]);
static std::tuple<StringRef, llvm_profdata_subcommand>
llvm_profdata_subcommands[] = {
{"merge", merge_main},
- {"show", show_llvmprofdata::main},
{"order", order_main},
{"overlap", overlap_main},
};
@@ -3132,6 +3186,13 @@ int llvm_profdata_main(int argc, char **argvNonConst,
return func(argc - 1, argv + 1);
}
+ // "show" subcommand and its options uses the subcommands supported by
+ // llvm::cl. See this post
+ // (https://lists.llvm.org/pipermail/llvm-dev/2016-June/101804.html) for
+ // a brief introduction.
+ if (strcmp(argv[1], "show") == 0)
+ return show_main(argc, argv);
+
if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "-help") == 0 ||
strcmp(argv[1], "--help") == 0) {
More information about the llvm-commits
mailing list