[llvm] c9baa56 - [InstrProf][Correlate] Verify debug info with llvm-profdata show

Ellis Hoag via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 27 10:11:11 PST 2022


Author: Ellis Hoag
Date: 2022-01-27T10:11:04-08:00
New Revision: c9baa5608bad5a0d908887f17bc47e569cd8883c

URL: https://github.com/llvm/llvm-project/commit/c9baa5608bad5a0d908887f17bc47e569cd8883c
DIFF: https://github.com/llvm/llvm-project/commit/c9baa5608bad5a0d908887f17bc47e569cd8883c.diff

LOG: [InstrProf][Correlate] Verify debug info with llvm-profdata show

Use the `llvm-profdata show` command to verify debug info for profile correlation using the `--debug-info` option.

Reviewed By: kyulee

Differential Revision: https://reviews.llvm.org/D118181

Added: 
    compiler-rt/test/profile/Linux/instrprof-show-debug-info-correlation.c
    llvm/test/tools/llvm-profdata/errors.test

Modified: 
    llvm/include/llvm/ProfileData/InstrProf.h
    llvm/include/llvm/ProfileData/InstrProfCorrelator.h
    llvm/lib/ProfileData/InstrProfCorrelator.cpp
    llvm/tools/llvm-profdata/llvm-profdata.cpp

Removed: 
    


################################################################################
diff  --git a/compiler-rt/test/profile/Linux/instrprof-show-debug-info-correlation.c b/compiler-rt/test/profile/Linux/instrprof-show-debug-info-correlation.c
new file mode 100644
index 000000000000..d0ab3ace1b05
--- /dev/null
+++ b/compiler-rt/test/profile/Linux/instrprof-show-debug-info-correlation.c
@@ -0,0 +1,16 @@
+// RUN: %clang_pgogen -o %t -g -mllvm --debug-info-correlate -mllvm --disable-vp=true %s
+// RUN: llvm-profdata show --debug-info=%t --detailed-summary --show-prof-sym-list | FileCheck %s
+
+// RUN: %clang_pgogen -o %t.no.dbg -mllvm --debug-info-correlate -mllvm --disable-vp=true %s
+// RUN: not llvm-profdata show --debug-info=%t.no.dbg 2>&1 | FileCheck %s --check-prefix NO-DBG
+// NO-DBG: unable to correlate profile: could not find any profile metadata in debug info
+
+void a() {}
+void b() {}
+int main() { return 0; }
+
+// CHECK: a
+// CHECK: b
+// CHECK: main
+// CHECK: Counters section size: 0x18 bytes
+// CHECK: Found 3 functions

