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][obj2yaml] Implements PGOAnalysisMap for elf2yaml and tests. #80924

Merged
merged 2 commits into from
Feb 14, 2024

Conversation

red1bluelost
Copy link
Member

Adds support to obj2yaml for PGO Analysis Map. Adds a test to both obj2yaml and yaml2obj.

@red1bluelost red1bluelost self-assigned this Feb 7, 2024
@llvmbot
Copy link
Member

llvmbot commented Feb 7, 2024

@llvm/pr-subscribers-objectyaml

Author: Micah Weston (red1bluelost)

Changes

Adds support to obj2yaml for PGO Analysis Map. Adds a test to both obj2yaml and yaml2obj.


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

3 Files Affected:

  • (added) llvm/test/tools/obj2yaml/ELF/bb-addr-map-pgo-analysis-map.yaml (+232)
  • (added) llvm/test/tools/yaml2obj/ELF/bb-addr-map-pgo-analysis-map.yaml (+83)
  • (modified) llvm/tools/obj2yaml/elf2yaml.cpp (+34)
diff --git a/llvm/test/tools/obj2yaml/ELF/bb-addr-map-pgo-analysis-map.yaml b/llvm/test/tools/obj2yaml/ELF/bb-addr-map-pgo-analysis-map.yaml
new file mode 100644
index 00000000000000..3bb03e6efb8ec1
--- /dev/null
+++ b/llvm/test/tools/obj2yaml/ELF/bb-addr-map-pgo-analysis-map.yaml
@@ -0,0 +1,232 @@
+## Check how obj2yaml produces YAML PGO Analysis Map in .llvm_bb_addr_map.
+
+## Check that obj2yaml uses the "Entries" tag to describe an .llvm_bb_addr_map section.
+
+# RUN: yaml2obj --docnum=1 %s -o %t1
+# RUN: obj2yaml %t1 | FileCheck %s --check-prefix=VALID
+
+# VALID:      --- !ELF
+# VALID-NEXT: FileHeader:
+# VALID-NEXT:   Class: ELFCLASS64
+# VALID-NEXT:   Data:  ELFDATA2LSB
+# VALID-NEXT:   Type:  ET_EXEC
+# VALID-NEXT: Sections:
+# VALID-NEXT:   - Name: .llvm_bb_addr_map
+# VALID-NEXT:     Type: SHT_LLVM_BB_ADDR_MAP
+# VALID-NEXT:     Entries:
+# VALID-NEXT:       - Version: 2
+# VALID-NEXT:         Feature: 0x7
+## The 'BaseAddress' field is omitted when it's zero.
+# VALID-NEXT:         BBRanges:
+# VALID-NEXT:           - BBEntries:
+# VALID-NEXT:             - ID:            0
+# VALID-NEXT:               AddressOffset: 0x1
+# VALID-NEXT:               Size:          0x2
+# VALID-NEXT:               Metadata:      0x3
+# VALID-NEXT:             - ID:            2
+# VALID-NEXT:               AddressOffset: 0x4
+# VALID-NEXT:               Size:          0x5
+# VALID-NEXT:               Metadata:      0x6
+# VALID-NEXT:             - ID:            4
+# VALID-NEXT:               AddressOffset: 0xFFFFFFFFFFFFFFF7
+# VALID-NEXT:               Size:          0xFFFFFFFFFFFFFFF8
+# VALID-NEXT:               Metadata:      0xFFFFFFFFFFFFFFF9
+# VALID-NEXT:       - Version: 2
+# VALID-NEXT:         Feature: 0xA
+# VALID-NEXT:         BBRanges:
+# VALID-NEXT:           - BaseAddress: 0xFFFFFFFFFFFFFF20
+# VALID-NEXT:             BBEntries:
+# VALID-NEXT:               - ID:            6
+# VALID-NEXT:                 AddressOffset: 0xA
+# VALID-NEXT:                 Size:          0xB
+# VALID-NEXT:                 Metadata:      0xC
+# VALID-NEXT:     PGOAnalyses:
+# VALID-NEXT:       - FuncEntryCount: 100
+# VALID-NEXT:         PGOBBEntries:
+# VALID-NEXT:           - BBFreq:        100
+# VALID-NEXT:             Successors:
+# VALID-NEXT:               - ID:        2
+# VALID-NEXT:                 BrProb:    0x80000000
+# VALID-NEXT:               - ID:        4
+# VALID-NEXT:                 BrProb:    0x80000000
+# VALID-NEXT:           - BBFreq:        50
+# VALID-NEXT:             Successors:
+# VALID-NEXT:               - ID:        4
+# VALID-NEXT:                 BrProb:    0xFFFFFFFF
+# VALID-NEXT:           - BBFreq:        100
+# VALID-NEXT:             Successors:    []
+# VALID-NEXT:         PGOBBEntries:
+# VALID-NEXT:           - BBFreq:        20
+
+--- !ELF
+FileHeader:
+  Class: ELFCLASS64
+  Data:  ELFDATA2LSB
+  Type:  ET_EXEC
+Sections:
+  - Name:   .llvm_bb_addr_map
+    Type:   SHT_LLVM_BB_ADDR_MAP
+    ShSize: [[SIZE=<none>]]
+    Entries:
+      - Version: 2
+        Feature: 0x7
+        BBRanges:
+          - BaseAddress: 0x0
+            BBEntries:
+              - ID:            0
+                AddressOffset: 0x1
+                Size:          0x2
+                Metadata:      0x3
+              - ID:            2
+                AddressOffset: 0x4
+                Size:          0x5
+                Metadata:      0x6
+              - ID:            4
+                AddressOffset: 0xFFFFFFFFFFFFFFF7
+                Size:          0xFFFFFFFFFFFFFFF8
+                Metadata:      0xFFFFFFFFFFFFFFF9
+      - Version:   2
+        Feature:   0xA
+        BBRanges:
+          - BaseAddress:   0xFFFFFFFFFFFFFF20
+            BBEntries:
+             - ID:            6
+               AddressOffset: 0xA
+               Size:          0xB
+               Metadata:      0xC
+    PGOAnalyses:
+      - FuncEntryCount: 100
+        PGOBBEntries:
+          - BBFreq:        100
+            Successors:
+              - ID:        2
+                BrProb:    0x80000000
+              - ID:        4
+                BrProb:    0x80000000
+          - BBFreq:        50
+            Successors:
+              - ID:        4
+                BrProb:    0xFFFFFFFF
+          - BBFreq:        100
+            Successors: []
+      - PGOBBEntries:
+          - BBFreq:        20
+
+## Check obj2yaml can dump multiple .llvm_bb_addr_map sections.
+
+# RUN: yaml2obj --docnum=2 %s -o %t2
+# RUN: obj2yaml %t2 | FileCheck %s --check-prefix=MULTI
+
+# MULTI:      --- !ELF
+# MULTI-NEXT: FileHeader:
+# MULTI-NEXT:   Class: ELFCLASS64
+# MULTI-NEXT:   Data:  ELFDATA2LSB
+# MULTI-NEXT:   Type:  ET_EXEC
+# MULTI-NEXT: Sections:
+# MULTI-NEXT:   - Name: .llvm_bb_addr_map
+# MULTI-NEXT:     Type: SHT_LLVM_BB_ADDR_MAP
+# MULTI-NEXT:     Entries:
+## Fieldx 'BaseAddress' is omitted when it is zero.
+# MULTI-NEXT:       - Version: 0
+# MULTI-NEXT:         Feature: 0x3
+# MULTI-NEXT:         BBRanges:
+# MULTI-NEXT:           - BBEntries:
+# MULTI-NEXT:              - ID:            0
+# MULTI-NEXT:                AddressOffset: 0x1
+# MULTI-NEXT:                Size:          0x2
+# MULTI-NEXT:                Metadata:      0x3
+# MULTI-NEXT:     PGOAnalyses:
+# MULTI-NEXT:       - FuncEntryCount: 0
+# MULTI-NEXT:         PGOBBEntries:
+# MULTI-NEXT:           - BBFreq: 0
+# MULTI-NEXT:   - Name: '.llvm_bb_addr_map (1)'
+# MULTI-NEXT:     Type: SHT_LLVM_BB_ADDR_MAP
+# MULTI-NEXT:     Entries:
+# MULTI-NEXT:       - Version:   0
+# MULTI-NEXT:         Feature:   0x1
+# MULTI-NEXT:         BBRanges:
+# MULTI-NEXT:           - BaseAddress:   0x20
+# MULTI-NEXT:             BBEntries: []
+# MULTI-NEXT:     PGOAnalyses:
+# MULTI-NEXT:       - FuncEntryCount: 0
+
+--- !ELF
+FileHeader:
+  Class: ELFCLASS64
+  Data:  ELFDATA2LSB
+  Type:  ET_EXEC
+Sections:
+  - Name: .llvm_bb_addr_map
+    Type: SHT_LLVM_BB_ADDR_MAP
+    Entries:
+## Check that obj2yaml does not emit the 'BaseAddress' and 'Feature' fields when
+## they are zero.
+      - Version: 0
+        Feature: 0x3
+        BBRanges:
+          - BaseAddress: 0x0
+            BBEntries:
+              - AddressOffset: 0x1
+                Size:          0x2
+                Metadata:      0x3
+    PGOAnalyses:
+      - FuncEntryCount: 0
+        PGOBBEntries:
+          - BBFreq:        0
+  - Name: '.llvm_bb_addr_map (1)'
+    Type:  SHT_LLVM_BB_ADDR_MAP
+    Entries:
+      - Version: 0
+        Feature: 0x1
+        BBRanges:
+          - BaseAddress: 0x20
+    PGOAnalyses:
+      - FuncEntryCount: 0
+
+## Check that obj2yaml uses the "Content" tag to describe an .llvm_bb_addr_map section
+## when it can't extract the entries, for example, when the section is truncated.
+
+# RUN: yaml2obj --docnum=1 -DSIZE=0x1D %s -o %t3
+# RUN: obj2yaml %t3 | FileCheck %s --check-prefixes=TRUNCATED,INVALID
+
+# INVALID:           --- !ELF
+# INVALID-NEXT:      FileHeader:
+# INVALID-NEXT:        Class: ELFCLASS64
+# INVALID-NEXT:        Data:  ELFDATA2LSB
+# INVALID-NEXT:        Type:  ET_EXEC
+# INVALID-NEXT:      Sections:
+# INVALID-NEXT:        - Name:    .llvm_bb_addr_map
+# INVALID-NEXT:          Type:    SHT_LLVM_BB_ADDR_MAP
+# TRUNCATED-NEXT:        Content: {{([[:xdigit:]]{58})}}{{$}}
+# TRUNCATED-NEXT:        Content: {{([[:xdigit:]]{58})}}{{$}}
+
+## Check that obj2yaml will fail when original YAML does not provide a PGO
+## field that was enabled in the feature byte
+
+# RUN: yaml2obj --docnum=3 %s -o %t4
+# RUN: obj2yaml %t4 | FileCheck %s --check-prefix=MISSING-FEC
+
+--- !ELF
+FileHeader:
+  Class: ELFCLASS64
+  Data:  ELFDATA2LSB
+  Type:  ET_EXEC
+Sections:
+  - Name: '.llvm_bb_addr_map'
+    Type:  SHT_LLVM_BB_ADDR_MAP
+    Entries:
+      - Version: 0
+        Feature: 0x1
+        BBRanges:
+          - BaseAddress: 0x20
+
+# MISSING-FEC:           --- !ELF
+# MISSING-FEC-NEXT:      FileHeader:
+# MISSING-FEC-NEXT:        Class: ELFCLASS64
+# MISSING-FEC-NEXT:        Data:  ELFDATA2LSB
+# MISSING-FEC-NEXT:        Type:  ET_EXEC
+# MISSING-FEC-NEXT:      Sections:
+# MISSING-FEC-NEXT:        - Name:    .llvm_bb_addr_map
+# MISSING-FEC-NEXT:          Type:    SHT_LLVM_BB_ADDR_MAP
+# MISSING-FEC-NEXT:          Content: '{{([[:xdigit:]]+)}}'{{$}}
+
diff --git a/llvm/test/tools/yaml2obj/ELF/bb-addr-map-pgo-analysis-map.yaml b/llvm/test/tools/yaml2obj/ELF/bb-addr-map-pgo-analysis-map.yaml
new file mode 100644
index 00000000000000..4dfaf60be3c0ed
--- /dev/null
+++ b/llvm/test/tools/yaml2obj/ELF/bb-addr-map-pgo-analysis-map.yaml
@@ -0,0 +1,83 @@
+## Check how yaml2obj produces PGO Analysis Map in .llvm_bb_addr_map section.
+
+# RUN: yaml2obj --docnum=1 %s -o %t1
+# RUN: llvm-readobj --sections --section-data %t1 | FileCheck %s
+
+# Case 4: Specify Entries.
+# CHECK:        Name: .llvm_bb_addr_map (1)
+# CHECK:        SectionData (
+# CHECK-NEXT:     0000: 02072000 00000000 0000010B 010203E8
+# CHECK-NEXT:     0010: 07E80702 0CEEDDBB F70E0D91 A2C48801
+# CHECK-NEXT:   )
+
+# Case 7: Not including a field which is enabled in feature doesn't emit value
+# CHECK:        Name: .llvm_bb_addr_map (1)
+# CHECK:        SectionData (
+# CHECK-NEXT:     0000: 02012000 00000000 0000020D 010203 |
+# CHECK-NEXT:   )
+
+--- !ELF
+FileHeader:
+  Class: ELFCLASS64
+  Data:  ELFDATA2LSB
+  Type:  ET_EXEC
+Sections:
+
+## Test the following cases:
+
+## 1) We can produce an .llvm_bb_addr_map section from a description with
+##    Entries and PGO Analysis data.
+  - Name: '.llvm_bb_addr_map (1)'
+    Type: SHT_LLVM_BB_ADDR_MAP
+    Entries:
+      - Version: 2
+        Feature: 0x7
+        BBRanges:
+          - BaseAddress: 0x0000000000000020
+            BBEntries:
+              - ID:            11
+                AddressOffset: 0x00000001
+                Size:          0x00000002
+                Metadata:      0x00000003
+    PGOAnalyses:
+      - FuncEntryCount: 1000
+        PGOBBEntries:
+          - BBFreq:        1000
+            Successors:
+              - ID:        12
+                BrProb:    0xeeeeeeee
+              - ID:        13
+                BrProb:    0x11111111
+
+## 2) According to feature we have FuncEntryCount but none is provided in yaml
+  - Name: '.llvm_bb_addr_map (2)'
+    Type: SHT_LLVM_BB_ADDR_MAP
+    Entries:
+      - Version: 2
+        Feature: 0x1
+        BBRanges:
+          - BaseAddress:   0x0000000000000020
+            NumBlocks: 2
+            BBEntries:
+             - ID:            13
+               AddressOffset: 0x00000001
+               Size:          0x00000002
+               Metadata:      0x00000003
+
+## Check that yaml2obj generates a warning when we use unsupported feature.
+# RUN: yaml2obj --docnum=2  %s 2>&1 | FileCheck %s --check-prefix=INVALID-FEATURE
+# INVALID-FEATURE: warning: invalid encoding for BBAddrMap::Features: 0xff
+
+--- !ELF
+FileHeader:
+  Class: ELFCLASS64
+  Data:  ELFDATA2LSB
+  Type:  ET_EXEC
+Sections:
+  - Name: '.llvm_bb_addr_map'
+    Type: SHT_LLVM_BB_ADDR_MAP
+    Entries:
+      - Version: 2
+##  Specify unsupported feature
+        Feature: 0xFF
+
diff --git a/llvm/tools/obj2yaml/elf2yaml.cpp b/llvm/tools/obj2yaml/elf2yaml.cpp
index 38a69f77ff8362..e1fe004abecf51 100644
--- a/llvm/tools/obj2yaml/elf2yaml.cpp
+++ b/llvm/tools/obj2yaml/elf2yaml.cpp
@@ -889,6 +889,8 @@ ELFDumper<ELFT>::dumpBBAddrMapSection(const Elf_Shdr *Shdr) {
   DataExtractor Data(Content, Obj.isLE(), ELFT::Is64Bits ? 8 : 4);
 
   std::vector<ELFYAML::BBAddrMapEntry> Entries;
+  bool FoundPGOAnalysis = false;
+  std::vector<ELFYAML::PGOAnalysisMapEntry> PGOAnalyses;
   DataExtractor::Cursor Cur(0);
   uint8_t Version = 0;
   uint8_t Feature = 0;
@@ -905,6 +907,7 @@ ELFDumper<ELFT>::dumpBBAddrMapSection(const Elf_Shdr *Shdr) {
     }
     uint64_t NumBBRanges = 1;
     uint64_t NumBlocks = 0;
+    uint32_t TotalNumBlocks = 0;
     auto FeatureOrErr = llvm::object::BBAddrMap::Features::decode(Feature);
     if (!FeatureOrErr)
       return FeatureOrErr.takeError();
@@ -934,10 +937,39 @@ ELFDumper<ELFT>::dumpBBAddrMapSection(const Elf_Shdr *Shdr) {
         uint64_t Metadata = Data.getULEB128(Cur);
         BBEntries.push_back({ID, Offset, Size, Metadata});
       }
+      TotalNumBlocks += BBEntries.size();
       BBRanges.push_back({BaseAddress, /*NumBlocks=*/{}, BBEntries});
     }
     Entries.push_back(
         {Version, Feature, /*NumBBRanges=*/{}, std::move(BBRanges)});
