[llvm] [SHT_LLVM_BB_ADDR_MAP][llvm-readobj] Implements llvm-readobj handling for PGOAnalysisMap. (PR #79520)

Micah Weston via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 25 15:29:10 PST 2024


https://github.com/red1bluelost created https://github.com/llvm/llvm-project/pull/79520

Adds raw printing of PGOAnalysisMap in llvm-readobj.

I'm leaving the fixme's for a later patch that will provide a 'pretty' printing for BBFreq and BrProb (i.e. relative frequencies and probabilities) that will apply to both llvm-readobj and llvm-objdump.


>From 4d78bde1910fea8061398f4011089ee71e4aa609 Mon Sep 17 00:00:00 2001
From: Micah Weston <micahsweston at gmail.com>
Date: Tue, 31 Oct 2023 21:42:27 -0400
Subject: [PATCH 1/2] Implements llvm-readobj handling without tests yet.

Adds tests for llvm-readobj PGOBBAddrMap.

Updates readobj for the redesign with PGOAnalysisMap

Updates tests after moving PGO analyses to after each function.

Updates readobj with bitfield features.
---
 .../ELF/pgo-bb-addr-map-relocatable.test      | 210 ++++++++++++++++++
 .../llvm-readobj/ELF/pgo-bb-addr-map.test     | 205 +++++++++++++++++
 llvm/tools/llvm-readobj/ELFDumper.cpp         |  45 +++-
 llvm/tools/llvm-readobj/ObjDumper.h           |   2 +-
 llvm/tools/llvm-readobj/Opts.td               |   1 +
 llvm/tools/llvm-readobj/llvm-readobj.cpp      |   6 +-
 6 files changed, 458 insertions(+), 11 deletions(-)
 create mode 100644 llvm/test/tools/llvm-readobj/ELF/pgo-bb-addr-map-relocatable.test
 create mode 100644 llvm/test/tools/llvm-readobj/ELF/pgo-bb-addr-map.test

diff --git a/llvm/test/tools/llvm-readobj/ELF/pgo-bb-addr-map-relocatable.test b/llvm/test/tools/llvm-readobj/ELF/pgo-bb-addr-map-relocatable.test
new file mode 100644
index 000000000000000..7a8844b49d44394
--- /dev/null
+++ b/llvm/test/tools/llvm-readobj/ELF/pgo-bb-addr-map-relocatable.test
@@ -0,0 +1,210 @@
+## This test checks how we handle the --pgo-analysis-map option on relocatable
+## object files.
+
+## Fails on windows (https://github.com/llvm/llvm-project/issues/60013).
+# UNSUPPORTED: system-windows
+
+# RUN: yaml2obj %s -o %t1.o
+# RUN: llvm-readobj %t1.o --pgo-analysis-map | FileCheck %s
+
+# CHECK:      BBAddrMap [
+# CHECK-NEXT:   Function {
+# CHECK-NEXT:     At: 0x0
+# CHECK-NEXT:     Name: <?>
+# CHECK-NEXT:     EntryCount: 89
+# CHECK-NEXT:     BB entries [
+# CHECK-NEXT:       {
+# CHECK-NEXT:         ID: 0
+# CHECK-NEXT:         Offset: 0x0
+# CHECK-NEXT:         Size: 0xF
+# CHECK-NEXT:         HasReturn: Yes
+# CHECK-NEXT:         HasTailCall: No
+# CHECK-NEXT:         IsEHPad: No
+# CHECK-NEXT:         CanFallThrough: No
+# CHECK-NEXT:         HasIndirectBranch: No
+# CHECK-NEXT:         Frequency: 90
+# CHECK-NEXT:       }
+# CHECK-NEXT:     ]
+# CHECK-NEXT:   }
+# CHECK-NEXT:   Function {
+# CHECK-NEXT:     At: 0x10
+# CHECK-NEXT:     Name: <?>
+# CHECK-NEXT:     BB entries [
+# CHECK-NEXT:       {
+# CHECK-NEXT:         ID: 0
+# CHECK-NEXT:         Offset: 0x0
+# CHECK-NEXT:         Size: 0x11
+# CHECK-NEXT:         HasReturn: No
+# CHECK-NEXT:         HasTailCall: No
+# CHECK-NEXT:         IsEHPad: No
+# CHECK-NEXT:         CanFallThrough: Yes
+# CHECK-NEXT:         HasIndirectBranch: No
+# CHECK-NEXT:         Frequency: 123
+# CHECK-NEXT:       }
+# CHECK-NEXT:     ]
+# CHECK-NEXT:   }
+# CHECK-NEXT: ]
+
+--- !ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_X86_64
+Sections:
+  - Name:    .text
+    Type:    SHT_PROGBITS
+    Flags:   [ SHF_ALLOC, SHF_EXECINSTR ]
+  - Name:    .llvm_bb_addr_map
+    Type:    SHT_LLVM_BB_ADDR_MAP
+    Link:    .text
+    Entries:
+      - Version: 2
+        Feature: 0x3
+        BBEntries:
+          - ID:              0
+            AddressOffset:   0x0
+            Size:            0xF
+            Metadata:        0x1
+      - Version: 2
+        Feature: 0x2
+        BBEntries:
+          - ID:              0
+            AddressOffset:   0x0
+            Size:            0x11
+            Metadata:        0x8
+    PGOAnalyses:
+      - FuncEntryCount: 89
+        PGOBBEntries:
+          - BBFreq:          90
+      - PGOBBEntries:
+          - BBFreq:          123
+  - Name:  .rela.llvm_bb_addr_map
+    Type:  SHT_RELA
+    Flags: [ SHF_INFO_LINK ]
+    Link:  .symtab
+    Info:  .llvm_bb_addr_map
+    Relocations:
+      - Offset: 0x2
+        Symbol: .text
+        Type:   R_X86_64_64
+      - Offset: 0x13
+        Symbol: .text
+        Type:   R_X86_64_64
+        Addend: 16
+Symbols:
+  - Name:    a
+    Section: .text
+    Value:   0x0
+  - Name:    c
+    Section: .text
+    Value:   0x10
+  - Name:    .text
+    Type:    STT_SECTION
+    Section: .text
+
+## Check that we get a warning if we expect a relocation and it is not present.
+
+--- !ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_X86_64
+Sections:
+  - Name:    .text
+    Type:    SHT_PROGBITS
+    Flags:   [ SHF_ALLOC, SHF_EXECINSTR ]
+  - Name:    .llvm_bb_addr_map
+    Type:    SHT_LLVM_BB_ADDR_MAP
+    Link:    .text
+    Entries:
+      - Version: 2
+        Feature: 0x7
+        BBEntries:
+          - ID:              0
+            AddressOffset:   0x0
+            Size:            0xF
+            Metadata:        0x1
+    PGOAnalyses:
+      - FuncEntryCount: 2
+        PGOBBEntries:
+          - BBFreq:          2
+  - Name:  .rela.llvm_bb_addr_map
+    Type:  SHT_RELA
+    Flags: [ SHF_INFO_LINK ]
+    Info:  .llvm_bb_addr_map
+
+--- !ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_X86_64
+Sections:
+  - Name:  .rela.llvm_bb_addr_map
+    Type:  SHT_RELA
+    Flags: [ SHF_INFO_LINK ]
+    Info:  0xFF
+
+# RUN: yaml2obj %s --docnum=3 -o %t4.o
+# RUN: llvm-readobj %t4.o --pgo-analysis-map 2>&1 | FileCheck %s --check-prefix=NO-RELOCATED-SECTION -DFILE=%t4.o
+
+# NO-RELOCATED-SECTION: warning: '[[FILE]]': failed to get SHT_LLVM_BB_ADDR_MAP section(s): SHT_RELA section with index 1: failed to get a relocated section: invalid section index: 255
+
+## Check that if we have an ET_DYN file with a .rela.dyn section, we don't get
+## a warning about a missing relocation section and can get the baddrmap data.
+
+--- !ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_DYN
+  Machine:         EM_X86_64
+Sections:
+  - Name:            .rela.dyn
+    Type:            SHT_RELA
+    Flags:           [ SHF_ALLOC ]
+  - Name:            .llvm_bb_addr_map
+    Type:            SHT_LLVM_BB_ADDR_MAP
+    Flags:           [ SHF_LINK_ORDER ]
+    Entries:
+      - Version:         2
+        Feature:         0x7
+        Address:         0xF
+        BBEntries:
+          - ID:              0
+            AddressOffset:   0x0
+            Size:            0xF
+            Metadata:        0x1
+    PGOAnalyses:
+      - FuncEntryCount: 100
+        PGOBBEntries:
+          - BBFreq:          100
+            Successors:      []
+
+# RUN: yaml2obj %s --docnum=4 -o %t5.o
+# RUN: llvm-readobj %t5.o --pgo-analysis-map | FileCheck %s --check-prefix=ET-DYN-NO-WARNING -DFILE=%t5.o
+
+# ET-DYN-NO-WARNING:      BBAddrMap [
+# ET-DYN-NO-WARNING-NEXT:   Function {
+# ET-DYN-NO-WARNING-NEXT:     At: 0xF
+# ET-DYN-NO-WARNING-NEXT:     Name: <?>
+# ET-DYN-NO-WARNING-NEXT:     EntryCount: 100
+# ET-DYN-NO-WARNING-NEXT:     BB entries [
+# ET-DYN-NO-WARNING-NEXT:       {
+# ET-DYN-NO-WARNING-NEXT:         ID: 0
+# ET-DYN-NO-WARNING-NEXT:         Offset: 0x0
+# ET-DYN-NO-WARNING-NEXT:         Size: 0xF
+# ET-DYN-NO-WARNING-NEXT:         HasReturn: Yes
+# ET-DYN-NO-WARNING-NEXT:         HasTailCall: No
+# ET-DYN-NO-WARNING-NEXT:         IsEHPad: No
+# ET-DYN-NO-WARNING-NEXT:         CanFallThrough: No
+# ET-DYN-NO-WARNING-NEXT:         HasIndirectBranch: No
+# ET-DYN-NO-WARNING-NEXT:         Frequency: 100
+# ET-DYN-NO-WARNING-NEXT:         Successors [
+# ET-DYN-NO-WARNING-NEXT:         ]
+# ET-DYN-NO-WARNING-NEXT:       }
+# ET-DYN-NO-WARNING-NEXT:     ]
+# ET-DYN-NO-WARNING-NEXT:   }
+# ET-DYN-NO-WARNING-NEXT: ]
diff --git a/llvm/test/tools/llvm-readobj/ELF/pgo-bb-addr-map.test b/llvm/test/tools/llvm-readobj/ELF/pgo-bb-addr-map.test
new file mode 100644
index 000000000000000..05ae4730108159f
--- /dev/null
+++ b/llvm/test/tools/llvm-readobj/ELF/pgo-bb-addr-map.test
@@ -0,0 +1,205 @@
+## This test checks how we handle the --pgo-analysis-map option.
+
+## Fails on windows (https://github.com/llvm/llvm-project/issues/60013).
+# UNSUPPORTED: system-windows
+
+## Check 64-bit:
+# RUN: yaml2obj --docnum=1 %s -DBITS=64 -DADDR=0x999999999 -o %t1.x64.o
+# RUN: llvm-readobj %t1.x64.o --pgo-analysis-map 2>&1 | FileCheck %s -DADDR=0x999999999 -DFILE=%t1.x64.o --check-prefix=CHECK
+# RUN: llvm-readelf %t1.x64.o --pgo-analysis-map | FileCheck %s --check-prefix=GNU
+
+## Check 64-bit:
+# RUN: yaml2obj --docnum=1 %s -DBITS=64 -DADDR=0x999999999 -o %t1.v1.x64.o
+# RUN: llvm-readobj %t1.v1.x64.o --pgo-analysis-map 2>&1 | FileCheck %s -DADDR=0x999999999 -DFILE=%t1.v1.x64.o --check-prefix=CHECK
+
+## Check 32-bit:
+# RUN: yaml2obj --docnum=1 %s -DBITS=32 -o %t1.x32.o
+# RUN: llvm-readobj %t1.x32.o --pgo-analysis-map 2>&1 | FileCheck -DADDR=0x11111 %s -DFILE=%t1.x32.o --check-prefix=CHECK
+# RUN: llvm-readelf %t1.x32.o --pgo-analysis-map | FileCheck %s --check-prefix=GNU
+
+## Check that a malformed section can be handled.
+# RUN: yaml2obj --docnum=1 %s -DBITS=32 -DSIZE=6 -o %t2.o
+# RUN: llvm-readobj %t2.o --pgo-analysis-map 2>&1 | FileCheck %s -DOFFSET=0x00000006 -DFILE=%t2.o --check-prefix=TRUNCATED
+
+## Check that invalid metadata can be handled.
+# RUN: yaml2obj --docnum=1 %s -DBITS=32 -DMETADATA=0xF000002 -o %t3.o
+# RUN: llvm-readobj %t3.o --pgo-analysis-map 2>&1 | FileCheck %s -DFILE=%t3.o --check-prefix=INVALIDMD
+
+# CHECK:      BBAddrMap [
+# CHECK-NEXT:   Function {
+# CHECK-NEXT:     At: [[ADDR]]
+# CHECK-NEXT: warning: '[[FILE]]': could not identify function symbol for address ([[ADDR]]) in SHT_LLVM_BB_ADDR_MAP section with index 3
+# CHECK-NEXT:     Name: <?>
+# CHECK-NEXT:     EntryCount: 100
+# CHECK-NEXT:     BB entries [
+# CHECK-NEXT:       {
+# CHECK-NEXT:         ID: 0
+# CHECK-NEXT:         Offset: 0x0
+# CHECK-NEXT:         Size: 0x1
+# CHECK-NEXT:         HasReturn: No
+# CHECK-NEXT:         HasTailCall: Yes
+# CHECK-NEXT:         IsEHPad: No
+# CHECK-NEXT:         CanFallThrough: No
+# CHECK-NEXT:         HasIndirectBranch: No
+# CHECK-NEXT:         Frequency: 100
+# CHECK-NEXT:         Successors [
+# CHECK-NEXT:           {
+# CHECK-NEXT:             ID: 2
+# CHECK-NEXT:             Probability: 0xFFFFFFFF
+# CHECK-NEXT:           }
+# CHECK-NEXT:         ]
+# CHECK-NEXT:       }
+# CHECK-NEXT:       {
+# CHECK-NEXT:         ID: 2
+# CHECK-NEXT:         Offset: 0x4
+# CHECK-NEXT:         Size: 0x4
+# CHECK-NEXT:         HasReturn: Yes
+# CHECK-NEXT:         HasTailCall: No
+# CHECK-NEXT:         IsEHPad: Yes
+# CHECK-NEXT:         CanFallThrough: No
+# CHECK-NEXT:         HasIndirectBranch: Yes
+# CHECK-NEXT:         Frequency: 100
+# CHECK-NEXT:         Successors [
+# CHECK-NEXT:         ]
+# CHECK-NEXT:       }
+# CHECK-NEXT:     ]
+# CHECK-NEXT:   }
+# CHECK-NEXT:   Function {
+# CHECK-NEXT:     At: 0x22222
+# CHECK-NEXT:     Name: foo
+# CHECK-NEXT:     EntryCount: 8888
+# CHECK-NEXT:     BB entries [
+# CHECK-NEXT:       {
+# CHECK-NEXT:         ID: 4
+# CHECK-NEXT:         Offset: 0x6
+# CHECK-NEXT:         Size: 0x7
+# CHECK-NEXT:         HasReturn: No
+# CHECK-NEXT:         HasTailCall: No
+# CHECK-NEXT:         IsEHPad: No
+# CHECK-NEXT:         CanFallThrough: Yes
+# CHECK-NEXT:         HasIndirectBranch: No
+# CHECK-NEXT:         Frequency: 9000
+# CHECK-NEXT:       }
+# CHECK-NEXT:     ]
+# CHECK-NEXT:   }
+# CHECK-NEXT: ]
+
+# GNU: GNUStyle::printBBAddrMaps not implemented
+
+# TRUNCATED:      BBAddrMap [
+# TRUNCATED-NEXT:   warning: '[[FILE]]': unable to dump SHT_LLVM_BB_ADDR_MAP section with index 3: unable to decode LEB128 at offset [[OFFSET]]: malformed uleb128, extends past end
+# TRUNCATED-NEXT: ]
+## Check that the other valid section is properly dumped.
+# TRUNCATED-NEXT: BBAddrMap [
+# TRUNCATED-NEXT:   Function {
+# TRUNCATED-NEXT:     At: 0x33333
+# TRUNCATED-NEXT:     Name: bar
+# TRUNCATED-NEXT:     EntryCount: 89
+# TRUNCATED-NEXT:     BB entries [
+# TRUNCATED-NEXT:       {
+# TRUNCATED-NEXT:         ID: 6
+# TRUNCATED-NEXT:         Offset: 0x9
+# TRUNCATED-NEXT:         Size: 0xA
+# TRUNCATED-NEXT:         HasReturn: Yes
+# TRUNCATED-NEXT:         HasTailCall: Yes
+# TRUNCATED-NEXT:         IsEHPad: No
+# TRUNCATED-NEXT:         CanFallThrough: Yes
+# TRUNCATED-NEXT:         HasIndirectBranch: Yes
+# TRUNCATED-NEXT:       }
+# TRUNCATED-NEXT:       {
+# TRUNCATED-NEXT:         ID: 7
+# TRUNCATED-NEXT:         Offset: 0x1F
+# TRUNCATED-NEXT:         Size: 0xD
+# TRUNCATED-NEXT:         HasReturn: No
+# TRUNCATED-NEXT:         HasTailCall: Yes
+# TRUNCATED-NEXT:         IsEHPad: Yes
+# TRUNCATED-NEXT:         CanFallThrough: Yes
+# TRUNCATED-NEXT:         HasIndirectBranch: No
+# TRUNCATED-NEXT:       }
+# TRUNCATED-NEXT:     ]
+# TRUNCATED-NEXT:   }
+# TRUNCATED-NEXT: ]
+
+# INVALIDMD:      BBAddrMap [
+# INVALIDMD-NEXT:   warning: '[[FILE]]': unable to dump SHT_LLVM_BB_ADDR_MAP section with index 3: invalid encoding for BBEntry::Metadata: 0xf000002
+
+--- !ELF
+FileHeader:
+  Class: ELFCLASS[[BITS]]
+  Data:  ELFDATA2LSB
+  Type:  ET_EXEC
+Sections:
+  - Name:   .text
+    Type:   SHT_PROGBITS
+    Flags:  [SHF_ALLOC]
+  - Name:   .text.bar
+    Type:   SHT_PROGBITS
+    Flags:  [SHF_ALLOC]
+  - Name:   .llvm_bb_addr_map
+    Type:   SHT_LLVM_BB_ADDR_MAP
+    ShSize: [[SIZE=<none>]]
+    Link:   .text
+    Entries:
+      - Version: 2
+        Feature: 0x7
+        Address: [[ADDR=0x11111]]
+        BBEntries:
+          - ID:            0
+            AddressOffset: 0x0
+            Size:          0x1
+            Metadata:      [[METADATA=0x2]]
+          - ID:            2
+            AddressOffset: 0x3
+            Size:          0x4
+            Metadata:      0x15
+      - Version: 2
+        Feature: 0x3
+        Address: 0x22222
+        BBEntries:
+          - ID:            4
+            AddressOffset: 0x6
+            Size:          0x7
+            Metadata:      0x8
+    PGOAnalyses:
+      - FuncEntryCount: 100
+        PGOBBEntries:
+          - BBFreq:        100
+            Successors:
+              - ID:        2
+                BrProb:    0xFFFFFFFF
+          - BBFreq:        100
+            Successors:    []
+      - FuncEntryCount: 8888
+        PGOBBEntries:
+          - BBFreq:        9000
+  - Name: dummy_section
+    Type: SHT_PROGBITS
+    Size: 16
+  - Name: '.llvm_bb_addr_map (1)'
+    Type: SHT_LLVM_BB_ADDR_MAP
+    Link: .text.bar
+    Entries:
+      - Version: 2
+        Feature: 0x1
+        Address: 0x33333
+        BBEntries:
+          - ID:            6
+            AddressOffset: 0x9
+            Size:          0xa
+            Metadata:      0x1b
+          - ID:            7
+            AddressOffset: 0xc
+            Size:          0xd
+            Metadata:      0xe
+    PGOAnalyses:
+      - FuncEntryCount: 89
+Symbols:
+  - Name:    foo
+    Section: .text
+    Type:    STT_FUNC
+    Value:   0x22222
+  - Name:    bar
+    Section: .text.bar
+    Type:    STT_FUNC
+    Value:   0x33333
+
diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp
index f369a63add1149b..3b32d9805277759 100644
--- a/llvm/tools/llvm-readobj/ELFDumper.cpp
+++ b/llvm/tools/llvm-readobj/ELFDumper.cpp
@@ -593,7 +593,7 @@ template <typename ELFT> class GNUELFDumper : public ELFDumper<ELFT> {
   void printVersionDefinitionSection(const Elf_Shdr *Sec) override;
   void printVersionDependencySection(const Elf_Shdr *Sec) override;
   void printCGProfile() override;
-  void printBBAddrMaps() override;
+  void printBBAddrMaps(bool IncludePGOAnalysis = false) override;
   void printAddrsig() override;
   void printNotes() override;
   void printELFLinkerOptions() override;
@@ -704,7 +704,7 @@ template <typename ELFT> class LLVMELFDumper : public ELFDumper<ELFT> {
   void printVersionDefinitionSection(const Elf_Shdr *Sec) override;
   void printVersionDependencySection(const Elf_Shdr *Sec) override;
   void printCGProfile() override;
-  void printBBAddrMaps() override;
+  void printBBAddrMaps(bool IncludePGOAnalysis = false) override;
   void printAddrsig() override;
   void printNotes() override;
   void printELFLinkerOptions() override;
@@ -739,6 +739,8 @@ template <typename ELFT> class LLVMELFDumper : public ELFDumper<ELFT> {
   void printMipsABIFlags() override;
   virtual void printZeroSymbolOtherField(const Elf_Sym &Symbol) const;
 
+  template<typename AddrMap> void printAddrMaps();
+
 protected:
   virtual std::string getGroupSectionHeaderName() const;
   void printSymbolOtherField(const Elf_Sym &Symbol) const;
@@ -5070,7 +5072,8 @@ template <class ELFT> void GNUELFDumper<ELFT>::printCGProfile() {
   OS << "GNUStyle::printCGProfile not implemented\n";
 }
 
-template <class ELFT> void GNUELFDumper<ELFT>::printBBAddrMaps() {
+template <class ELFT>
+void GNUELFDumper<ELFT>::printBBAddrMaps(bool IncludePGOAnalysis) {
   OS << "GNUStyle::printBBAddrMaps not implemented\n";
 }
 
@@ -7541,7 +7544,8 @@ template <class ELFT> void LLVMELFDumper<ELFT>::printCGProfile() {
   }
 }
 
-template <class ELFT> void LLVMELFDumper<ELFT>::printBBAddrMaps() {
+template <class ELFT>
+void LLVMELFDumper<ELFT>::printBBAddrMaps(bool IncludePGOAnalysis) {
   bool IsRelocatable = this->Obj.getHeader().e_type == ELF::ET_REL;
   using Elf_Shdr = typename ELFT::Shdr;
   auto IsMatch = [](const Elf_Shdr &Sec) -> bool {
@@ -7567,14 +7571,16 @@ template <class ELFT> void LLVMELFDumper<ELFT>::printBBAddrMaps() {
                                 this->describe(*Sec));
       continue;
     }
-    Expected<std::vector<BBAddrMap>> BBAddrMapOrErr =
-        this->Obj.decodeBBAddrMap(*Sec, RelocSec);
+    std::vector<PGOAnalysisMap> PGOAnalysis;
+    Expected<std::vector<BBAddrMap>> BBAddrMapOrErr = this->Obj.decodeBBAddrMap(
+        *Sec, RelocSec, IncludePGOAnalysis ? &PGOAnalysis : nullptr);
     if (!BBAddrMapOrErr) {
       this->reportUniqueWarning("unable to dump " + this->describe(*Sec) +
                                 ": " + toString(BBAddrMapOrErr.takeError()));
       continue;
     }
-    for (const BBAddrMap &AM : *BBAddrMapOrErr) {
+    for (const auto &[Idx, AM] : llvm::enumerate(*BBAddrMapOrErr)) {
+      const auto *PAM = IncludePGOAnalysis ? &PGOAnalysis[Idx] : nullptr;
       DictScope D(W, "Function");
       W.printHex("At", AM.Addr);
       SmallVector<uint32_t> FuncSymIndex =
@@ -7587,9 +7593,14 @@ template <class ELFT> void LLVMELFDumper<ELFT>::printBBAddrMaps() {
       else
         FuncName = this->getStaticSymbolName(FuncSymIndex.front());
       W.printString("Name", FuncName);
+      if (IncludePGOAnalysis && PAM->FeatEnable.FuncEntryCount)
+        W.printNumber("EntryCount", PAM->FuncEntryCount);
 
+      bool IncludePGOBBData =
+          IncludePGOAnalysis && PAM->BBEntries.size() == AM.BBEntries.size();
       ListScope L(W, "BB entries");
-      for (const BBAddrMap::BBEntry &BBE : AM.BBEntries) {
+      for (const auto &[BIdx, BBE] : llvm::enumerate(AM.BBEntries)) {
+        const auto *PBBE = IncludePGOBBData ? &PAM->BBEntries[BIdx] : nullptr;
         DictScope L(W);
         W.printNumber("ID", BBE.ID);
         W.printHex("Offset", BBE.Offset);
@@ -7599,6 +7610,24 @@ template <class ELFT> void LLVMELFDumper<ELFT>::printBBAddrMaps() {
         W.printBoolean("IsEHPad", BBE.isEHPad());
         W.printBoolean("CanFallThrough", BBE.canFallThrough());
         W.printBoolean("HasIndirectBranch", BBE.hasIndirectBranch());
+
+        /// FIXME: currently we just emit the raw frequency, it may be better to
+        /// provide an option to scale it by the first entry frequence using
+        /// BlockFrequency::Scaled64 number
+        if (IncludePGOBBData && PAM->FeatEnable.BBFreq)
+          W.printNumber("Frequency", PBBE->BlockFreq.getFrequency());
+
+        if (IncludePGOBBData && PAM->FeatEnable.BrProb) {
+          ListScope L(W, "Successors");
+          for (const auto &Succ : PBBE->Successors) {
+            DictScope L(W);
+            W.printNumber("ID", Succ.ID);
+            /// FIXME: currently we just emit the raw numerator of the probably,
+            /// it may be better to provide an option to emit it as a percentage
+            /// or other prettied representation
+            W.printHex("Probability", Succ.Prob.getNumerator());
+          }
+        }
       }
     }
   }
diff --git a/llvm/tools/llvm-readobj/ObjDumper.h b/llvm/tools/llvm-readobj/ObjDumper.h
index 1d679453581bc84..082aba80841c6b6 100644
--- a/llvm/tools/llvm-readobj/ObjDumper.h
+++ b/llvm/tools/llvm-readobj/ObjDumper.h
@@ -129,7 +129,7 @@ class ObjDumper {
   virtual void printGroupSections() {}
   virtual void printHashHistograms() {}
   virtual void printCGProfile() {}
-  virtual void printBBAddrMaps() {}
+  virtual void printBBAddrMaps(bool IncludePGOAnalysis = false) {}
   virtual void printAddrsig() {}
   virtual void printNotes() {}
   virtual void printELFLinkerOptions() {}
diff --git a/llvm/tools/llvm-readobj/Opts.td b/llvm/tools/llvm-readobj/Opts.td
index e2d93c6ec229e9f..a981fac2f2f3650 100644
--- a/llvm/tools/llvm-readobj/Opts.td
+++ b/llvm/tools/llvm-readobj/Opts.td
@@ -29,6 +29,7 @@ def extra_sym_info : FF<"extra-sym-info", "Display extra information when showin
 def file_header : FF<"file-header", "Display file header">;
 def headers : FF<"headers", "Equivalent to setting: --file-header, --program-headers, --section-headers">;
 defm hex_dump : Eq<"hex-dump", "Display the specified section(s) as hexadecimal bytes">, MetaVarName<"<name or index>">;
+def pgo_analysis_map : FF<"pgo-analysis-map", "Display the BB address map section with PGO data included">;
 def pretty_print : FF<"pretty-print", "Pretty print JSON output">;
 def relocs : FF<"relocs", "Display the relocation entries in the file">;
 def section_data : FF<"section-data", "Display section data for each section shown. This option has no effect for GNU style output">;
diff --git a/llvm/tools/llvm-readobj/llvm-readobj.cpp b/llvm/tools/llvm-readobj/llvm-readobj.cpp
index f9d605d35244bf3..4dcab4ce5c9f74d 100644
--- a/llvm/tools/llvm-readobj/llvm-readobj.cpp
+++ b/llvm/tools/llvm-readobj/llvm-readobj.cpp
@@ -95,6 +95,7 @@ static bool Addrsig;
 static bool All;
 static bool ArchSpecificInfo;
 static bool BBAddrMap;
+static bool PGOAnalysisMap;
 bool ExpandRelocs;
 static bool CGProfile;
 bool Demangle;
@@ -211,6 +212,7 @@ static void parseOptions(const opt::InputArgList &Args) {
   opts::All = Args.hasArg(OPT_all);
   opts::ArchSpecificInfo = Args.hasArg(OPT_arch_specific);
   opts::BBAddrMap = Args.hasArg(OPT_bb_addr_map);
+  opts::PGOAnalysisMap = Args.hasArg(OPT_pgo_analysis_map);
   opts::CGProfile = Args.hasArg(OPT_cg_profile);
   opts::Demangle = Args.hasFlag(OPT_demangle, OPT_no_demangle, false);
   opts::DependentLibraries = Args.hasArg(OPT_dependent_libraries);
@@ -463,8 +465,8 @@ static void dumpObject(ObjectFile &Obj, ScopedPrinter &Writer,
       Dumper->printHashHistograms();
     if (opts::CGProfile)
       Dumper->printCGProfile();
-    if (opts::BBAddrMap)
-      Dumper->printBBAddrMaps();
+    if (opts::BBAddrMap || opts::PGOAnalysisMap)
+      Dumper->printBBAddrMaps(opts::PGOAnalysisMap);
     if (opts::Addrsig)
       Dumper->printAddrsig();
     if (opts::Notes)

>From c036ea8331dce425d05515ed06073b520ba7e3ce Mon Sep 17 00:00:00 2001
From: Micah Weston <micahsweston at gmail.com>
Date: Thu, 25 Jan 2024 18:20:38 -0500
Subject: [PATCH 2/2] Updates to pgo-analysis-map and always prints.

---
 ...test => bb-addr-map-pgo-analysis-map.test} |  60 +++--
 .../ELF/pgo-bb-addr-map-relocatable.test      | 210 ------------------
 llvm/tools/llvm-readobj/ELFDumper.cpp         |  96 ++++----
 llvm/tools/llvm-readobj/ObjDumper.h           |   2 +-
 llvm/tools/llvm-readobj/Opts.td               |   1 -
 llvm/tools/llvm-readobj/llvm-readobj.cpp      |   6 +-
 6 files changed, 92 insertions(+), 283 deletions(-)
 rename llvm/test/tools/llvm-readobj/ELF/{pgo-bb-addr-map.test => bb-addr-map-pgo-analysis-map.test} (75%)
 delete mode 100644 llvm/test/tools/llvm-readobj/ELF/pgo-bb-addr-map-relocatable.test

diff --git a/llvm/test/tools/llvm-readobj/ELF/pgo-bb-addr-map.test b/llvm/test/tools/llvm-readobj/ELF/bb-addr-map-pgo-analysis-map.test
similarity index 75%
rename from llvm/test/tools/llvm-readobj/ELF/pgo-bb-addr-map.test
rename to llvm/test/tools/llvm-readobj/ELF/bb-addr-map-pgo-analysis-map.test
index 05ae4730108159f..fad2cca1990a49b 100644
--- a/llvm/test/tools/llvm-readobj/ELF/pgo-bb-addr-map.test
+++ b/llvm/test/tools/llvm-readobj/ELF/bb-addr-map-pgo-analysis-map.test
@@ -1,36 +1,35 @@
-## This test checks how we handle the --pgo-analysis-map option.
+## This test checks how we handle PGO Analysis Map in --bb-addr-map.
 
 ## Fails on windows (https://github.com/llvm/llvm-project/issues/60013).
 # UNSUPPORTED: system-windows
 
 ## Check 64-bit:
 # RUN: yaml2obj --docnum=1 %s -DBITS=64 -DADDR=0x999999999 -o %t1.x64.o
-# RUN: llvm-readobj %t1.x64.o --pgo-analysis-map 2>&1 | FileCheck %s -DADDR=0x999999999 -DFILE=%t1.x64.o --check-prefix=CHECK
-# RUN: llvm-readelf %t1.x64.o --pgo-analysis-map | FileCheck %s --check-prefix=GNU
+# RUN: llvm-readobj %t1.x64.o --bb-addr-map 2>&1 | FileCheck %s -DADDR=0x999999999 -DFILE=%t1.x64.o --check-prefix=CHECK
+# RUN: llvm-readelf %t1.x64.o --bb-addr-map | FileCheck %s --check-prefix=GNU
 
 ## Check 64-bit:
 # RUN: yaml2obj --docnum=1 %s -DBITS=64 -DADDR=0x999999999 -o %t1.v1.x64.o
-# RUN: llvm-readobj %t1.v1.x64.o --pgo-analysis-map 2>&1 | FileCheck %s -DADDR=0x999999999 -DFILE=%t1.v1.x64.o --check-prefix=CHECK
+# RUN: llvm-readobj %t1.v1.x64.o --bb-addr-map 2>&1 | FileCheck %s -DADDR=0x999999999 -DFILE=%t1.v1.x64.o --check-prefix=CHECK
 
 ## Check 32-bit:
 # RUN: yaml2obj --docnum=1 %s -DBITS=32 -o %t1.x32.o
-# RUN: llvm-readobj %t1.x32.o --pgo-analysis-map 2>&1 | FileCheck -DADDR=0x11111 %s -DFILE=%t1.x32.o --check-prefix=CHECK
-# RUN: llvm-readelf %t1.x32.o --pgo-analysis-map | FileCheck %s --check-prefix=GNU
+# RUN: llvm-readobj %t1.x32.o --bb-addr-map 2>&1 | FileCheck -DADDR=0x11111 %s -DFILE=%t1.x32.o --check-prefix=CHECK
+# RUN: llvm-readelf %t1.x32.o --bb-addr-map | FileCheck %s --check-prefix=GNU
 
 ## Check that a malformed section can be handled.
 # RUN: yaml2obj --docnum=1 %s -DBITS=32 -DSIZE=6 -o %t2.o
-# RUN: llvm-readobj %t2.o --pgo-analysis-map 2>&1 | FileCheck %s -DOFFSET=0x00000006 -DFILE=%t2.o --check-prefix=TRUNCATED
+# RUN: llvm-readobj %t2.o --bb-addr-map 2>&1 | FileCheck %s -DOFFSET=0x00000006 -DFILE=%t2.o --check-prefix=TRUNCATED
 
 ## Check that invalid metadata can be handled.
 # RUN: yaml2obj --docnum=1 %s -DBITS=32 -DMETADATA=0xF000002 -o %t3.o
-# RUN: llvm-readobj %t3.o --pgo-analysis-map 2>&1 | FileCheck %s -DFILE=%t3.o --check-prefix=INVALIDMD
+# RUN: llvm-readobj %t3.o --bb-addr-map 2>&1 | FileCheck %s -DFILE=%t3.o --check-prefix=INVALIDMD
 
 # CHECK:      BBAddrMap [
 # CHECK-NEXT:   Function {
 # CHECK-NEXT:     At: [[ADDR]]
 # CHECK-NEXT: warning: '[[FILE]]': could not identify function symbol for address ([[ADDR]]) in SHT_LLVM_BB_ADDR_MAP section with index 3
 # CHECK-NEXT:     Name: <?>
-# CHECK-NEXT:     EntryCount: 100
 # CHECK-NEXT:     BB entries [
 # CHECK-NEXT:       {
 # CHECK-NEXT:         ID: 0
@@ -41,13 +40,6 @@
 # CHECK-NEXT:         IsEHPad: No
 # CHECK-NEXT:         CanFallThrough: No
 # CHECK-NEXT:         HasIndirectBranch: No
-# CHECK-NEXT:         Frequency: 100
-# CHECK-NEXT:         Successors [
-# CHECK-NEXT:           {
-# CHECK-NEXT:             ID: 2
-# CHECK-NEXT:             Probability: 0xFFFFFFFF
-# CHECK-NEXT:           }
-# CHECK-NEXT:         ]
 # CHECK-NEXT:       }
 # CHECK-NEXT:       {
 # CHECK-NEXT:         ID: 2
@@ -58,16 +50,31 @@
 # CHECK-NEXT:         IsEHPad: Yes
 # CHECK-NEXT:         CanFallThrough: No
 # CHECK-NEXT:         HasIndirectBranch: Yes
-# CHECK-NEXT:         Frequency: 100
-# CHECK-NEXT:         Successors [
-# CHECK-NEXT:         ]
 # CHECK-NEXT:       }
 # CHECK-NEXT:     ]
+# CHECK-NEXT:     PGO analyses {
+# CHECK-NEXT:       FuncEntryCount: 100
+# CHECK-NEXT:       PGO BB entries [
+# CHECK-NEXT:         {
+# CHECK-NEXT:           Frequency: 100
+# CHECK-NEXT:           Successors [
+# CHECK-NEXT:             {
+# CHECK-NEXT:               ID: 2
+# CHECK-NEXT:               Probability: 0xFFFFFFFF
+# CHECK-NEXT:             }
+# CHECK-NEXT:           ]
+# CHECK-NEXT:         }
+# CHECK-NEXT:         {
+# CHECK-NEXT:           Frequency: 100
+# CHECK-NEXT:           Successors [
+# CHECK-NEXT:           ]
+# CHECK-NEXT:         }
+# CHECK-NEXT:       ]
+# CHECK-NEXT:     }
 # CHECK-NEXT:   }
 # CHECK-NEXT:   Function {
 # CHECK-NEXT:     At: 0x22222
 # CHECK-NEXT:     Name: foo
-# CHECK-NEXT:     EntryCount: 8888
 # CHECK-NEXT:     BB entries [
 # CHECK-NEXT:       {
 # CHECK-NEXT:         ID: 4
@@ -78,9 +85,16 @@
 # CHECK-NEXT:         IsEHPad: No
 # CHECK-NEXT:         CanFallThrough: Yes
 # CHECK-NEXT:         HasIndirectBranch: No
-# CHECK-NEXT:         Frequency: 9000
 # CHECK-NEXT:       }
 # CHECK-NEXT:     ]
+# CHECK-NEXT:     PGO analyses {
+# CHECK-NEXT:       FuncEntryCount: 8888
+# CHECK-NEXT:       PGO BB entries [
+# CHECK-NEXT:         {
+# CHECK-NEXT:           Frequency: 9000
+# CHECK-NEXT:         }
+# CHECK-NEXT:       ]
+# CHECK-NEXT:     }
 # CHECK-NEXT:   }
 # CHECK-NEXT: ]
 
@@ -94,7 +108,6 @@
 # TRUNCATED-NEXT:   Function {
 # TRUNCATED-NEXT:     At: 0x33333
 # TRUNCATED-NEXT:     Name: bar
-# TRUNCATED-NEXT:     EntryCount: 89
 # TRUNCATED-NEXT:     BB entries [
 # TRUNCATED-NEXT:       {
 # TRUNCATED-NEXT:         ID: 6
@@ -117,6 +130,9 @@
 # TRUNCATED-NEXT:         HasIndirectBranch: No
 # TRUNCATED-NEXT:       }
 # TRUNCATED-NEXT:     ]
+# TRUNCATED-NEXT:     PGO analyses {
+# TRUNCATED-NEXT:       FuncEntryCount: 89
+# TRUNCATED-NEXT:     }
 # TRUNCATED-NEXT:   }
 # TRUNCATED-NEXT: ]
 
diff --git a/llvm/test/tools/llvm-readobj/ELF/pgo-bb-addr-map-relocatable.test b/llvm/test/tools/llvm-readobj/ELF/pgo-bb-addr-map-relocatable.test
deleted file mode 100644
index 7a8844b49d44394..000000000000000
--- a/llvm/test/tools/llvm-readobj/ELF/pgo-bb-addr-map-relocatable.test
+++ /dev/null
@@ -1,210 +0,0 @@
-## This test checks how we handle the --pgo-analysis-map option on relocatable
-## object files.
-
-## Fails on windows (https://github.com/llvm/llvm-project/issues/60013).
-# UNSUPPORTED: system-windows
-
-# RUN: yaml2obj %s -o %t1.o
-# RUN: llvm-readobj %t1.o --pgo-analysis-map | FileCheck %s
-
-# CHECK:      BBAddrMap [
-# CHECK-NEXT:   Function {
-# CHECK-NEXT:     At: 0x0
-# CHECK-NEXT:     Name: <?>
-# CHECK-NEXT:     EntryCount: 89
-# CHECK-NEXT:     BB entries [
-# CHECK-NEXT:       {
-# CHECK-NEXT:         ID: 0
-# CHECK-NEXT:         Offset: 0x0
-# CHECK-NEXT:         Size: 0xF
-# CHECK-NEXT:         HasReturn: Yes
-# CHECK-NEXT:         HasTailCall: No
-# CHECK-NEXT:         IsEHPad: No
-# CHECK-NEXT:         CanFallThrough: No
-# CHECK-NEXT:         HasIndirectBranch: No
-# CHECK-NEXT:         Frequency: 90
-# CHECK-NEXT:       }
-# CHECK-NEXT:     ]
-# CHECK-NEXT:   }
-# CHECK-NEXT:   Function {
-# CHECK-NEXT:     At: 0x10
-# CHECK-NEXT:     Name: <?>
-# CHECK-NEXT:     BB entries [
-# CHECK-NEXT:       {
-# CHECK-NEXT:         ID: 0
-# CHECK-NEXT:         Offset: 0x0
-# CHECK-NEXT:         Size: 0x11
-# CHECK-NEXT:         HasReturn: No
-# CHECK-NEXT:         HasTailCall: No
-# CHECK-NEXT:         IsEHPad: No
-# CHECK-NEXT:         CanFallThrough: Yes
-# CHECK-NEXT:         HasIndirectBranch: No
-# CHECK-NEXT:         Frequency: 123
-# CHECK-NEXT:       }
-# CHECK-NEXT:     ]
-# CHECK-NEXT:   }
-# CHECK-NEXT: ]
-
---- !ELF
-FileHeader:
-  Class:           ELFCLASS64
-  Data:            ELFDATA2LSB
-  Type:            ET_REL
-  Machine:         EM_X86_64
-Sections:
-  - Name:    .text
-    Type:    SHT_PROGBITS
-    Flags:   [ SHF_ALLOC, SHF_EXECINSTR ]
-  - Name:    .llvm_bb_addr_map
-    Type:    SHT_LLVM_BB_ADDR_MAP
-    Link:    .text
-    Entries:
-      - Version: 2
-        Feature: 0x3
-        BBEntries:
-          - ID:              0
-            AddressOffset:   0x0
-            Size:            0xF
-            Metadata:        0x1
-      - Version: 2
-        Feature: 0x2
-        BBEntries:
-          - ID:              0
-            AddressOffset:   0x0
-            Size:            0x11
-            Metadata:        0x8
-    PGOAnalyses:
-      - FuncEntryCount: 89
-        PGOBBEntries:
-          - BBFreq:          90
-      - PGOBBEntries:
-          - BBFreq:          123
-  - Name:  .rela.llvm_bb_addr_map
-    Type:  SHT_RELA
-    Flags: [ SHF_INFO_LINK ]
-    Link:  .symtab
-    Info:  .llvm_bb_addr_map
-    Relocations:
-      - Offset: 0x2
-        Symbol: .text
-        Type:   R_X86_64_64
-      - Offset: 0x13
-        Symbol: .text
-        Type:   R_X86_64_64
-        Addend: 16
-Symbols:
-  - Name:    a
-    Section: .text
-    Value:   0x0
-  - Name:    c
-    Section: .text
-    Value:   0x10
-  - Name:    .text
-    Type:    STT_SECTION
-    Section: .text
-
-## Check that we get a warning if we expect a relocation and it is not present.
-
---- !ELF
-FileHeader:
-  Class:           ELFCLASS64
-  Data:            ELFDATA2LSB
-  Type:            ET_REL
-  Machine:         EM_X86_64
-Sections:
-  - Name:    .text
-    Type:    SHT_PROGBITS
-    Flags:   [ SHF_ALLOC, SHF_EXECINSTR ]
-  - Name:    .llvm_bb_addr_map
-    Type:    SHT_LLVM_BB_ADDR_MAP
-    Link:    .text
-    Entries:
-      - Version: 2
-        Feature: 0x7
-        BBEntries:
-          - ID:              0
-            AddressOffset:   0x0
-            Size:            0xF
-            Metadata:        0x1
-    PGOAnalyses:
-      - FuncEntryCount: 2
-        PGOBBEntries:
-          - BBFreq:          2
-  - Name:  .rela.llvm_bb_addr_map
-    Type:  SHT_RELA
-    Flags: [ SHF_INFO_LINK ]
-    Info:  .llvm_bb_addr_map
-
---- !ELF
-FileHeader:
-  Class:           ELFCLASS64
-  Data:            ELFDATA2LSB
-  Type:            ET_REL
-  Machine:         EM_X86_64
-Sections:
-  - Name:  .rela.llvm_bb_addr_map
-    Type:  SHT_RELA
-    Flags: [ SHF_INFO_LINK ]
-    Info:  0xFF
-
-# RUN: yaml2obj %s --docnum=3 -o %t4.o
-# RUN: llvm-readobj %t4.o --pgo-analysis-map 2>&1 | FileCheck %s --check-prefix=NO-RELOCATED-SECTION -DFILE=%t4.o
-
-# NO-RELOCATED-SECTION: warning: '[[FILE]]': failed to get SHT_LLVM_BB_ADDR_MAP section(s): SHT_RELA section with index 1: failed to get a relocated section: invalid section index: 255
-
-## Check that if we have an ET_DYN file with a .rela.dyn section, we don't get
-## a warning about a missing relocation section and can get the baddrmap data.
-
---- !ELF
-FileHeader:
-  Class:           ELFCLASS64
-  Data:            ELFDATA2LSB
-  Type:            ET_DYN
-  Machine:         EM_X86_64
-Sections:
-  - Name:            .rela.dyn
-    Type:            SHT_RELA
-    Flags:           [ SHF_ALLOC ]
-  - Name:            .llvm_bb_addr_map
-    Type:            SHT_LLVM_BB_ADDR_MAP
-    Flags:           [ SHF_LINK_ORDER ]
-    Entries:
-      - Version:         2
-        Feature:         0x7
-        Address:         0xF
-        BBEntries:
-          - ID:              0
-            AddressOffset:   0x0
-            Size:            0xF
-            Metadata:        0x1
-    PGOAnalyses:
-      - FuncEntryCount: 100
-        PGOBBEntries:
-          - BBFreq:          100
-            Successors:      []
-
-# RUN: yaml2obj %s --docnum=4 -o %t5.o
-# RUN: llvm-readobj %t5.o --pgo-analysis-map | FileCheck %s --check-prefix=ET-DYN-NO-WARNING -DFILE=%t5.o
-
-# ET-DYN-NO-WARNING:      BBAddrMap [
-# ET-DYN-NO-WARNING-NEXT:   Function {
-# ET-DYN-NO-WARNING-NEXT:     At: 0xF
-# ET-DYN-NO-WARNING-NEXT:     Name: <?>
-# ET-DYN-NO-WARNING-NEXT:     EntryCount: 100
-# ET-DYN-NO-WARNING-NEXT:     BB entries [
-# ET-DYN-NO-WARNING-NEXT:       {
-# ET-DYN-NO-WARNING-NEXT:         ID: 0
-# ET-DYN-NO-WARNING-NEXT:         Offset: 0x0
-# ET-DYN-NO-WARNING-NEXT:         Size: 0xF
-# ET-DYN-NO-WARNING-NEXT:         HasReturn: Yes
-# ET-DYN-NO-WARNING-NEXT:         HasTailCall: No
-# ET-DYN-NO-WARNING-NEXT:         IsEHPad: No
-# ET-DYN-NO-WARNING-NEXT:         CanFallThrough: No
-# ET-DYN-NO-WARNING-NEXT:         HasIndirectBranch: No
-# ET-DYN-NO-WARNING-NEXT:         Frequency: 100
-# ET-DYN-NO-WARNING-NEXT:         Successors [
-# ET-DYN-NO-WARNING-NEXT:         ]
-# ET-DYN-NO-WARNING-NEXT:       }
-# ET-DYN-NO-WARNING-NEXT:     ]
-# ET-DYN-NO-WARNING-NEXT:   }
-# ET-DYN-NO-WARNING-NEXT: ]
diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp
index 3b32d9805277759..4bf4640f1a4ca39 100644
--- a/llvm/tools/llvm-readobj/ELFDumper.cpp
+++ b/llvm/tools/llvm-readobj/ELFDumper.cpp
@@ -593,7 +593,7 @@ template <typename ELFT> class GNUELFDumper : public ELFDumper<ELFT> {
   void printVersionDefinitionSection(const Elf_Shdr *Sec) override;
   void printVersionDependencySection(const Elf_Shdr *Sec) override;
   void printCGProfile() override;
-  void printBBAddrMaps(bool IncludePGOAnalysis = false) override;
+  void printBBAddrMaps() override;
   void printAddrsig() override;
   void printNotes() override;
   void printELFLinkerOptions() override;
@@ -704,7 +704,7 @@ template <typename ELFT> class LLVMELFDumper : public ELFDumper<ELFT> {
   void printVersionDefinitionSection(const Elf_Shdr *Sec) override;
   void printVersionDependencySection(const Elf_Shdr *Sec) override;
   void printCGProfile() override;
-  void printBBAddrMaps(bool IncludePGOAnalysis = false) override;
+  void printBBAddrMaps() override;
   void printAddrsig() override;
   void printNotes() override;
   void printELFLinkerOptions() override;
@@ -739,8 +739,6 @@ template <typename ELFT> class LLVMELFDumper : public ELFDumper<ELFT> {
   void printMipsABIFlags() override;
   virtual void printZeroSymbolOtherField(const Elf_Sym &Symbol) const;
 
-  template<typename AddrMap> void printAddrMaps();
-
 protected:
   virtual std::string getGroupSectionHeaderName() const;
   void printSymbolOtherField(const Elf_Sym &Symbol) const;
@@ -5072,8 +5070,7 @@ template <class ELFT> void GNUELFDumper<ELFT>::printCGProfile() {
   OS << "GNUStyle::printCGProfile not implemented\n";
 }
 
-template <class ELFT>
-void GNUELFDumper<ELFT>::printBBAddrMaps(bool IncludePGOAnalysis) {
+template <class ELFT> void GNUELFDumper<ELFT>::printBBAddrMaps() {
   OS << "GNUStyle::printBBAddrMaps not implemented\n";
 }
 
@@ -7544,8 +7541,7 @@ template <class ELFT> void LLVMELFDumper<ELFT>::printCGProfile() {
   }
 }
 
-template <class ELFT>
-void LLVMELFDumper<ELFT>::printBBAddrMaps(bool IncludePGOAnalysis) {
+template <class ELFT> void LLVMELFDumper<ELFT>::printBBAddrMaps() {
   bool IsRelocatable = this->Obj.getHeader().e_type == ELF::ET_REL;
   using Elf_Shdr = typename ELFT::Shdr;
   auto IsMatch = [](const Elf_Shdr &Sec) -> bool {
@@ -7571,16 +7567,15 @@ void LLVMELFDumper<ELFT>::printBBAddrMaps(bool IncludePGOAnalysis) {
                                 this->describe(*Sec));
       continue;
     }
-    std::vector<PGOAnalysisMap> PGOAnalysis;
-    Expected<std::vector<BBAddrMap>> BBAddrMapOrErr = this->Obj.decodeBBAddrMap(
-        *Sec, RelocSec, IncludePGOAnalysis ? &PGOAnalysis : nullptr);
+    std::vector<PGOAnalysisMap> PGOAnalyses;
+    Expected<std::vector<BBAddrMap>> BBAddrMapOrErr =
+        this->Obj.decodeBBAddrMap(*Sec, RelocSec, &PGOAnalyses);
     if (!BBAddrMapOrErr) {
       this->reportUniqueWarning("unable to dump " + this->describe(*Sec) +
                                 ": " + toString(BBAddrMapOrErr.takeError()));
       continue;
     }
-    for (const auto &[Idx, AM] : llvm::enumerate(*BBAddrMapOrErr)) {
-      const auto *PAM = IncludePGOAnalysis ? &PGOAnalysis[Idx] : nullptr;
+    for (const auto &[AM, PAM] : zip_equal(*BBAddrMapOrErr, PGOAnalyses)) {
       DictScope D(W, "Function");
       W.printHex("At", AM.Addr);
       SmallVector<uint32_t> FuncSymIndex =
@@ -7593,39 +7588,50 @@ void LLVMELFDumper<ELFT>::printBBAddrMaps(bool IncludePGOAnalysis) {
       else
         FuncName = this->getStaticSymbolName(FuncSymIndex.front());
       W.printString("Name", FuncName);
-      if (IncludePGOAnalysis && PAM->FeatEnable.FuncEntryCount)
-        W.printNumber("EntryCount", PAM->FuncEntryCount);
-
-      bool IncludePGOBBData =
-          IncludePGOAnalysis && PAM->BBEntries.size() == AM.BBEntries.size();
-      ListScope L(W, "BB entries");
-      for (const auto &[BIdx, BBE] : llvm::enumerate(AM.BBEntries)) {
-        const auto *PBBE = IncludePGOBBData ? &PAM->BBEntries[BIdx] : nullptr;
-        DictScope L(W);
-        W.printNumber("ID", BBE.ID);
-        W.printHex("Offset", BBE.Offset);
-        W.printHex("Size", BBE.Size);
-        W.printBoolean("HasReturn", BBE.hasReturn());
-        W.printBoolean("HasTailCall", BBE.hasTailCall());
-        W.printBoolean("IsEHPad", BBE.isEHPad());
-        W.printBoolean("CanFallThrough", BBE.canFallThrough());
-        W.printBoolean("HasIndirectBranch", BBE.hasIndirectBranch());
-
-        /// FIXME: currently we just emit the raw frequency, it may be better to
-        /// provide an option to scale it by the first entry frequence using
-        /// BlockFrequency::Scaled64 number
-        if (IncludePGOBBData && PAM->FeatEnable.BBFreq)
-          W.printNumber("Frequency", PBBE->BlockFreq.getFrequency());
-
-        if (IncludePGOBBData && PAM->FeatEnable.BrProb) {
-          ListScope L(W, "Successors");
-          for (const auto &Succ : PBBE->Successors) {
+
+      {
+        ListScope L(W, "BB entries");
+        for (const BBAddrMap::BBEntry &BBE : AM.BBEntries) {
+          DictScope L(W);
+          W.printNumber("ID", BBE.ID);
+          W.printHex("Offset", BBE.Offset);
+          W.printHex("Size", BBE.Size);
+          W.printBoolean("HasReturn", BBE.hasReturn());
+          W.printBoolean("HasTailCall", BBE.hasTailCall());
+          W.printBoolean("IsEHPad", BBE.isEHPad());
+          W.printBoolean("CanFallThrough", BBE.canFallThrough());
+          W.printBoolean("HasIndirectBranch", BBE.hasIndirectBranch());
+        }
+      }
+
+      if (PAM.FeatEnable.anyEnabled()) {
+        DictScope PD(W, "PGO analyses");
+
+        if (PAM.FeatEnable.FuncEntryCount)
+          W.printNumber("FuncEntryCount", PAM.FuncEntryCount);
+
+        if (PAM.FeatEnable.BBFreq || PAM.FeatEnable.BrProb) {
+          ListScope L(W, "PGO BB entries");
+          for (const PGOAnalysisMap::PGOBBEntry &PBBE : PAM.BBEntries) {
             DictScope L(W);
-            W.printNumber("ID", Succ.ID);
-            /// FIXME: currently we just emit the raw numerator of the probably,
-            /// it may be better to provide an option to emit it as a percentage
-            /// or other prettied representation
-            W.printHex("Probability", Succ.Prob.getNumerator());
+
+            /// FIXME: currently we just emit the raw frequency, it may be
+            /// better to provide an option to scale it by the first entry
+            /// frequence using BlockFrequency::Scaled64 number
+            if (PAM.FeatEnable.BBFreq)
+              W.printNumber("Frequency", PBBE.BlockFreq.getFrequency());
+
+            if (PAM.FeatEnable.BrProb) {
+              ListScope L(W, "Successors");
+              for (const auto &Succ : PBBE.Successors) {
+                DictScope L(W);
+                W.printNumber("ID", Succ.ID);
+                /// FIXME: currently we just emit the raw numerator of the
+                /// probably, it may be better to provide an option to emit it
+                /// as a percentage or other prettied representation
+                W.printHex("Probability", Succ.Prob.getNumerator());
+              }
+            }
           }
         }
       }
diff --git a/llvm/tools/llvm-readobj/ObjDumper.h b/llvm/tools/llvm-readobj/ObjDumper.h
index 082aba80841c6b6..1d679453581bc84 100644
--- a/llvm/tools/llvm-readobj/ObjDumper.h
+++ b/llvm/tools/llvm-readobj/ObjDumper.h
@@ -129,7 +129,7 @@ class ObjDumper {
   virtual void printGroupSections() {}
   virtual void printHashHistograms() {}
   virtual void printCGProfile() {}
-  virtual void printBBAddrMaps(bool IncludePGOAnalysis = false) {}
+  virtual void printBBAddrMaps() {}
   virtual void printAddrsig() {}
   virtual void printNotes() {}
   virtual void printELFLinkerOptions() {}
diff --git a/llvm/tools/llvm-readobj/Opts.td b/llvm/tools/llvm-readobj/Opts.td
index a981fac2f2f3650..e2d93c6ec229e9f 100644
--- a/llvm/tools/llvm-readobj/Opts.td
+++ b/llvm/tools/llvm-readobj/Opts.td
@@ -29,7 +29,6 @@ def extra_sym_info : FF<"extra-sym-info", "Display extra information when showin
 def file_header : FF<"file-header", "Display file header">;
 def headers : FF<"headers", "Equivalent to setting: --file-header, --program-headers, --section-headers">;
 defm hex_dump : Eq<"hex-dump", "Display the specified section(s) as hexadecimal bytes">, MetaVarName<"<name or index>">;
-def pgo_analysis_map : FF<"pgo-analysis-map", "Display the BB address map section with PGO data included">;
 def pretty_print : FF<"pretty-print", "Pretty print JSON output">;
 def relocs : FF<"relocs", "Display the relocation entries in the file">;
 def section_data : FF<"section-data", "Display section data for each section shown. This option has no effect for GNU style output">;
diff --git a/llvm/tools/llvm-readobj/llvm-readobj.cpp b/llvm/tools/llvm-readobj/llvm-readobj.cpp
index 4dcab4ce5c9f74d..f9d605d35244bf3 100644
--- a/llvm/tools/llvm-readobj/llvm-readobj.cpp
+++ b/llvm/tools/llvm-readobj/llvm-readobj.cpp
@@ -95,7 +95,6 @@ static bool Addrsig;
 static bool All;
 static bool ArchSpecificInfo;
 static bool BBAddrMap;
-static bool PGOAnalysisMap;
 bool ExpandRelocs;
 static bool CGProfile;
 bool Demangle;
@@ -212,7 +211,6 @@ static void parseOptions(const opt::InputArgList &Args) {
   opts::All = Args.hasArg(OPT_all);
   opts::ArchSpecificInfo = Args.hasArg(OPT_arch_specific);
   opts::BBAddrMap = Args.hasArg(OPT_bb_addr_map);
-  opts::PGOAnalysisMap = Args.hasArg(OPT_pgo_analysis_map);
   opts::CGProfile = Args.hasArg(OPT_cg_profile);
   opts::Demangle = Args.hasFlag(OPT_demangle, OPT_no_demangle, false);
   opts::DependentLibraries = Args.hasArg(OPT_dependent_libraries);
@@ -465,8 +463,8 @@ static void dumpObject(ObjectFile &Obj, ScopedPrinter &Writer,
       Dumper->printHashHistograms();
     if (opts::CGProfile)
       Dumper->printCGProfile();
-    if (opts::BBAddrMap || opts::PGOAnalysisMap)
-      Dumper->printBBAddrMaps(opts::PGOAnalysisMap);
+    if (opts::BBAddrMap)
+      Dumper->printBBAddrMaps();
     if (opts::Addrsig)
       Dumper->printAddrsig();
     if (opts::Notes)



More information about the llvm-commits mailing list