diff  --git a/llvm/include/llvm/ProfileData/InstrProf.h b/llvm/include/llvm/ProfileData/InstrProf.h
index 56198ea978ee..4d3bb0e8ff10 100644
--- a/llvm/include/llvm/ProfileData/InstrProf.h
+++ b/llvm/include/llvm/ProfileData/InstrProf.h
@@ -529,6 +529,12 @@ class InstrProfSymtab {
 
   /// Return the name section data.
   inline StringRef getNameData() const { return Data; }
+
+  /// Dump the symbols in this table.
+  void dumpNames(raw_ostream &OS) const {
+    for (StringRef S : NameTab.keys())
+      OS << S << "\n";
+  }
 };
 
 Error InstrProfSymtab::create(StringRef D, uint64_t BaseAddr) {

diff  --git a/llvm/include/llvm/ProfileData/InstrProfCorrelator.h b/llvm/include/llvm/ProfileData/InstrProfCorrelator.h
index e254169c447a..135936b99f24 100644
--- a/llvm/include/llvm/ProfileData/InstrProfCorrelator.h
+++ b/llvm/include/llvm/ProfileData/InstrProfCorrelator.h
@@ -35,6 +35,20 @@ class InstrProfCorrelator {
   /// to their functions.
   virtual Error correlateProfileData() = 0;
 
+  /// Return the number of ProfileData elements.
+  llvm::Optional<size_t> getDataSize() const;
+
+  /// Return a pointer to the names string that this class constructs.
+  const char *getNamesPointer() const { return Names.c_str(); }
+
+  /// Return the number of bytes in the names string.
+  size_t getNamesSize() const { return Names.size(); }
+
+  /// Return the size of the counters section in bytes.
+  uint64_t getCountersSectionSize() const {
+    return Ctx->CountersSectionEnd - Ctx->CountersSectionStart;
+  }
+
   static const char *FunctionNameAttributeName;
   static const char *CFGHashAttributeName;
   static const char *NumCountersAttributeName;
@@ -59,6 +73,9 @@ class InstrProfCorrelator {
   InstrProfCorrelator(InstrProfCorrelatorKind K, std::unique_ptr<Context> Ctx)
       : Ctx(std::move(Ctx)), Kind(K) {}
 
+  std::string Names;
+  std::vector<std::string> NamesVec;
+
 private:
   static llvm::Expected<std::unique_ptr<InstrProfCorrelator>>
   get(std::unique_ptr<MemoryBuffer> Buffer);
@@ -83,19 +100,12 @@ class InstrProfCorrelatorImpl : public InstrProfCorrelator {
   /// Return the number of ProfileData elements.
   size_t getDataSize() const { return Data.size(); }
 
-  /// Return a pointer to the names string that this class constructs.
-  const char *getNamesPointer() const { return Names.c_str(); }
-
-  /// Return the number of bytes in the names string.
-  size_t getNamesSize() const { return Names.size(); }
-
   static llvm::Expected<std::unique_ptr<InstrProfCorrelatorImpl<IntPtrT>>>
   get(std::unique_ptr<InstrProfCorrelator::Context> Ctx,
       const object::ObjectFile &Obj);
 
 protected:
   std::vector<RawInstrProf::ProfileData<IntPtrT>> Data;
-  std::string Names;
 
   Error correlateProfileData() override;
   virtual void correlateProfileDataImpl() = 0;
@@ -107,7 +117,6 @@ class InstrProfCorrelatorImpl : public InstrProfCorrelator {
   InstrProfCorrelatorImpl(InstrProfCorrelatorKind Kind,
                           std::unique_ptr<InstrProfCorrelator::Context> Ctx)
       : InstrProfCorrelator(Kind, std::move(Ctx)){};
-  std::vector<std::string> NamesVec;
   llvm::DenseSet<IntPtrT> CounterOffsets;
 
   // Byte-swap the value if necessary.

diff  --git a/llvm/lib/ProfileData/InstrProfCorrelator.cpp b/llvm/lib/ProfileData/InstrProfCorrelator.cpp
index 7a5791eedb61..8e38a6869d07 100644
--- a/llvm/lib/ProfileData/InstrProfCorrelator.cpp
+++ b/llvm/lib/ProfileData/InstrProfCorrelator.cpp
@@ -88,6 +88,15 @@ InstrProfCorrelator::get(std::unique_ptr<MemoryBuffer> Buffer) {
       instrprof_error::unable_to_correlate_profile, "not an object file");
 }
 
+Optional<size_t> InstrProfCorrelator::getDataSize() const {
+  if (auto *C = dyn_cast<InstrProfCorrelatorImpl<uint32_t>>(this)) {
+    return C->getDataSize();
+  } else if (auto *C = dyn_cast<InstrProfCorrelatorImpl<uint64_t>>(this)) {
+    return C->getDataSize();
+  }
+  return {};
+}
+
 namespace llvm {
 
 template <>

diff  --git a/llvm/test/tools/llvm-profdata/errors.test b/llvm/test/tools/llvm-profdata/errors.test
new file mode 100644
index 000000000000..bd7d491b9a6b
--- /dev/null
+++ b/llvm/test/tools/llvm-profdata/errors.test
@@ -0,0 +1,8 @@
+RUN: not llvm-profdata show 2>&1 | FileCheck %s --check-prefix SHOW-REQ
+SHOW-REQ: the positional argument '<profdata-file>' is required unless '--debug-info' is provided
+
+RUN: not llvm-profdata show file -o file 2>&1 | FileCheck %s --check-prefix SHOW-OUT
+SHOW-OUT: Input file name cannot be the same as the output file name!
+
+RUN: not llvm-profdata 2>&1 | FileCheck %s --check-prefix EMPTY
+EMPTY: No command specified!

diff  --git a/llvm/tools/llvm-profdata/llvm-profdata.cpp b/llvm/tools/llvm-profdata/llvm-profdata.cpp
index 356dd5c48829..5e58c1365d80 100644
--- a/llvm/tools/llvm-profdata/llvm-profdata.cpp
+++ b/llvm/tools/llvm-profdata/llvm-profdata.cpp
@@ -2486,9 +2486,35 @@ static int showMemProfProfile(const std::string &Filename, raw_fd_ostream &OS) {
   return 0;
 }
 
+static int showDebugInfoCorrelation(const std::string &Filename,
+                                    bool ShowDetailedSummary,
+                                    bool ShowProfileSymbolList,
+                                    raw_fd_ostream &OS) {
+  std::unique_ptr<InstrProfCorrelator> Correlator;
+  if (auto Err = InstrProfCorrelator::get(Filename).moveInto(Correlator))
+    exitWithError(std::move(Err), Filename);
+  if (auto Err = Correlator->correlateProfileData())
+    exitWithError(std::move(Err), Filename);
+
+  InstrProfSymtab Symtab;
+  if (auto Err = Symtab.create(
+          StringRef(Correlator->getNamesPointer(), Correlator->getNamesSize())))
+    exitWithError(std::move(Err), Filename);
+
+  if (ShowProfileSymbolList)
+    Symtab.dumpNames(OS);
+  // TODO: Read "Profile Data Type" from debug info to compute and show how many
+  // counters the section holds.
+  if (ShowDetailedSummary)
+    OS << "Counters section size: 0x"
+       << Twine::utohexstr(Correlator->getCountersSectionSize()) << " bytes\n";
+  OS << "Found " << Correlator->getDataSize() << " functions\n";
+
+  return 0;
+}
+
 static int show_main(int argc, const char *argv[]) {
-  cl::opt<std::string> Filename(cl::Positional, cl::Required,
-                                cl::desc("<profdata-file>"));
+  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"));
@@ -2549,9 +2575,18 @@ static int show_main(int argc, const char *argv[]) {
                "extbinary format"));
   cl::opt<bool> ShowBinaryIds("binary-ids", cl::init(false),
                               cl::desc("Show binary ids 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::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])
            << ": Input file name cannot be the same as the output file name!\n";
@@ -2566,6 +2601,10 @@ static int show_main(int argc, const char *argv[]) {
   if (ShowAllFunctions && !ShowFunction.empty())
     WithColor::warning() << "-function argument ignored: showing all functions\n";
 
+  if (!DebugInfoFilename.empty())
+    return showDebugInfoCorrelation(DebugInfoFilename, ShowDetailedSummary,
+                                    ShowProfileSymbolList, OS);
+
   if (ProfileKind == instr)
     return showInstrProfile(
         Filename, ShowCounts, TopNFunctions, ShowIndirectCallTargets,


        


More information about the llvm-commits mailing list