+
+    ELFYAML::PGOAnalysisMapEntry &PGOAnalysis = PGOAnalyses.emplace_back();
+    if (FeatureOrErr->hasPGOAnalysis()) {
+      FoundPGOAnalysis = true;
+
+      if (FeatureOrErr->FuncEntryCount)
+        PGOAnalysis.FuncEntryCount = Data.getULEB128(Cur);
+
+      if (FeatureOrErr->hasPGOAnalysisBBData()) {
+        auto &PGOBBEntries = PGOAnalysis.PGOBBEntries.emplace();
+        for (uint64_t BlockIndex = 0; Cur && BlockIndex < TotalNumBlocks;
+             ++BlockIndex) {
+          auto &PGOBBEntry = PGOBBEntries.emplace_back();
+          if (FeatureOrErr->BBFreq)
+            PGOBBEntry.BBFreq = Data.getULEB128(Cur);
+
+          if (FeatureOrErr->BrProb) {
+            auto &SuccEntries = PGOBBEntry.Successors.emplace();
+            uint64_t SuccCount = Data.getULEB128(Cur);
+            for (uint64_t SuccIdx = 0; SuccIdx < SuccCount; ++SuccIdx) {
+              uint32_t ID = Data.getULEB128(Cur);
+              uint32_t BrProb = Data.getULEB128(Cur);
+              SuccEntries.push_back({ID, BrProb});
+            }
+          }
+        }
+      }
+    }
   }
 
   if (!Cur) {
@@ -946,6 +978,8 @@ ELFDumper<ELFT>::dumpBBAddrMapSection(const Elf_Shdr *Shdr) {
     S->Content = yaml::BinaryRef(Content);
   } else {
     S->Entries = std::move(Entries);
+    if (FoundPGOAnalysis)
+      S->PGOAnalyses = std::move(PGOAnalyses);
   }
 
   return S.release();

@red1bluelost red1bluelost requested a review from rlavaee February 7, 2024 18:33
… elf2yaml and tests.

Addresses reviewer feedback.
@red1bluelost red1bluelost requested a review from rlavaee February 12, 2024 20:21
@red1bluelost red1bluelost merged commit a3f61c8 into llvm:main Feb 14, 2024
4 of 5 checks passed
@red1bluelost red1bluelost deleted the pgo-bb-addr-map--llvm-obj2yaml branch February 14, 2024 02:53
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.

3 participants