diff --git a/llvm/tools/llvm-profdata/llvm-profdata.cpp b/llvm/tools/llvm-profdata/llvm-profdata.cpp index e7e7f8228d7d9..f8e6bf5dd9b99 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 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 Filename(cl::Positional, cl::desc("")); + +cl::opt ShowCounts("counts", cl::init(false), + cl::desc("Show counter values for shown functions")); +cl::opt + 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 + TextFormat("text", cl::init(false), + cl::desc("Show instr profile data in text dump format")); +cl::opt + JsonFormat("json", cl::desc("Show sample profile data in the JSON format " + "(deprecated, please use --show-format=json)")); +cl::opt ShowIndirectCallTargets( + "ic-targets", cl::init(false), + cl::desc("Show indirect call site target values for shown functions")); +cl::opt ShowMemOPSizes( + "memop-sizes", cl::init(false), + cl::desc("Show the profiled sizes of the memory intrinsic calls " + "for shown functions")); +cl::opt ShowDetailedSummary("detailed-summary", cl::init(false), + cl::desc("Show detailed profile summary")); +cl::list DetailedSummaryCutoffs( + cl::CommaSeparated, "detailed-summary-cutoffs", + cl::desc( + "Cutoff percentages (times 10000) for generating detailed summary"), + cl::value_desc("800000,901000,999999")); +cl::opt ShowHotFuncList( + "hot-func-list", cl::init(false), + cl::desc("Show profile summary of a list of hot functions")); +cl::opt ShowAllFunctions("all-functions", cl::init(false), + cl::desc("Details for every function")); +cl::opt ShowCS("showcs", cl::init(false), + cl::desc("Show context sensitive counts")); +cl::opt ShowFunction("function", + cl::desc("Details for matching functions")); + +cl::opt 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 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 TopNFunctions( + "topn", cl::init(0), + cl::desc("Show the list of functions with the largest internal counts")); +cl::opt 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 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 ShowProfileSymbolList( + "show-prof-sym-list", cl::init(false), + cl::desc("Show profile symbol list if it exists in the profile. ")); +cl::opt 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 ShowBinaryIds("binary-ids", cl::init(false), + cl::desc("Show binary ids in the profile. ")); +cl::opt ShowTemporalProfTraces( + "temporal-profile-traces", + cl::desc("Show temporal profile traces in the profile.")); +cl::opt DebugInfoFilename( + "debug-info", cl::init(""), + cl::desc("Read and extract profile metadata from debug info and show " + "the functions it found.")); +cl::opt 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 + ShowCovered("covered", cl::init(false), + cl::desc("Show only the functions that have been executed.")); +cl::opt ProfiledBinary( + "profiled-binary", cl::init(""), + cl::desc("Path to binary from which the profile was collected.")); +cl::opt 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> 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 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 Filename(cl::Positional, cl::desc("")); - - cl::opt ShowCounts("counts", cl::init(false), - cl::desc("Show counter values for shown functions")); - cl::opt 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 TextFormat( - "text", cl::init(false), - cl::desc("Show instr profile data in text dump format")); - cl::opt JsonFormat( - "json", cl::desc("Show sample profile data in the JSON format " - "(deprecated, please use --show-format=json)")); - cl::opt ShowIndirectCallTargets( - "ic-targets", cl::init(false), - cl::desc("Show indirect call site target values for shown functions")); - cl::opt ShowMemOPSizes( - "memop-sizes", cl::init(false), - cl::desc("Show the profiled sizes of the memory intrinsic calls " - "for shown functions")); - cl::opt ShowDetailedSummary("detailed-summary", cl::init(false), - cl::desc("Show detailed profile summary")); - cl::list DetailedSummaryCutoffs( - cl::CommaSeparated, "detailed-summary-cutoffs", - cl::desc( - "Cutoff percentages (times 10000) for generating detailed summary"), - cl::value_desc("800000,901000,999999")); - cl::opt ShowHotFuncList( - "hot-func-list", cl::init(false), - cl::desc("Show profile summary of a list of hot functions")); - cl::opt ShowAllFunctions("all-functions", cl::init(false), - cl::desc("Details for every function")); - cl::opt ShowCS("showcs", cl::init(false), - cl::desc("Show context sensitive counts")); - cl::opt ShowFunction("function", - cl::desc("Details for matching functions")); - - cl::opt 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 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 TopNFunctions( - "topn", cl::init(0), - cl::desc("Show the list of functions with the largest internal counts")); - cl::opt 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 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 ShowProfileSymbolList( - "show-prof-sym-list", cl::init(false), - cl::desc("Show profile symbol list if it exists in the profile. ")); - cl::opt 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 ShowBinaryIds("binary-ids", cl::init(false), - cl::desc("Show binary ids in the profile. ")); - cl::opt ShowTemporalProfTraces( - "temporal-profile-traces", - cl::desc("Show temporal profile traces in the profile.")); - cl::opt DebugInfoFilename( - "debug-info", cl::init(""), - cl::desc("Read and extract profile metadata from debug info and show " - "the functions it found.")); - cl::opt 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 ShowCovered( - "covered", cl::init(false), - cl::desc("Show only the functions that have been executed.")); - cl::opt ProfiledBinary( - "profiled-binary", cl::init(""), - cl::desc("Path to binary from which the profile was collected.")); - cl::opt 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 '' 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 Filename(cl::Positional, cl::desc("")); cl::opt OutputFilename("output", cl::value_desc("output"), @@ -3130,7 +3108,7 @@ typedef int (*llvm_profdata_subcommand)(int, const char *[]); static std::tuple llvm_profdata_subcommands[] = { {"merge", merge_main}, - {"show", show_main}, + {"show", show_llvmprofdata::main}, {"order", order_main}, {"overlap", overlap_main}, };