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
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
221 changes: 221 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,221 @@
## This test checks how we handle PGO Analysis Map in --bb-addr-map.
red1bluelost marked this conversation as resolved.
Show resolved Hide resolved

## Fails on windows (https://github.com/llvm/llvm-project/issues/60013).
# UNSUPPORTED: system-windows
red1bluelost marked this conversation as resolved.
Show resolved Hide resolved

## 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
red1bluelost marked this conversation as resolved.
Show resolved Hide resolved
# 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
red1bluelost marked this conversation as resolved.
Show resolved Hide resolved
# 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
red1bluelost marked this conversation as resolved.
Show resolved Hide resolved
# 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

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
Loading