[llvm] [llvm-objdump] Add support for symbolizing PGOBBAddrMap Info (PR #76386)

Aiden Grossman via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 11 18:32:50 PST 2024


https://github.com/boomanaiden154 updated https://github.com/llvm/llvm-project/pull/76386

>From 0878d071177fa66f86763bb30253029ec131cb62 Mon Sep 17 00:00:00 2001
From: Aiden Grossman <agrossman154 at yahoo.com>
Date: Mon, 25 Dec 2023 23:28:13 -0800
Subject: [PATCH 1/3] [llvm-objdump] Add support for symbolizing PGOBBAddrMap
 Info

This patch adds in support for symbolizing PGO information contained
within the SHT_LLVM_BB_ADDR_MAP section in llvm-objdump. The outputs are
simply the raw values contained within the section.
---
 .../llvm-objdump/X86/elf-pgoanalysismap.yaml  | 181 ++++++++++++++++++
 llvm/tools/llvm-objdump/llvm-objdump.cpp      | 103 ++++++++--
 2 files changed, 267 insertions(+), 17 deletions(-)
 create mode 100644 llvm/test/tools/llvm-objdump/X86/elf-pgoanalysismap.yaml

diff --git a/llvm/test/tools/llvm-objdump/X86/elf-pgoanalysismap.yaml b/llvm/test/tools/llvm-objdump/X86/elf-pgoanalysismap.yaml
new file mode 100644
index 00000000000000..881ce905b22645
--- /dev/null
+++ b/llvm/test/tools/llvm-objdump/X86/elf-pgoanalysismap.yaml
@@ -0,0 +1,181 @@
+# Test that in the presence of SHT_LLVM_BB_ADDR_MAP sections which also
+# contain PGO data, --symbolize-operands is able to label the basic blocks
+# correctly.
+
+# Check the case where we only have entry counts.
+
+# RUN: yaml2obj %s -o %t1
+# RUN: llvm-objdump %t1 -d --symbolize-operands --no-show-raw-insn --no-leading-addr | \
+# RUN:   FileCheck %s --check-prefix=ENTRYCOUNT
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_EXEC
+  Machine: EM_X86_64
+Sections:
+  - Name:    .text.foo
+    Type:    SHT_PROGBITS
+    Address: 0x0
+    Flags:   [SHF_ALLOC, SHF_EXECINSTR]
+    Content: '50'
+  - Name:   .llvm_bb_addr_map.foo
+    Type:   SHT_LLVM_BB_ADDR_MAP
+    Link:   .text.foo
+    Entries:
+      - Version: 2
+        Address: 0x0
+        Feature: 0x1
+        BBEntries:
+          - ID:            3
+            AddressOffset: 0x0
+            Size:          0x1
+            Metadata:      0x1
+    PGOAnalyses:
+      - FuncEntryCount: 1000
+Symbols:
+  - Name:    foo
+    Section: .text.foo
+    Value:   0x0
+
+# ENTRYCOUNT: <foo>:
+# ENTRYCOUNT: <BB3> (Entry count: 1000):
+
+# Check the case where we have entrypoints and block frequency information
+
+# RUN: yaml2obj %s --docnum=2 -o %t2
+# RUN: llvm-objdump %t2 -d --symbolize-operands --no-show-raw-insn --no-leading-addr | \
+# RUN:   FileCheck %s --check-prefix=ENTRYCOUNT-BLOCKFREQ
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_EXEC
+  Machine: EM_X86_64
+Sections:
+  - Name:    .text.foo
+    Type:    SHT_PROGBITS
+    Address: 0x0
+    Flags:   [SHF_ALLOC, SHF_EXECINSTR]
+    Content: '503b0505200000907d02ebf5c3'
+  - Name:   .llvm_bb_addr_map.foo
+    Type:   SHT_LLVM_BB_ADDR_MAP
+    Link:   .text.foo
+    Entries:
+      - Version: 2
+        Address: 0x0
+        Feature: 0x3
+        BBEntries:
+          - ID:            3
+            AddressOffset: 0x0
+            Size:          0x1
+            Metadata:      0x1
+          - ID:            1
+            AddressOffset: 0x0
+            Size:          0x6
+            Metadata:      0x0
+          - ID:            2
+            AddressOffset: 0x1
+            Size:          0x4
+            Metadata:      0x0
+          - ID:            5
+            AddressOffset: 0x0
+            Size:          0x1
+            Metadata:      0x2
+    PGOAnalyses:
+      - FuncEntryCount: 1000
+        PGOBBEntries:
+          - BBFreq: 1000
+          - BBFreq: 133
+          - BBFreq: 18
+          - BBFreq: 1000
+Symbols:
+  - Name:    foo
+    Section: .text.foo
+    Value:   0x0
+
+# ENTRYCOUNT-BLOCKFREQ: <foo>:
+# ENTRYCOUNT-BLOCKFREQ: <BB3> (Entry count: 1000, Frequency: 1000):
+# ENTRYCOUNT-BLOCKFREQ: <BB1> (Frequency: 133):
+# ENTRYCOUNT-BLOCKFREQ: <BB2> (Frequency: 18):
+# ENTRYCOUNT-BLOCKFREQ: <BB5> (Frequency: 1000):
+
+# Check the case where we have entrypoints, block frequency, and branch
+# proabability information.
+
+# RUN: yaml2obj %s --docnum=3 -o %t3
+# RUN: llvm-objdump %t3 -d --symbolize-operands --no-show-raw-insn --no-leading-addr | \
+# RUN:   FileCheck %s --check-prefix=ENTRY-FREQ-PROB
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_EXEC
+  Machine: EM_X86_64
+Sections:
+  - Name:    .text.foo
+    Type:    SHT_PROGBITS
+    Address: 0x0
+    Flags:   [SHF_ALLOC, SHF_EXECINSTR]
+    Content: '503b0505200000907d02ebf5c3'
+  - Name:   .llvm_bb_addr_map.foo
+    Type:   SHT_LLVM_BB_ADDR_MAP
+    Link:   .text.foo
+    Entries:
+      - Version: 2
+        Address: 0x0
+        Feature: 0x7
+        BBEntries:
+          - ID:            3
+            AddressOffset: 0x0
+            Size:          0x1
+            Metadata:      0x1
+          - ID:            1
+            AddressOffset: 0x0
+            Size:          0x6
+            Metadata:      0x0
+          - ID:            2
+            AddressOffset: 0x1
+            Size:          0x4
+            Metadata:      0x0
+          - ID:            5
+            AddressOffset: 0x0
+            Size:          0x1
+            Metadata:      0x2
+    PGOAnalyses:
+      - FuncEntryCount: 1000
+        PGOBBEntries:
+          - BBFreq: 1000
+            Successors:
+            - ID:          1
+              BrProb:      0x22222222
+            - ID:          2
+              BrProb:      0x33333333
+            - ID:          3
+              BrProb:      0xaaaaaaaa
+          - BBFreq: 133
+            Successors:
+            - ID:          2
+              BrProb:      0x11111111
+            - ID:          3
+              BrProb:      0xeeeeeeee
+          - BBFreq: 18
+            Successors:
+            - ID:          3
+              BrProb:      0xffffffff
+          - BBFreq: 1000
+            Successors:    []
+Symbols:
+  - Name:    foo
+    Section: .text.foo
+    Value:   0x0
+
+# ENTRY-FREQ-PROB: <foo>:
+# ENTRY-FREQ-PROB: <BB3> (Entry count: 1000, Frequency: 1000, Successors: BB1:22222222, BB2:33333333, BB3:aaaaaaaa):
+# ENTRY-FREQ-PROB: <BB1> (Frequency: 133, Successors: BB2:11111111, BB3:eeeeeeee):
+# ENTRY-FREQ-PROB: <BB2> (Frequency: 18, Successors: BB3:ffffffff):
+# ENTRY-FREQ-PROB: <BB5> (Frequency: 1000):
+
diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp
index 7467a6062b5a8b..d92d95a9936218 100644
--- a/llvm/tools/llvm-objdump/llvm-objdump.cpp
+++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp
@@ -1264,10 +1264,53 @@ static SymbolInfoTy createDummySymbolInfo(const ObjectFile &Obj,
     return SymbolInfoTy(Addr, Name, Type);
 }
 
-static void
-collectBBAddrMapLabels(const std::unordered_map<uint64_t, BBAddrMap> &AddrToBBAddrMap,
-                       uint64_t SectionAddr, uint64_t Start, uint64_t End,
-                       std::unordered_map<uint64_t, std::vector<std::string>> &Labels) {
+struct BBAddrMapLabel {
+  std::string BlockLabel;
+  std::string PGOAnalysis;
+};
+
+static void constructPGOLabelString(std::string &PGOString,
+                                    const PGOAnalysisMap &PGOMap,
+                                    size_t BBEntryIndex) {
+  raw_string_ostream PGOSS(PGOString);
+
+  PGOSS << " (";
+  if (PGOMap.FeatEnable.FuncEntryCount && BBEntryIndex == 0) {
+    PGOSS << "Entry count: " << Twine(PGOMap.FuncEntryCount);
+    if (PGOMap.FeatEnable.BBFreq || PGOMap.FeatEnable.BrProb) {
+      PGOSS << ", ";
+    }
+  }
+
+  if (PGOMap.FeatEnable.BBFreq || PGOMap.FeatEnable.BrProb) {
+    const PGOAnalysisMap::PGOBBEntry &PGOBBEntry =
+        PGOMap.BBEntries[BBEntryIndex];
+
+    if (PGOMap.FeatEnable.BBFreq) {
+      PGOSS << "Frequency: " << Twine(PGOBBEntry.BlockFreq.getFrequency());
+      if (PGOMap.FeatEnable.BrProb && PGOBBEntry.Successors.size() > 0) {
+        PGOSS << ", ";
+      }
+    }
+    if (PGOMap.FeatEnable.BrProb && PGOBBEntry.Successors.size() > 0) {
+      PGOSS << "Successors: ";
+      interleaveComma(
+          PGOBBEntry.Successors, PGOSS,
+          [&PGOSS](const PGOAnalysisMap::PGOBBEntry::SuccessorEntry &SE) {
+            PGOSS << "BB" << SE.ID << ":";
+            PGOSS.write_hex(SE.Prob.getNumerator());
+          });
+    }
+  }
+  PGOSS << ")";
+}
+
+static void collectBBAddrMapLabels(
+    const std::unordered_map<uint64_t, BBAddrMap> &AddrToBBAddrMap,
+    const std::unordered_map<uint64_t, PGOAnalysisMap> &AddrToPGOAnalysisMap,
+    uint64_t SectionAddr, uint64_t Start, uint64_t End,
+    std::unordered_map<uint64_t, std::vector<BBAddrMapLabel>> &Labels,
+    const StringRef FileName) {
   if (AddrToBBAddrMap.empty())
     return;
   Labels.clear();
@@ -1276,11 +1319,27 @@ collectBBAddrMapLabels(const std::unordered_map<uint64_t, BBAddrMap> &AddrToBBAd
   auto Iter = AddrToBBAddrMap.find(StartAddress);
   if (Iter == AddrToBBAddrMap.end())
     return;
-  for (const BBAddrMap::BBEntry &BBEntry : Iter->second.getBBEntries()) {
+  auto PGOIter = AddrToPGOAnalysisMap.find(StartAddress);
+  if (!AddrToPGOAnalysisMap.empty() && PGOIter == AddrToPGOAnalysisMap.end())
+    reportWarning("Expected BBAddrMap and PGOAnalysisMap to have information "
+                  "on the same basic blocks",
+                  FileName);
+
+  for (size_t I = 0; I < Iter->second.getBBEntries().size(); ++I) {
+    const BBAddrMap::BBEntry &BBEntry = Iter->second.getBBEntries()[I];
     uint64_t BBAddress = BBEntry.Offset + Iter->second.getFunctionAddress();
     if (BBAddress >= EndAddress)
       continue;
-    Labels[BBAddress].push_back(("BB" + Twine(BBEntry.ID)).str());
+
+    std::string LabelString = ("BB" + Twine(BBEntry.ID)).str();
+    std::string PGOString;
+
+    if (!AddrToPGOAnalysisMap.empty() &&
+        PGOIter != AddrToPGOAnalysisMap.end() &&
+        PGOIter->second.FeatEnable.anyEnabled())
+      constructPGOLabelString(PGOString, PGOIter->second, I);
+
+    Labels[BBAddress].push_back({LabelString, PGOString});
   }
 }
 
@@ -1638,18 +1697,25 @@ disassembleObject(ObjectFile &Obj, const ObjectFile &DbgObj,
   LLVM_DEBUG(LVP.dump());
 
   std::unordered_map<uint64_t, BBAddrMap> AddrToBBAddrMap;
+  std::unordered_map<uint64_t, PGOAnalysisMap> AddrToPGOAnalysisMap;
   auto ReadBBAddrMap = [&](std::optional<unsigned> SectionIndex =
                                std::nullopt) {
     AddrToBBAddrMap.clear();
     if (const auto *Elf = dyn_cast<ELFObjectFileBase>(&Obj)) {
-      auto BBAddrMapsOrErr = Elf->readBBAddrMap(SectionIndex);
+      std::vector<PGOAnalysisMap> PGOAnalyses;
+      auto BBAddrMapsOrErr = Elf->readBBAddrMap(SectionIndex, &PGOAnalyses);
       if (!BBAddrMapsOrErr) {
         reportWarning(toString(BBAddrMapsOrErr.takeError()), Obj.getFileName());
         return;
       }
-      for (auto &FunctionBBAddrMap : *BBAddrMapsOrErr)
-        AddrToBBAddrMap.emplace(FunctionBBAddrMap.Addr,
-                                std::move(FunctionBBAddrMap));
+      for (size_t I = 0; I < (*BBAddrMapsOrErr).size(); ++I) {
+        uint64_t BBAddrMapAddr = (*BBAddrMapsOrErr)[I].Addr;
+        AddrToBBAddrMap.emplace(BBAddrMapAddr,
+                                std::move((*BBAddrMapsOrErr)[I]));
+        if (PGOAnalyses.size() > 0)
+          AddrToPGOAnalysisMap.emplace(BBAddrMapAddr,
+                                       std::move(PGOAnalyses[I]));
+      }
     }
   };
 
@@ -1978,14 +2044,15 @@ disassembleObject(ObjectFile &Obj, const ObjectFile &DbgObj,
         FOS.SetUnbuffered();
 
       std::unordered_map<uint64_t, std::string> AllLabels;
-      std::unordered_map<uint64_t, std::vector<std::string>> BBAddrMapLabels;
+      std::unordered_map<uint64_t, std::vector<BBAddrMapLabel>> BBAddrMapLabels;
       if (SymbolizeOperands) {
         collectLocalBranchTargets(Bytes, DT->InstrAnalysis.get(),
                                   DT->DisAsm.get(), DT->InstPrinter.get(),
                                   PrimaryTarget.SubtargetInfo.get(),
                                   SectionAddr, Index, End, AllLabels);
-        collectBBAddrMapLabels(AddrToBBAddrMap, SectionAddr, Index, End,
-                               BBAddrMapLabels);
+        collectBBAddrMapLabels(AddrToBBAddrMap, AddrToPGOAnalysisMap,
+                               SectionAddr, Index, End, BBAddrMapLabels,
+                               FileName);
       }
 
       if (DT->InstrAnalysis)
@@ -2083,8 +2150,9 @@ disassembleObject(ObjectFile &Obj, const ObjectFile &DbgObj,
           // Print local label if there's any.
           auto Iter1 = BBAddrMapLabels.find(SectionAddr + Index);
           if (Iter1 != BBAddrMapLabels.end()) {
-            for (StringRef Label : Iter1->second)
-              FOS << "<" << Label << ">:\n";
+            for (const auto &BBLabel : Iter1->second)
+              FOS << "<" << BBLabel.BlockLabel << ">" << BBLabel.PGOAnalysis
+                  << ":\n";
           } else {
             auto Iter2 = AllLabels.find(SectionAddr + Index);
             if (Iter2 != AllLabels.end())
@@ -2261,7 +2329,7 @@ disassembleObject(ObjectFile &Obj, const ObjectFile &DbgObj,
                 } else if (!Disp) {
                   *TargetOS << TargetName;
                 } else if (BBAddrMapLabelAvailable) {
-                  *TargetOS << BBAddrMapLabels[Target].front();
+                  *TargetOS << BBAddrMapLabels[Target].front().BlockLabel;
                 } else if (LabelAvailable) {
                   *TargetOS << AllLabels[Target];
                 } else {
@@ -2277,7 +2345,8 @@ disassembleObject(ObjectFile &Obj, const ObjectFile &DbgObj,
                 }
 
               } else if (BBAddrMapLabelAvailable) {
-                *TargetOS << " <" << BBAddrMapLabels[Target].front() << ">";
+                *TargetOS << " <" << BBAddrMapLabels[Target].front().BlockLabel
+                          << ">";
               } else if (LabelAvailable) {
                 *TargetOS << " <" << AllLabels[Target] << ">";
               }

>From 440ebccd5e7edf04f8bcc0bcbad245f6d6730505 Mon Sep 17 00:00:00 2001
From: Aiden Grossman <agrossman154 at yahoo.com>
Date: Mon, 8 Jan 2024 12:53:16 -0800
Subject: [PATCH 2/3] Address reviewer feedback

---
 llvm/tools/llvm-objdump/llvm-objdump.cpp | 21 +++++++--------------
 1 file changed, 7 insertions(+), 14 deletions(-)

diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp
index d92d95a9936218..0918a9a4af606e 100644
--- a/llvm/tools/llvm-objdump/llvm-objdump.cpp
+++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp
@@ -1320,10 +1320,6 @@ static void collectBBAddrMapLabels(
   if (Iter == AddrToBBAddrMap.end())
     return;
   auto PGOIter = AddrToPGOAnalysisMap.find(StartAddress);
-  if (!AddrToPGOAnalysisMap.empty() && PGOIter == AddrToPGOAnalysisMap.end())
-    reportWarning("Expected BBAddrMap and PGOAnalysisMap to have information "
-                  "on the same basic blocks",
-                  FileName);
 
   for (size_t I = 0; I < Iter->second.getBBEntries().size(); ++I) {
     const BBAddrMap::BBEntry &BBEntry = Iter->second.getBBEntries()[I];
@@ -1334,9 +1330,7 @@ static void collectBBAddrMapLabels(
     std::string LabelString = ("BB" + Twine(BBEntry.ID)).str();
     std::string PGOString;
 
-    if (!AddrToPGOAnalysisMap.empty() &&
-        PGOIter != AddrToPGOAnalysisMap.end() &&
-        PGOIter->second.FeatEnable.anyEnabled())
+    if (PGOIter != AddrToPGOAnalysisMap.end())
       constructPGOLabelString(PGOString, PGOIter->second, I);
 
     Labels[BBAddress].push_back({LabelString, PGOString});
@@ -1708,13 +1702,12 @@ disassembleObject(ObjectFile &Obj, const ObjectFile &DbgObj,
         reportWarning(toString(BBAddrMapsOrErr.takeError()), Obj.getFileName());
         return;
       }
-      for (size_t I = 0; I < (*BBAddrMapsOrErr).size(); ++I) {
-        uint64_t BBAddrMapAddr = (*BBAddrMapsOrErr)[I].Addr;
-        AddrToBBAddrMap.emplace(BBAddrMapAddr,
-                                std::move((*BBAddrMapsOrErr)[I]));
-        if (PGOAnalyses.size() > 0)
-          AddrToPGOAnalysisMap.emplace(BBAddrMapAddr,
-                                       std::move(PGOAnalyses[I]));
+      for (const auto &[FunctionBBAddrMap, FunctionPGOAnalysis] :
+           zip_equal(*BBAddrMapsOrErr, PGOAnalyses)) {
+        AddrToBBAddrMap.emplace(FunctionBBAddrMap.Addr, FunctionBBAddrMap);
+        if (FunctionPGOAnalysis.FeatEnable.anyEnabled())
+          AddrToPGOAnalysisMap.emplace(FunctionBBAddrMap.Addr,
+                                       FunctionPGOAnalysis);
       }
     }
   };

>From 3e1c01081a6eab70755410f9ae465dc34f6ad938 Mon Sep 17 00:00:00 2001
From: Aiden Grossman <agrossman154 at yahoo.com>
Date: Thu, 11 Jan 2024 18:32:39 -0800
Subject: [PATCH 3/3] Switch to move semantics where relevant

---
 llvm/tools/llvm-objdump/llvm-objdump.cpp | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp
index 0918a9a4af606e..4cfea2af287da4 100644
--- a/llvm/tools/llvm-objdump/llvm-objdump.cpp
+++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp
@@ -1702,12 +1702,12 @@ disassembleObject(ObjectFile &Obj, const ObjectFile &DbgObj,
         reportWarning(toString(BBAddrMapsOrErr.takeError()), Obj.getFileName());
         return;
       }
-      for (const auto &[FunctionBBAddrMap, FunctionPGOAnalysis] :
+      for (auto &&[FunctionBBAddrMap, FunctionPGOAnalysis] :
            zip_equal(*BBAddrMapsOrErr, PGOAnalyses)) {
-        AddrToBBAddrMap.emplace(FunctionBBAddrMap.Addr, FunctionBBAddrMap);
+        uint64_t Addr = FunctionBBAddrMap.Addr;
+        AddrToBBAddrMap.emplace(Addr, std::move(FunctionBBAddrMap));
         if (FunctionPGOAnalysis.FeatEnable.anyEnabled())
-          AddrToPGOAnalysisMap.emplace(FunctionBBAddrMap.Addr,
-                                       FunctionPGOAnalysis);
+          AddrToPGOAnalysisMap.emplace(Addr, std::move(FunctionPGOAnalysis));
       }
     }
   };



More information about the llvm-commits mailing list