[llvm] r253913 - [PGO] Add --text option for llvm-profdata show|merge commands
Xinliang David Li via llvm-commits
llvm-commits at lists.llvm.org
Mon Nov 23 12:47:39 PST 2015
Author: davidxl
Date: Mon Nov 23 14:47:38 2015
New Revision: 253913
URL: http://llvm.org/viewvc/llvm-project?rev=253913&view=rev
Log:
[PGO] Add --text option for llvm-profdata show|merge commands
The new option is similar to the SampleProfile dump option.
- dump raw/indexed format into text profile format
- merge the profile and output into text profile format.
Note that Value Profiling data text format is not yet designed.
That functionality will be added later.
Differential Revision: http://reviews.llvm.org/D14894
Added:
llvm/trunk/test/tools/llvm-profdata/Inputs/basic.proftext
llvm/trunk/test/tools/llvm-profdata/text-dump.test
Modified:
llvm/trunk/docs/CommandGuide/llvm-profdata.rst
llvm/trunk/include/llvm/ProfileData/InstrProfWriter.h
llvm/trunk/lib/ProfileData/InstrProfWriter.cpp
llvm/trunk/tools/llvm-profdata/llvm-profdata.cpp
Modified: llvm/trunk/docs/CommandGuide/llvm-profdata.rst
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/CommandGuide/llvm-profdata.rst?rev=253913&r1=253912&r2=253913&view=diff
==============================================================================
--- llvm/trunk/docs/CommandGuide/llvm-profdata.rst (original)
+++ llvm/trunk/docs/CommandGuide/llvm-profdata.rst Mon Nov 23 14:47:38 2015
@@ -51,7 +51,17 @@ OPTIONS
.. option:: -instr (default)
- Specify that the input profile is an instrumentation-based profile.
+ Specify that the input profile is an instrumentation-based profile. When
+ using instrumentation-based profiles, the format of the generated file
+ can be generated in one of the two ways:
+
+ .. option:: -binary (default)
+
+ Emit the profile using a binary encoding in indexed profile format.
+
+ .. option:: -text
+
+ Emit the profile in text format.
.. option:: -sample
@@ -121,6 +131,13 @@ OPTIONS
Specify that the input profile is an instrumentation-based profile.
+.. option:: -text
+
+ Instruct the profile dumper to show profile counts in the text format of the
+ instrumentation-based profile data representation. By default, the profile
+ information is dumped in a more human readable form (also in text) with
+ annotations.
+
.. option:: -sample
Specify that the input profile is a sample-based profile.
Modified: llvm/trunk/include/llvm/ProfileData/InstrProfWriter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ProfileData/InstrProfWriter.h?rev=253913&r1=253912&r2=253913&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ProfileData/InstrProfWriter.h (original)
+++ llvm/trunk/include/llvm/ProfileData/InstrProfWriter.h Mon Nov 23 14:47:38 2015
@@ -43,6 +43,11 @@ public:
std::error_code addRecord(InstrProfRecord &&I);
/// Write the profile to \c OS
void write(raw_fd_ostream &OS);
+ /// Write the profile in text format to \c OS
+ void writeText(raw_fd_ostream &OS);
+ /// Write \c Record in text format to \c OS
+ static void writeRecordInText(const InstrProfRecord &Record,
+ raw_fd_ostream &OS);
/// Write the profile, returning the raw data. For testing.
std::unique_ptr<MemoryBuffer> writeBuffer();
Modified: llvm/trunk/lib/ProfileData/InstrProfWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ProfileData/InstrProfWriter.cpp?rev=253913&r1=253912&r2=253913&view=diff
==============================================================================
--- llvm/trunk/lib/ProfileData/InstrProfWriter.cpp (original)
+++ llvm/trunk/lib/ProfileData/InstrProfWriter.cpp Mon Nov 23 14:47:38 2015
@@ -171,6 +171,21 @@ void InstrProfWriter::write(raw_fd_ostre
endian::Writer<little>(OS).write<uint64_t>(TableStart.second);
}
+void InstrProfWriter::writeRecordInText(const InstrProfRecord &Func,
+ raw_fd_ostream &OS) {
+ OS << Func.Name << "\n" << Func.Hash << "\n" << Func.Counts.size() << "\n";
+ for (uint64_t Count : Func.Counts)
+ OS << Count << "\n";
+
+ OS << "\n";
+}
+
+void InstrProfWriter::writeText(raw_fd_ostream &OS) {
+ for (const auto &I : FunctionData)
+ for (const auto &Func : I.getValue())
+ writeRecordInText(Func.second, OS);
+}
+
std::unique_ptr<MemoryBuffer> InstrProfWriter::writeBuffer() {
std::string Data;
llvm::raw_string_ostream OS(Data);
Added: llvm/trunk/test/tools/llvm-profdata/Inputs/basic.proftext
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-profdata/Inputs/basic.proftext?rev=253913&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-profdata/Inputs/basic.proftext (added)
+++ llvm/trunk/test/tools/llvm-profdata/Inputs/basic.proftext Mon Nov 23 14:47:38 2015
@@ -0,0 +1,40 @@
+foo
+10
+2
+499500
+179900
+
+main
+16650
+4
+1
+1000
+1000000
+499500
+
+foo2
+10
+2
+500500
+180100
+
+foo
+10
+2
+499500
+179900
+
+main
+16650
+4
+1
+1000
+1000000
+499500
+
+foo2
+10
+2
+500500
+180100
+
Added: llvm/trunk/test/tools/llvm-profdata/text-dump.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-profdata/text-dump.test?rev=253913&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-profdata/text-dump.test (added)
+++ llvm/trunk/test/tools/llvm-profdata/text-dump.test Mon Nov 23 14:47:38 2015
@@ -0,0 +1,21 @@
+Basic tests for testing text dump functions.
+
+RUN: llvm-profdata show --all-functions -counts --text %p/Inputs/basic.proftext > %t-basic.proftext1
+RUN: llvm-profdata merge -o %t-basic.proftext2 --text %p/Inputs/basic.proftext
+
+RUN: llvm-profdata merge -binary -o %t-basic.profdata1 %t-basic.proftext1
+RUN: llvm-profdata merge -o %t-basic.profdata2 %t-basic.proftext2
+
+RUN: llvm-profdata show --all-functions -counts %t-basic.profdata1 > %t-basic.dump3
+RUN: llvm-profdata show --all-functions -counts %t-basic.profdata2 > %t-basic.dump4
+
+RUN: llvm-profdata merge -text -o %t-basic.proftext5 %t-basic.profdata1
+RUN: llvm-profdata merge -text -o %t-basic.proftext6 %t-basic.profdata2
+
+RUN: diff %t-basic.dump3 %t-basic.dump4
+RUN: diff %t-basic.proftext5 %t-basic.proftext6
+
+RUN: not llvm-profdata merge -gcc -o %t-basic-profdata3 %t-basic.proftext2 2>&1 | FileCheck %s --check-prefix=UNKNOWN
+UNKNOWN: Unknown
+
+
Modified: llvm/trunk/tools/llvm-profdata/llvm-profdata.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-profdata/llvm-profdata.cpp?rev=253913&r1=253912&r2=253913&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-profdata/llvm-profdata.cpp (original)
+++ llvm/trunk/tools/llvm-profdata/llvm-profdata.cpp Mon Nov 23 14:47:38 2015
@@ -30,6 +30,8 @@
using namespace llvm;
+enum ProfileFormat { PF_None = 0, PF_Text, PF_Binary, PF_GCC };
+
static void exitWithError(const Twine &Message,
StringRef Whence = "",
StringRef Hint = "") {
@@ -92,10 +94,14 @@ static void handleMergeWriterError(std::
}
static void mergeInstrProfile(const cl::list<std::string> &Inputs,
- StringRef OutputFilename) {
+ StringRef OutputFilename,
+ ProfileFormat OutputFormat) {
if (OutputFilename.compare("-") == 0)
exitWithError("Cannot write indexed profdata format to stdout.");
+ if (OutputFormat != PF_Binary && OutputFormat != PF_Text)
+ exitWithError("Unknown format is specified.");
+
std::error_code EC;
raw_fd_ostream Output(OutputFilename.data(), EC, sys::fs::F_None);
if (EC)
@@ -119,14 +125,22 @@ static void mergeInstrProfile(const cl::
if (Reader->hasError())
exitWithErrorCode(Reader->getError(), Filename);
}
- Writer.write(Output);
+ if (OutputFormat == PF_Text)
+ Writer.writeText(Output);
+ else
+ Writer.write(Output);
}
+static sampleprof::SampleProfileFormat FormatMap[] = {
+ sampleprof::SPF_None, sampleprof::SPF_Text, sampleprof::SPF_Binary,
+ sampleprof::SPF_GCC};
+
static void mergeSampleProfile(const cl::list<std::string> &Inputs,
StringRef OutputFilename,
- sampleprof::SampleProfileFormat OutputFormat) {
+ ProfileFormat OutputFormat) {
using namespace sampleprof;
- auto WriterOrErr = SampleProfileWriter::create(OutputFilename, OutputFormat);
+ auto WriterOrErr =
+ SampleProfileWriter::create(OutputFilename, FormatMap[OutputFormat]);
if (std::error_code EC = WriterOrErr.getError())
exitWithErrorCode(EC, OutputFilename);
@@ -174,19 +188,18 @@ static int merge_main(int argc, const ch
cl::values(clEnumVal(instr, "Instrumentation profile (default)"),
clEnumVal(sample, "Sample profile"), clEnumValEnd));
- cl::opt<sampleprof::SampleProfileFormat> OutputFormat(
- cl::desc("Format of output profile (only meaningful with --sample)"),
- cl::init(sampleprof::SPF_Binary),
- cl::values(clEnumValN(sampleprof::SPF_Binary, "binary",
- "Binary encoding (default)"),
- clEnumValN(sampleprof::SPF_Text, "text", "Text encoding"),
- clEnumValN(sampleprof::SPF_GCC, "gcc", "GCC encoding"),
+ cl::opt<ProfileFormat> OutputFormat(
+ cl::desc("Format of output profile"), cl::init(PF_Binary),
+ cl::values(clEnumValN(PF_Binary, "binary", "Binary encoding (default)"),
+ clEnumValN(PF_Text, "text", "Text encoding"),
+ clEnumValN(PF_GCC, "gcc",
+ "GCC encoding (only meaningful for -sample)"),
clEnumValEnd));
cl::ParseCommandLineOptions(argc, argv, "LLVM profile data merger\n");
if (ProfileKind == instr)
- mergeInstrProfile(Inputs, OutputFilename);
+ mergeInstrProfile(Inputs, OutputFilename, OutputFormat);
else
mergeSampleProfile(Inputs, OutputFilename, OutputFormat);
@@ -195,7 +208,8 @@ static int merge_main(int argc, const ch
static int showInstrProfile(std::string Filename, bool ShowCounts,
bool ShowIndirectCallTargets, bool ShowAllFunctions,
- std::string ShowFunction, raw_fd_ostream &OS) {
+ std::string ShowFunction, bool TextFormat,
+ raw_fd_ostream &OS) {
auto ReaderOrErr = InstrProfReader::create(Filename);
if (std::error_code EC = ReaderOrErr.getError())
exitWithErrorCode(EC, Filename);
@@ -208,53 +222,69 @@ static int showInstrProfile(std::string
ShowAllFunctions || (!ShowFunction.empty() &&
Func.Name.find(ShowFunction) != Func.Name.npos);
+ bool doTextFormatDump = (Show && ShowCounts && TextFormat);
+
+ if (doTextFormatDump) {
+ InstrProfWriter::writeRecordInText(Func, OS);
+ continue;
+ }
+
++TotalFunctions;
assert(Func.Counts.size() > 0 && "function missing entry counter");
if (Func.Counts[0] > MaxFunctionCount)
MaxFunctionCount = Func.Counts[0];
+ for (size_t I = 1, E = Func.Counts.size(); I < E; ++I) {
+ if (Func.Counts[I] > MaxBlockCount)
+ MaxBlockCount = Func.Counts[I];
+ }
+
if (Show) {
+
if (!ShownFunctions)
OS << "Counters:\n";
+
++ShownFunctions;
OS << " " << Func.Name << ":\n"
<< " Hash: " << format("0x%016" PRIx64, Func.Hash) << "\n"
<< " Counters: " << Func.Counts.size() << "\n"
<< " Function count: " << Func.Counts[0] << "\n";
+
if (ShowIndirectCallTargets)
OS << " Indirect Call Site Count: "
<< Func.getNumValueSites(IPVK_IndirectCallTarget) << "\n";
- }
- if (Show && ShowCounts)
- OS << " Block counts: [";
- for (size_t I = 1, E = Func.Counts.size(); I < E; ++I) {
- if (Func.Counts[I] > MaxBlockCount)
- MaxBlockCount = Func.Counts[I];
- if (Show && ShowCounts)
- OS << (I == 1 ? "" : ", ") << Func.Counts[I];
- }
- if (Show && ShowCounts)
- OS << "]\n";
+ if (ShowCounts) {
+ OS << " Block counts: [";
+ for (size_t I = 1, E = Func.Counts.size(); I < E; ++I) {
+ OS << (I == 1 ? "" : ", ") << Func.Counts[I];
+ }
+ OS << "]\n";
+ }
- if (Show && ShowIndirectCallTargets) {
- uint32_t NS = Func.getNumValueSites(IPVK_IndirectCallTarget);
- OS << " Indirect Target Results: \n";
- for (size_t I = 0; I < NS; ++I) {
- uint32_t NV = Func.getNumValueDataForSite(IPVK_IndirectCallTarget, I);
- std::unique_ptr<InstrProfValueData[]> VD =
- Func.getValueForSite(IPVK_IndirectCallTarget, I);
- for (uint32_t V = 0; V < NV; V++) {
- OS << "\t[ " << I << ", ";
- OS << (const char *)VD[V].Value << ", " << VD[V].Count << " ]\n";
+ if (ShowIndirectCallTargets) {
+ uint32_t NS = Func.getNumValueSites(IPVK_IndirectCallTarget);
+ OS << " Indirect Target Results: \n";
+ for (size_t I = 0; I < NS; ++I) {
+ uint32_t NV = Func.getNumValueDataForSite(IPVK_IndirectCallTarget, I);
+ std::unique_ptr<InstrProfValueData[]> VD =
+ Func.getValueForSite(IPVK_IndirectCallTarget, I);
+ for (uint32_t V = 0; V < NV; V++) {
+ OS << "\t[ " << I << ", ";
+ OS << (const char *)VD[V].Value << ", " << VD[V].Count << " ]\n";
+ }
}
}
}
}
+
if (Reader->hasError())
exitWithErrorCode(Reader->getError(), Filename);
+ if (ShowCounts && TextFormat)
+ return 0;
+
if (ShowAllFunctions || !ShowFunction.empty())
OS << "Functions shown: " << ShownFunctions << "\n";
OS << "Total functions: " << TotalFunctions << "\n";
@@ -289,6 +319,9 @@ static int show_main(int argc, const cha
cl::opt<bool> ShowCounts("counts", cl::init(false),
cl::desc("Show counter values for shown functions"));
+ cl::opt<bool> TextFormat(
+ "text", cl::init(false),
+ cl::desc("Show instr profile data in text dump format"));
cl::opt<bool> ShowIndirectCallTargets(
"ic-targets", cl::init(false),
cl::desc("Show indirect call site target values for shown functions"));
@@ -314,14 +347,14 @@ static int show_main(int argc, const cha
std::error_code EC;
raw_fd_ostream OS(OutputFilename.data(), EC, sys::fs::F_Text);
if (EC)
- exitWithErrorCode(EC, OutputFilename);
+ exitWithErrorCode(EC, OutputFilename);
if (ShowAllFunctions && !ShowFunction.empty())
errs() << "warning: -function argument ignored: showing all functions\n";
if (ProfileKind == instr)
return showInstrProfile(Filename, ShowCounts, ShowIndirectCallTargets,
- ShowAllFunctions, ShowFunction, OS);
+ ShowAllFunctions, ShowFunction, TextFormat, OS);
else
return showSampleProfile(Filename, ShowCounts, ShowAllFunctions,
ShowFunction, OS);
More information about the llvm-commits
mailing list