Skip to content

Commit

Permalink
[SHT_LLVM_BB_ADDR_MAP][obj2yaml] Implements PGOAnalysisMap for elf2ya…
Browse files Browse the repository at this point in the history
…ml and tests. (llvm#80924)

Adds support to obj2yaml for PGO Analysis Map. Adds a test to both
obj2yaml and yaml2obj.
  • Loading branch information
red1bluelost authored Feb 14, 2024
1 parent 09e9895 commit a3f61c8
Show file tree
Hide file tree
Showing 3 changed files with 352 additions and 0 deletions.
232 changes: 232 additions & 0 deletions llvm/test/tools/obj2yaml/ELF/bb-addr-map-pgo-analysis-map.yaml
Original file line number Diff line number Diff line change
@@ -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 uses the "Content" tag 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:]]+)}}'{{$}}

83 changes: 83 additions & 0 deletions llvm/test/tools/yaml2obj/ELF/bb-addr-map-pgo-analysis-map.yaml
Original file line number Diff line number Diff line change
@@ -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

37 changes: 37 additions & 0 deletions llvm/tools/obj2yaml/elf2yaml.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 HasAnyPGOAnalysisMapEntry = false;
std::vector<ELFYAML::PGOAnalysisMapEntry> PGOAnalyses;
DataExtractor::Cursor Cur(0);
uint8_t Version = 0;
uint8_t Feature = 0;
Expand All @@ -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();
Expand Down Expand Up @@ -934,10 +937,42 @@ 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()) {
HasAnyPGOAnalysisMapEntry = 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 (!Cur)
break;
}

if (FeatureOrErr->BrProb) {
auto &SuccEntries = PGOBBEntry.Successors.emplace();
uint64_t SuccCount = Data.getULEB128(Cur);
for (uint64_t SuccIdx = 0; Cur && SuccIdx < SuccCount; ++SuccIdx) {
uint32_t ID = Data.getULEB128(Cur);
uint32_t BrProb = Data.getULEB128(Cur);
SuccEntries.push_back({ID, BrProb});
}
}
}
}
}
}

if (!Cur) {
Expand All @@ -946,6 +981,8 @@ ELFDumper<ELFT>::dumpBBAddrMapSection(const Elf_Shdr *Shdr) {
S->Content = yaml::BinaryRef(Content);
} else {
S->Entries = std::move(Entries);
if (HasAnyPGOAnalysisMapEntry)
S->PGOAnalyses = std::move(PGOAnalyses);
}

return S.release();
Expand Down

0 comments on commit a3f61c8

Please sign in to comment.