Skip to content

Commit aaaff74

Browse files
authored
[SHT_LLVM_BB_ADDR_MAP][llvm-readobj] Implements llvm-readobj handling 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.
1 parent 7a7d548 commit aaaff74

File tree

2 files changed

+262
-13
lines changed

2 files changed

+262
-13
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
## This test checks how llvm-readobj prints the PGO Analysis Map with the
2+
## --bb-addr-map option.
3+
4+
## Check 64-bit:
5+
# RUN: yaml2obj %s -DBITS=64 -DADDR=0x999999999 -o %t1.x64.o
6+
# RUN: llvm-readobj %t1.x64.o --bb-addr-map 2>&1 | FileCheck %s -DADDR=0x999999999 -DFILE=%t1.x64.o --check-prefix=CHECK
7+
# RUN: llvm-readelf %t1.x64.o --bb-addr-map | FileCheck %s --check-prefix=GNU
8+
9+
## Check 32-bit:
10+
# RUN: yaml2obj %s -DBITS=32 -o %t1.x32.o
11+
# RUN: llvm-readobj %t1.x32.o --bb-addr-map 2>&1 | FileCheck -DADDR=0x11111 %s -DFILE=%t1.x32.o --check-prefix=CHECK
12+
# RUN: llvm-readelf %t1.x32.o --bb-addr-map | FileCheck %s --check-prefix=GNU
13+
14+
## Check that a malformed section can be handled.
15+
# RUN: yaml2obj %s -DBITS=32 -DSIZE=24 -o %t2.o
16+
# RUN: llvm-readobj %t2.o --bb-addr-map 2>&1 | FileCheck %s -DOFFSET=0x00000018 -DFILE=%t2.o --check-prefix=TRUNCATED
17+
18+
## Check that missing features can be handled.
19+
# RUN: yaml2obj %s -DBITS=32 -DFEATURE=0x2 -o %t3.o
20+
# RUN: llvm-readobj %t3.o --bb-addr-map 2>&1 | FileCheck %s -DFILE=%t3.o --check-prefix=INVALIDFT
21+
22+
# CHECK: BBAddrMap [
23+
# CHECK-NEXT: Function {
24+
# CHECK-NEXT: At: [[ADDR]]
25+
# CHECK-NEXT: warning: '[[FILE]]': could not identify function symbol for address ([[ADDR]]) in SHT_LLVM_BB_ADDR_MAP section with index 3
26+
# CHECK-NEXT: Name: <?>
27+
# CHECK-NEXT: BB entries [
28+
# CHECK-NEXT: {
29+
# CHECK-NEXT: ID: 0
30+
# CHECK-NEXT: Offset: 0x0
31+
# CHECK-NEXT: Size: 0x1
32+
# CHECK-NEXT: HasReturn: No
33+
# CHECK-NEXT: HasTailCall: Yes
34+
# CHECK-NEXT: IsEHPad: No
35+
# CHECK-NEXT: CanFallThrough: No
36+
# CHECK-NEXT: HasIndirectBranch: No
37+
# CHECK-NEXT: }
38+
# CHECK-NEXT: {
39+
# CHECK-NEXT: ID: 2
40+
# CHECK-NEXT: Offset: 0x4
41+
# CHECK-NEXT: Size: 0x4
42+
# CHECK-NEXT: HasReturn: Yes
43+
# CHECK-NEXT: HasTailCall: No
44+
# CHECK-NEXT: IsEHPad: Yes
45+
# CHECK-NEXT: CanFallThrough: No
46+
# CHECK-NEXT: HasIndirectBranch: Yes
47+
# CHECK-NEXT: }
48+
# CHECK-NEXT: ]
49+
# CHECK-NEXT: PGO analyses {
50+
# CHECK-NEXT: FuncEntryCount: 100
51+
# CHECK-NEXT: PGO BB entries [
52+
# CHECK-NEXT: {
53+
# CHECK-NEXT: Frequency: 100
54+
# CHECK-NEXT: Successors [
55+
# CHECK-NEXT: {
56+
# CHECK-NEXT: ID: 2
57+
# CHECK-NEXT: Probability: 0xFFFFFFFF
58+
# CHECK-NEXT: }
59+
# CHECK-NEXT: ]
60+
# CHECK-NEXT: }
61+
# CHECK-NEXT: {
62+
# CHECK-NEXT: Frequency: 100
63+
# CHECK-NEXT: Successors [
64+
# CHECK-NEXT: ]
65+
# CHECK-NEXT: }
66+
# CHECK-NEXT: ]
67+
# CHECK-NEXT: }
68+
# CHECK-NEXT: }
69+
# CHECK-NEXT: Function {
70+
# CHECK-NEXT: At: 0x22222
71+
# CHECK-NEXT: Name: foo
72+
# CHECK-NEXT: BB entries [
73+
# CHECK-NEXT: {
74+
# CHECK-NEXT: ID: 4
75+
# CHECK-NEXT: Offset: 0x6
76+
# CHECK-NEXT: Size: 0x7
77+
# CHECK-NEXT: HasReturn: No
78+
# CHECK-NEXT: HasTailCall: No
79+
# CHECK-NEXT: IsEHPad: No
80+
# CHECK-NEXT: CanFallThrough: Yes
81+
# CHECK-NEXT: HasIndirectBranch: No
82+
# CHECK-NEXT: }
83+
# CHECK-NEXT: ]
84+
# CHECK-NEXT: PGO analyses {
85+
# CHECK-NEXT: FuncEntryCount: 8888
86+
# CHECK-NEXT: PGO BB entries [
87+
# CHECK-NEXT: {
88+
# CHECK-NEXT: Frequency: 9000
89+
# CHECK-NEXT: }
90+
# CHECK-NEXT: ]
91+
# CHECK-NEXT: }
92+
# CHECK-NEXT: }
93+
# CHECK-NEXT: ]
94+
95+
# GNU: GNUStyle::printBBAddrMaps not implemented
96+
97+
# TRUNCATED: BBAddrMap [
98+
# 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
99+
# TRUNCATED-NEXT: ]
100+
## Check that the other valid section is properly dumped.
101+
# TRUNCATED-NEXT: BBAddrMap [
102+
# TRUNCATED-NEXT: Function {
103+
# TRUNCATED-NEXT: At: 0x33333
104+
# TRUNCATED-NEXT: Name: bar
105+
# TRUNCATED-NEXT: BB entries [
106+
# TRUNCATED-NEXT: {
107+
# TRUNCATED-NEXT: ID: 6
108+
# TRUNCATED-NEXT: Offset: 0x9
109+
# TRUNCATED-NEXT: Size: 0xA
110+
# TRUNCATED-NEXT: HasReturn: Yes
111+
# TRUNCATED-NEXT: HasTailCall: Yes
112+
# TRUNCATED-NEXT: IsEHPad: No
113+
# TRUNCATED-NEXT: CanFallThrough: Yes
114+
# TRUNCATED-NEXT: HasIndirectBranch: Yes
115+
# TRUNCATED-NEXT: }
116+
# TRUNCATED-NEXT: {
117+
# TRUNCATED-NEXT: ID: 7
118+
# TRUNCATED-NEXT: Offset: 0x1F
119+
# TRUNCATED-NEXT: Size: 0xD
120+
# TRUNCATED-NEXT: HasReturn: No
121+
# TRUNCATED-NEXT: HasTailCall: Yes
122+
# TRUNCATED-NEXT: IsEHPad: Yes
123+
# TRUNCATED-NEXT: CanFallThrough: Yes
124+
# TRUNCATED-NEXT: HasIndirectBranch: No
125+
# TRUNCATED-NEXT: }
126+
# TRUNCATED-NEXT: ]
127+
# TRUNCATED-NEXT: PGO analyses {
128+
# TRUNCATED-NEXT: FuncEntryCount: 89
129+
# TRUNCATED-NEXT: }
130+
# TRUNCATED-NEXT: }
131+
# TRUNCATED-NEXT: ]
132+
133+
# 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
134+
135+
--- !ELF
136+
FileHeader:
137+
Class: ELFCLASS[[BITS]]
138+
Data: ELFDATA2LSB
139+
Type: ET_EXEC
140+
Sections:
141+
- Name: .text
142+
Type: SHT_PROGBITS
143+
Flags: [SHF_ALLOC]
144+
- Name: .text.bar
145+
Type: SHT_PROGBITS
146+
Flags: [SHF_ALLOC]
147+
- Name: .llvm_bb_addr_map
148+
Type: SHT_LLVM_BB_ADDR_MAP
149+
ShSize: [[SIZE=<none>]]
150+
Link: .text
151+
Entries:
152+
- Version: 2
153+
Feature: 0x7
154+
Address: [[ADDR=0x11111]]
155+
BBEntries:
156+
- ID: 0
157+
AddressOffset: 0x0
158+
Size: 0x1
159+
Metadata: 0x2
160+
- ID: 2
161+
AddressOffset: 0x3
162+
Size: 0x4
163+
Metadata: 0x15
164+
- Version: 2
165+
Feature: 0x3
166+
Address: 0x22222
167+
BBEntries:
168+
- ID: 4
169+
AddressOffset: 0x6
170+
Size: 0x7
171+
Metadata: 0x8
172+
PGOAnalyses:
173+
- FuncEntryCount: 100
174+
PGOBBEntries:
175+
- BBFreq: 100
176+
Successors:
177+
- ID: 2
178+
BrProb: 0xFFFFFFFF
179+
- BBFreq: 100
180+
Successors: []
181+
- FuncEntryCount: 8888
182+
PGOBBEntries:
183+
- BBFreq: 9000
184+
- Name: dummy_section
185+
Type: SHT_PROGBITS
186+
Size: 16
187+
- Name: '.llvm_bb_addr_map (1)'
188+
Type: SHT_LLVM_BB_ADDR_MAP
189+
Link: .text.bar
190+
Entries:
191+
- Version: 2
192+
Feature: [[FEATURE=0x1]]
193+
Address: 0x33333
194+
BBEntries:
195+
- ID: 6
196+
AddressOffset: 0x9
197+
Size: 0xa
198+
Metadata: 0x1b
199+
- ID: 7
200+
AddressOffset: 0xc
201+
Size: 0xd
202+
Metadata: 0xe
203+
PGOAnalyses:
204+
- FuncEntryCount: 89
205+
Symbols:
206+
- Name: foo
207+
Section: .text
208+
Type: STT_FUNC
209+
Value: 0x22222
210+
- Name: bar
211+
Section: .text.bar
212+
Type: STT_FUNC
213+
Value: 0x33333
214+

