diff --git a/compiler-rt/test/profile/Linux/profile-version.c b/compiler-rt/test/profile/Linux/profile-version.c new file mode 100644 --- /dev/null +++ b/compiler-rt/test/profile/Linux/profile-version.c @@ -0,0 +1,34 @@ +// REQUIRES: linux +// RUN: %clang_profgen -O2 -o %t %s +// RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t +// RUN: llvm-profdata show --profile-version %t.profraw > %t.profraw.out +// RUN: FileCheck %s --check-prefix=RAW-PROF < %t.profraw.out + +// RUN: rm -rf %t.profdir +// RUN: env LLVM_PROFILE_FILE=%t.profdir/default_%m.profraw %run %t +// RUN: env LLVM_PROFILE_FILE=%t.profdir/default_%m.profraw %run %t +// RUN: env LLVM_PROFILE_FILE=%t.profdir/default_%m.profraw %run %t +// RUN: llvm-profdata show --profile-version %t.profdir/default_*.profraw > %t.profraw.out +// RUN: FileCheck %s --check-prefix=INDEXED-PROF < %t.profraw.out + +void foo() {} + +void bar() {} + +int main() { + foo(); + bar(); + return 0; +} + +// RAW-PROF: Instrumentation level: Front-end +// RAW-PROF-NEXT: Total functions: 3 +// RAW-PROF-NEXT: Maximum function count: 1 +// RAW-PROF-NEXT: Maximum internal block count: 0 +// RAW-PROF-NEXT: Profile version: {{[0-9]+}} + +// INDEXED-PROF: Instrumentation level: Front-end +// INDEXED-PROF-NEXT: Total functions: 3 +// INDEXED-PROF-NEXT: Maximum function count: 3 +// INDEXED-PROF-NEXT: Maximum internal block count: 0 +// INDEXED-PROF-NEXT: Profile version: {{[0-9]+}} diff --git a/llvm/docs/CommandGuide/llvm-profdata.rst b/llvm/docs/CommandGuide/llvm-profdata.rst --- a/llvm/docs/CommandGuide/llvm-profdata.rst +++ b/llvm/docs/CommandGuide/llvm-profdata.rst @@ -245,6 +245,10 @@ Print details for every function. +.. option:: --binary-ids + + Print embedded binary ids in a profile. + .. option:: --counts Print the counter values for the displayed functions. @@ -297,6 +301,10 @@ Only output names of functions whose max count value are below the cutoff value. +.. option:: --profile-version + + Print profile version. + .. option:: --showcs Only show context sensitive profile counts. The default is to filter all diff --git a/llvm/include/llvm/ProfileData/InstrProfReader.h b/llvm/include/llvm/ProfileData/InstrProfReader.h --- a/llvm/include/llvm/ProfileData/InstrProfReader.h +++ b/llvm/include/llvm/ProfileData/InstrProfReader.h @@ -103,6 +103,9 @@ InstrProfIterator<> begin() { return InstrProfIterator<>(this); } InstrProfIterator<> end() { return InstrProfIterator<>(); } + /// Return the profile version. + virtual uint64_t getVersion() const = 0; + virtual bool isIRLevelProfile() const = 0; virtual bool hasCSIRLevelProfile() const = 0; @@ -215,6 +218,9 @@ /// Return true if the given buffer is in text instrprof format. static bool hasFormat(const MemoryBuffer &Buffer); + // Text format does not have version, so return 0. + uint64_t getVersion() const override { return 0; } + bool isIRLevelProfile() const override { return static_cast(ProfileKind & InstrProfKind::IRInstrumentation); } @@ -306,6 +312,8 @@ Error readNextRecord(NamedInstrProfRecord &Record) override; Error printBinaryIds(raw_ostream &OS) override; + uint64_t getVersion() const override { return Version; } + bool isIRLevelProfile() const override { return (Version & VARIANT_MASK_IR_PROF) != 0; } @@ -608,7 +616,7 @@ IndexedInstrProfReader &operator=(const IndexedInstrProfReader &) = delete; /// Return the profile version. - uint64_t getVersion() const { return Index->getVersion(); } + uint64_t getVersion() const override { return Index->getVersion(); } bool isIRLevelProfile() const override { return Index->isIRLevelProfile(); } bool hasCSIRLevelProfile() const override { return Index->hasCSIRLevelProfile(); diff --git a/llvm/tools/llvm-profdata/llvm-profdata.cpp b/llvm/tools/llvm-profdata/llvm-profdata.cpp --- a/llvm/tools/llvm-profdata/llvm-profdata.cpp +++ b/llvm/tools/llvm-profdata/llvm-profdata.cpp @@ -2252,7 +2252,7 @@ uint64_t ValueCutoff, bool OnlyListBelow, const std::string &ShowFunction, bool TextFormat, bool ShowBinaryIds, bool ShowCovered, - raw_fd_ostream &OS) { + bool ShowProfileVersion, raw_fd_ostream &OS) { auto ReaderOrErr = InstrProfReader::create(Filename); std::vector Cutoffs = std::move(DetailedSummaryCutoffs); if (ShowDetailedSummary && Cutoffs.empty()) { @@ -2462,6 +2462,8 @@ if (Error E = Reader->printBinaryIds(OS)) exitWithError(std::move(E), Filename); + if (ShowProfileVersion) + OS << "Profile version: " << Reader->getVersion() << "\n"; return 0; } @@ -2786,7 +2788,8 @@ 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. ")); cl::ParseCommandLineOptions(argc, argv, "LLVM profile data summary\n"); if (Filename.empty() && DebugInfoFilename.empty()) @@ -2817,7 +2820,7 @@ Filename, ShowCounts, TopNFunctions, ShowIndirectCallTargets, ShowMemOPSizes, ShowDetailedSummary, DetailedSummaryCutoffs, ShowAllFunctions, ShowCS, ValueCutoff, OnlyListBelow, ShowFunction, - TextFormat, ShowBinaryIds, ShowCovered, OS); + TextFormat, ShowBinaryIds, ShowCovered, ShowProfileVersion, OS); if (ProfileKind == sample) return showSampleProfile( Filename, ShowCounts, TopNFunctions, ShowAllFunctions,