[compiler-rt] 70fb7bb - [InstrProf][llvm-profdata] Dump profile correlation data as YAML

Ellis Hoag via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 7 09:47:47 PDT 2022


Author: Ellis Hoag
Date: 2022-10-07T09:47:25-07:00
New Revision: 70fb7bb561db39e648d1732c60190c8c09c5b1c5

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

LOG: [InstrProf][llvm-profdata] Dump profile correlation data as YAML

Change the behavior of the `llvm-profdata show --debug-info=` command to dump a YAML file when using debug info correlation since it provides more information in a parseable format.

Reviewed By: yozhu, phosek

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

Added: 
    

Modified: 
    compiler-rt/test/profile/Linux/instrprof-show-debug-info-correlation.c
    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
index d0ab3ace1b05c..a7ea54f208aec 100644
--- a/compiler-rt/test/profile/Linux/instrprof-show-debug-info-correlation.c
+++ b/compiler-rt/test/profile/Linux/instrprof-show-debug-info-correlation.c
@@ -1,16 +1,41 @@
 // 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: llvm-profdata show --debug-info=%t --output-format=yaml | FileCheck %s --match-full-lines --check-prefix YAML
 
 // 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
 
+// CHECK: a
+// YAML: Probes:
+// YAML:   - Function Name:   a
+// YAML:     Linkage Name:    a
+// YAML:     CFG Hash:        0x[[#%.1X,HASH:]]
+// YAML:     Counter Offset:  0x0
+// YAML:     Num Counters:    1
+// YAML:     File:            [[FILE:'.*']]
+// YAML:     Line:            [[@LINE+1]]
 void a() {}
-void b() {}
-int main() { return 0; }
 
-// CHECK: a
 // CHECK: b
+// YAML:   - Function Name:   b
+// YAML:     Linkage Name:    b
+// YAML:     CFG Hash:        0x[[#%.1X,HASH:]]
+// YAML:     Counter Offset:  0x8
+// YAML:     Num Counters:    1
+// YAML:     File:            [[FILE:'.*']]
+// YAML:     Line:            [[@LINE+1]]
+void b() {}
+
 // CHECK: main
+// YAML:   - Function Name:   main
+// YAML:     Linkage Name:    main
+// YAML:     CFG Hash:        0x[[#%.1X,HASH:]]
+// YAML:     Counter Offset:  0x10
+// YAML:     Num Counters:    1
+// YAML:     File:            [[FILE]]
+// YAML:     Line:            [[@LINE+1]]
+int main() { return 0; }
+
 // CHECK: Counters section size: 0x18 bytes
 // CHECK: Found 3 functions