llvm/tools/llvm-readobj/ELFDumper.cpp

+48-13
Original file line numberDiff line numberDiff line change
@@ -7567,14 +7567,15 @@ template <class ELFT> void LLVMELFDumper<ELFT>::printBBAddrMaps() {
75677567
this->describe(*Sec));
75687568
continue;
75697569
}
7570+
std::vector<PGOAnalysisMap> PGOAnalyses;
75707571
Expected<std::vector<BBAddrMap>> BBAddrMapOrErr =
7571-
this->Obj.decodeBBAddrMap(*Sec, RelocSec);
7572+
this->Obj.decodeBBAddrMap(*Sec, RelocSec, &PGOAnalyses);
75727573
if (!BBAddrMapOrErr) {
75737574
this->reportUniqueWarning("unable to dump " + this->describe(*Sec) +
75747575
": " + toString(BBAddrMapOrErr.takeError()));
75757576
continue;
75767577
}
7577-
for (const BBAddrMap &AM : *BBAddrMapOrErr) {
7578+
for (const auto &[AM, PAM] : zip_equal(*BBAddrMapOrErr, PGOAnalyses)) {
75787579
DictScope D(W, "Function");
75797580
W.printHex("At", AM.Addr);
75807581
SmallVector<uint32_t> FuncSymIndex =
@@ -7588,17 +7589,51 @@ template <class ELFT> void LLVMELFDumper<ELFT>::printBBAddrMaps() {
75887589
FuncName = this->getStaticSymbolName(FuncSymIndex.front());
75897590
W.printString("Name", FuncName);
75907591

7591-
ListScope L(W, "BB entries");
7592-
for (const BBAddrMap::BBEntry &BBE : AM.BBEntries) {
7593-
DictScope L(W);
7594-
W.printNumber("ID", BBE.ID);
7595-
W.printHex("Offset", BBE.Offset);
7596-
W.printHex("Size", BBE.Size);
7597-
W.printBoolean("HasReturn", BBE.hasReturn());
7598-
W.printBoolean("HasTailCall", BBE.hasTailCall());
7599-
W.printBoolean("IsEHPad", BBE.isEHPad());
7600-
W.printBoolean("CanFallThrough", BBE.canFallThrough());
7601-
W.printBoolean("HasIndirectBranch", BBE.hasIndirectBranch());
7592+
{
7593+
ListScope L(W, "BB entries");
7594+
for (const BBAddrMap::BBEntry &BBE : AM.BBEntries) {
7595+
DictScope L(W);
7596+
W.printNumber("ID", BBE.ID);
7597+
W.printHex("Offset", BBE.Offset);
7598+
W.printHex("Size", BBE.Size);
7599+
W.printBoolean("HasReturn", BBE.hasReturn());
7600+
W.printBoolean("HasTailCall", BBE.hasTailCall());
7601+
W.printBoolean("IsEHPad", BBE.isEHPad());
7602+
W.printBoolean("CanFallThrough", BBE.canFallThrough());
7603+
W.printBoolean("HasIndirectBranch", BBE.hasIndirectBranch());
7604+
}
7605+
}
7606+
7607+
if (PAM.FeatEnable.anyEnabled()) {
7608+
DictScope PD(W, "PGO analyses");
7609+
7610+
if (PAM.FeatEnable.FuncEntryCount)
7611+
W.printNumber("FuncEntryCount", PAM.FuncEntryCount);
7612+
7613+
if (PAM.FeatEnable.BBFreq || PAM.FeatEnable.BrProb) {
7614+
ListScope L(W, "PGO BB entries");
7615+
for (const PGOAnalysisMap::PGOBBEntry &PBBE : PAM.BBEntries) {
7616+
DictScope L(W);
7617+
7618+
/// FIXME: currently we just emit the raw frequency, it may be
7619+
/// better to provide an option to scale it by the first entry
7620+
/// frequence using BlockFrequency::Scaled64 number
7621+
if (PAM.FeatEnable.BBFreq)
7622+
W.printNumber("Frequency", PBBE.BlockFreq.getFrequency());
7623+
7624+
if (PAM.FeatEnable.BrProb) {
7625+
ListScope L(W, "Successors");
7626+
for (const auto &Succ : PBBE.Successors) {
7627+
DictScope L(W);
7628+
W.printNumber("ID", Succ.ID);
7629+
/// FIXME: currently we just emit the raw numerator of the
7630+
/// probably, it may be better to provide an option to emit it
7631+
/// as a percentage or other prettied representation
7632+
W.printHex("Probability", Succ.Prob.getNumerator());
7633+
}
7634+
}
7635+
}
7636+
}
76027637
}
76037638
}
76047639
}

0 commit comments

Comments
 (0)