Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion llvm/include/llvm/Support/CommandLine.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
7 changes: 7 additions & 0 deletions llvm/lib/Support/CommandLine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
227 changes: 133 additions & 94 deletions llvm/tools/llvm-profdata/llvm-profdata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 = "----";
Expand Down Expand Up @@ -2950,99 +2952,130 @@ 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"));
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

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 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())
Expand All @@ -3051,7 +3084,7 @@ static int show_main(int argc, const char *argv[]) {
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;
}
Expand Down Expand Up @@ -3130,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_main},
{"order", order_main},
{"overlap", overlap_main},
};
Expand All @@ -3154,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) {

Expand Down