Skip to content

Commit

Permalink
[SHT_LLVM_BB_ADDR_MAP][llvm-readobj] Implements llvm-readobj handling…
Browse files Browse the repository at this point in the history
… for PGOAnalysisMap. (#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.
  • Loading branch information
red1bluelost authored Feb 1, 2024
1 parent 7a7d548 commit aaaff74
Show file tree
Hide file tree
Showing 2 changed files with 262 additions and 13 deletions.
214 changes: 214 additions & 0 deletions llvm/test/tools/llvm-readobj/ELF/bb-addr-map-pgo-analysis-map.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
## This test checks how llvm-readobj prints the PGO Analysis Map with the
## --bb-addr-map option.

## Check 64-bit:
# RUN: yaml2obj %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 32-bit:
# RUN: yaml2obj %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 %s -DBITS=32 -DSIZE=24 -o %t2.o
# RUN: llvm-readobj %t2.o --bb-addr-map 2>&1 | FileCheck %s -DOFFSET=0x00000018 -DFILE=%t2.o --check-prefix=TRUNCATED

## Check that missing features can be handled.
# RUN: yaml2obj %s -DBITS=32 -DFEATURE=0x2 -o %t3.o
# RUN: llvm-readobj %t3.o --bb-addr-map 2>&1 | FileCheck %s -DFILE=%t3.o --check-prefix=INVALIDFT

# 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: ]

# INVALIDFT: warning: '[[FILE]]': unable to dump SHT_LLVM_BB_ADDR_MAP section with index 5: unable to decode LEB128 at offset 0x00000010: malformed uleb128, extends past end

--- !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: 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: [[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

61 changes: 48 additions & 13 deletions llvm/tools/llvm-readobj/ELFDumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand All @@ -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());
}
}
}
}
}
}
}
Expand Down

0 comments on commit aaaff74

Please sign in to comment.