diff  --git a/llvm/include/llvm/ProfileData/InstrProfCorrelator.h b/llvm/include/llvm/ProfileData/InstrProfCorrelator.h
index 79995c8132661..0efd4ea65bfdc 100644
--- a/llvm/include/llvm/ProfileData/InstrProfCorrelator.h
+++ b/llvm/include/llvm/ProfileData/InstrProfCorrelator.h
@@ -16,6 +16,7 @@
 #include "llvm/ProfileData/InstrProf.h"
 #include "llvm/Support/Error.h"
 #include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/YAMLTraits.h"
 #include <vector>
 
 namespace llvm {
@@ -36,6 +37,9 @@ class InstrProfCorrelator {
   /// to their functions.
   virtual Error correlateProfileData() = 0;
 
+  /// Process debug info and dump the correlation data.
+  virtual Error dumpYaml(raw_ostream &OS) = 0;
+
   /// Return the number of ProfileData elements.
   llvm::Optional<size_t> getDataSize() const;
 
@@ -69,7 +73,7 @@ class InstrProfCorrelator {
     /// True if target and host have 
diff erent endian orders.
     bool ShouldSwapBytes;
   };
-  const std::unique_ptr<InstrProfCorrelator::Context> Ctx;
+  const std::unique_ptr<Context> Ctx;
 
   InstrProfCorrelator(InstrProfCorrelatorKind K, std::unique_ptr<Context> Ctx)
       : Ctx(std::move(Ctx)), Kind(K) {}
@@ -77,6 +81,24 @@ class InstrProfCorrelator {
   std::string Names;
   std::vector<std::string> NamesVec;
 
+  struct Probe {
+    std::string FunctionName;
+    Optional<std::string> LinkageName;
+    yaml::Hex64 CFGHash;
+    yaml::Hex64 CounterOffset;
+    uint32_t NumCounters;
+    Optional<std::string> FilePath;
+    Optional<int> LineNumber;
+  };
+
+  struct CorrelationData {
+    std::vector<Probe> Probes;
+  };
+
+  friend struct yaml::MappingTraits<Probe>;
+  friend struct yaml::SequenceElementTraits<Probe>;
+  friend struct yaml::MappingTraits<CorrelationData>;
+
 private:
   static llvm::Expected<std::unique_ptr<InstrProfCorrelator>>
   get(std::unique_ptr<MemoryBuffer> Buffer);
@@ -109,7 +131,10 @@ class InstrProfCorrelatorImpl : public InstrProfCorrelator {
   std::vector<RawInstrProf::ProfileData<IntPtrT>> Data;
 
   Error correlateProfileData() override;
-  virtual void correlateProfileDataImpl() = 0;
+  virtual void correlateProfileDataImpl(
+      InstrProfCorrelator::CorrelationData *Data = nullptr) = 0;
+
+  Error dumpYaml(raw_ostream &OS) override;
 
   void addProbe(StringRef FunctionName, uint64_t CFGHash, IntPtrT CounterOffset,
                 IntPtrT FunctionPtr, uint32_t NumCounters);
@@ -171,7 +196,8 @@ class DwarfInstrProfCorrelator : public InstrProfCorrelatorImpl<IntPtrT> {
   ///       NULL
   ///     NULL
   /// \endcode
-  void correlateProfileDataImpl() override;
+  void correlateProfileDataImpl(
+      InstrProfCorrelator::CorrelationData *Data = nullptr) override;
 };
 
 } // end namespace llvm

diff  --git a/llvm/lib/ProfileData/InstrProfCorrelator.cpp b/llvm/lib/ProfileData/InstrProfCorrelator.cpp
index 4b8212c546f77..6c460a5f9c317 100644
--- a/llvm/lib/ProfileData/InstrProfCorrelator.cpp
+++ b/llvm/lib/ProfileData/InstrProfCorrelator.cpp
@@ -155,6 +155,42 @@ Error InstrProfCorrelatorImpl<IntPtrT>::correlateProfileData() {
   return Result;
 }
 
+template <> struct yaml::MappingTraits<InstrProfCorrelator::CorrelationData> {
+  static void mapping(yaml::IO &io,
+                      InstrProfCorrelator::CorrelationData &Data) {
+    io.mapRequired("Probes", Data.Probes);
+  }
+};
+
+template <> struct yaml::MappingTraits<InstrProfCorrelator::Probe> {
+  static void mapping(yaml::IO &io, InstrProfCorrelator::Probe &P) {
+    io.mapRequired("Function Name", P.FunctionName);
+    io.mapOptional("Linkage Name", P.LinkageName);
+    io.mapRequired("CFG Hash", P.CFGHash);
+    io.mapRequired("Counter Offset", P.CounterOffset);
+    io.mapRequired("Num Counters", P.NumCounters);
+    io.mapOptional("File", P.FilePath);
+    io.mapOptional("Line", P.LineNumber);
+  }
+};
+
+template <> struct yaml::SequenceElementTraits<InstrProfCorrelator::Probe> {
+  static const bool flow = false;
+};
+
+template <class IntPtrT>
+Error InstrProfCorrelatorImpl<IntPtrT>::dumpYaml(raw_ostream &OS) {
+  InstrProfCorrelator::CorrelationData Data;
+  correlateProfileDataImpl(&Data);
+  if (Data.Probes.empty())
+    return make_error<InstrProfError>(
+        instrprof_error::unable_to_correlate_profile,
+        "could not find any profile metadata in debug info");
+  yaml::Output YamlOS(OS);
+  YamlOS << Data;
+  return Error::success();
+}
+
 template <class IntPtrT>
 void InstrProfCorrelatorImpl<IntPtrT>::addProbe(StringRef FunctionName,
                                                 uint64_t CFGHash,
@@ -222,15 +258,16 @@ bool DwarfInstrProfCorrelator<IntPtrT>::isDIEOfProbe(const DWARFDie &Die) {
 }
 
 template <class IntPtrT>
-void DwarfInstrProfCorrelator<IntPtrT>::correlateProfileDataImpl() {
+void DwarfInstrProfCorrelator<IntPtrT>::correlateProfileDataImpl(
+    InstrProfCorrelator::CorrelationData *Data) {
   auto maybeAddProbe = [&](DWARFDie Die) {
     if (!isDIEOfProbe(Die))
       return;
     Optional<const char *> FunctionName;
     Optional<uint64_t> CFGHash;
     Optional<uint64_t> CounterPtr = getLocation(Die);
-    auto FunctionPtr =
-        dwarf::toAddress(Die.getParent().find(dwarf::DW_AT_low_pc));
+    auto FnDie = Die.getParent();
+    auto FunctionPtr = dwarf::toAddress(FnDie.find(dwarf::DW_AT_low_pc));
     Optional<uint64_t> NumCounters;
     for (const DWARFDie &Child : Die.children()) {
       if (Child.getTag() != dwarf::DW_TAG_LLVM_annotation)
@@ -283,8 +320,26 @@ void DwarfInstrProfCorrelator<IntPtrT>::correlateProfileDataImpl() {
                         << "\n");
       LLVM_DEBUG(Die.dump(dbgs()));
     }
-    this->addProbe(*FunctionName, *CFGHash, *CounterPtr - CountersStart,
-                   FunctionPtr.value_or(0), *NumCounters);
+    IntPtrT CounterOffset = *CounterPtr - CountersStart;
+    if (Data) {
+      InstrProfCorrelator::Probe P;
+      P.FunctionName = *FunctionName;
+      if (auto Name = FnDie.getName(DINameKind::LinkageName))
+        P.LinkageName = Name;
+      P.CFGHash = *CFGHash;
+      P.CounterOffset = CounterOffset;
+      P.NumCounters = *NumCounters;
+      auto FilePath = FnDie.getDeclFile(
+          DILineInfoSpecifier::FileLineInfoKind::RelativeFilePath);
+      if (!FilePath.empty())
+        P.FilePath = FilePath;
+      if (auto LineNumber = FnDie.getDeclLine())
+        P.LineNumber = LineNumber;
+      Data->Probes.push_back(P);
+    } else {
+      this->addProbe(*FunctionName, *CFGHash, CounterOffset,
+                     FunctionPtr.value_or(0), *NumCounters);
+    }
   };
   for (auto &CU : DICtx->normal_units())
     for (const auto &Entry : CU->dies())

diff  --git a/llvm/tools/llvm-profdata/llvm-profdata.cpp b/llvm/tools/llvm-profdata/llvm-profdata.cpp
index 3fe91f4b570c5..95019c96d9a2b 100644
--- a/llvm/tools/llvm-profdata/llvm-profdata.cpp
+++ b/llvm/tools/llvm-profdata/llvm-profdata.cpp
@@ -2703,11 +2703,14 @@ static int showDebugInfoCorrelation(const std::string &Filename,
                                     OutputFormat OFormat, raw_fd_ostream &OS) {
   if (OFormat == OutputFormat::Json)
     exitWithError("JSON output is not supported for debug info correlation");
-  if (OFormat == OutputFormat::Yaml)
-    exitWithError("YAML output is not supported for debug info correlation");
   std::unique_ptr<InstrProfCorrelator> Correlator;
   if (auto Err = InstrProfCorrelator::get(Filename).moveInto(Correlator))
     exitWithError(std::move(Err), Filename);
+  if (OFormat == OutputFormat::Yaml) {
+    if (auto Err = Correlator->dumpYaml(OS))
+      exitWithError(std::move(Err), Filename);
+    return 0;
+  }
 
   if (auto Err = Correlator->correlateProfileData())
     exitWithError(std::move(Err), Filename);


        


More information about the llvm-commits mailing list