Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 3 commits into from
Feb 1, 2024

Conversation

red1bluelost
Copy link
Member

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.

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.
@llvmbot
Copy link
Collaborator

llvmbot commented Jan 25, 2024

@llvm/pr-subscribers-llvm-binary-utilities

Author: Micah Weston (red1bluelost)

Changes

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.


Full diff: https://github.com/llvm/llvm-project/pull/79520.diff

2 Files Affected:

  • (added) llvm/test/tools/llvm-readobj/ELF/bb-addr-map-pgo-analysis-map.test (+221)
  • (modified) llvm/tools/llvm-readobj/ELFDumper.cpp (+48-13)
diff --git a/llvm/test/tools/llvm-readobj/ELF/bb-addr-map-pgo-analysis-map.test b/llvm/test/tools/llvm-readobj/ELF/bb-addr-map-pgo-analysis-map.test
new file mode 100644
index 000000000000000..fad2cca1990a49b
--- /dev/null
+++ b/llvm/test/tools/llvm-readobj/ELF/bb-addr-map-pgo-analysis-map.test
@@ -0,0 +1,221 @@
+## 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 --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 --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 --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 --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 --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:     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:       }
+# 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:       }
+# 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:     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:       }
+# 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: ]
+
+# 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:     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:     PGO analyses {
+# TRUNCATED-NEXT:       FuncEntryCount: 89
+# 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..4bf4640f1a4ca39 100644
--- a/llvm/tools/llvm-readobj/ELFDumper.cpp
+++ b/llvm/tools/llvm-readobj/ELFDumper.cpp
@@ -7567,14 +7567,15 @@ template <class ELFT> void LLVMELFDumper<ELFT>::printBBAddrMaps() {
                                 this->describe(*Sec));
       continue;
     }
+    std::vector<PGOAnalysisMap> PGOAnalyses;
     Expected<std::vector<BBAddrMap>> BBAddrMapOrErr =
-        this->Obj.decodeBBAddrMap(*Sec, RelocSec);
+        this->Obj.decodeBBAddrMap(*Sec, RelocSec, &PGOAnalyses);
     if (!BBAddrMapOrErr) {
       this->reportUniqueWarning("unable to dump " + this->describe(*Sec) +
                                 ": " + toString(BBAddrMapOrErr.takeError()));
       continue;
     }
-    for (const BBAddrMap &AM : *BBAddrMapOrErr) {
+    for (const auto &[AM, PAM] : zip_equal(*BBAddrMapOrErr, PGOAnalyses)) {
       DictScope D(W, "Function");
       W.printHex("At", AM.Addr);
       SmallVector<uint32_t> FuncSymIndex =
@@ -7588,17 +7589,51 @@ template <class ELFT> void LLVMELFDumper<ELFT>::printBBAddrMaps() {
         FuncName = this->getStaticSymbolName(FuncSymIndex.front());
       W.printString("Name", FuncName);
 
-      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());
+      {
+        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);
+
+            /// 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());
+              }
+            }
+          }
+        }
       }
     }
   }

@red1bluelost
Copy link
Member Author

I updated the metadata test to instead provide the wrong feature bit.

@red1bluelost red1bluelost merged commit aaaff74 into llvm:main Feb 1, 2024
3 of 4 checks passed
ichaer added a commit to ichaer/llvm-project-onesided_lower_bound that referenced this pull request Feb 2, 2024
* llvm/main: (500 commits)
  [docs] Add beginner-focused office hours (llvm#80308)
  [mlir][sparse] external entry method wrapper for sparse tensors (llvm#80326)
  [StackSlotColoring] Ignore non-spill objects in RemoveDeadStores. (llvm#80242)
  [libc][stdbit] fix return types (llvm#80337)
  Revert "[RISCV] Refine cost on Min/Max reduction" (llvm#80340)
  [TTI]Add support for strided loads/stores.
  [analyzer][HTMLRewriter] Cache partial rewrite results. (llvm#80220)
  [flang][openacc][openmp] Use #0 from hlfir.declare value when generating bound ops (llvm#80317)
  [AArch64][PAC] Expand blend(reg, imm) operation in aarch64-pauth pass (llvm#74729)
  [SHT_LLVM_BB_ADDR_MAP][llvm-readobj] Implements llvm-readobj handling for PGOAnalysisMap. (llvm#79520)
  [libc] add bazel support for most of unistd (llvm#80078)
  [clang-tidy] Remove enforcement of rule C.48 from cppcoreguidelines-prefer-member-init (llvm#80330)
  [OpenMP] Fix typo (NFC) (llvm#80332)
  [BOLT] Enable re-writing of Linux kernel binary (llvm#80228)
  [BOLT] Adjust section sizes based on file offsets (llvm#80226)
  [libc] fix stdbit include test when not all entrypoints are available (llvm#80323)
  [RISCV][GISel] RegBank select and instruction select for vector G_ADD, G_SUB (llvm#74114)
  [RISCV] Add srmcfg CSR from Ssqosid extension. (llvm#79914)
  [mlir][sparse] add sparsification options to pretty print and debug s… (llvm#80205)
  [RISCV][MC] MC layer support for the experimental zalasr extension (llvm#79911)
  ...
agozillon pushed a commit to agozillon/llvm-project that referenced this pull request Feb 5, 2024
… for PGOAnalysisMap. (llvm#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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants