Skip to content

Commit 0878d07

Browse files
[llvm-objdump] Add support for symbolizing PGOBBAddrMap Info
This patch adds in support for symbolizing PGO information contained within the SHT_LLVM_BB_ADDR_MAP section in llvm-objdump. The outputs are simply the raw values contained within the section.
1 parent 6e1ecd1 commit 0878d07

File tree

2 files changed

+267
-17
lines changed

2 files changed

+267
-17
lines changed
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
# Test that in the presence of SHT_LLVM_BB_ADDR_MAP sections which also
2+
# contain PGO data, --symbolize-operands is able to label the basic blocks
3+
# correctly.
4+
5+
# Check the case where we only have entry counts.
6+
7+
# RUN: yaml2obj %s -o %t1
8+
# RUN: llvm-objdump %t1 -d --symbolize-operands --no-show-raw-insn --no-leading-addr | \
9+
# RUN: FileCheck %s --check-prefix=ENTRYCOUNT
10+
11+
--- !ELF
12+
FileHeader:
13+
Class: ELFCLASS64
14+
Data: ELFDATA2LSB
15+
Type: ET_EXEC
16+
Machine: EM_X86_64
17+
Sections:
18+
- Name: .text.foo
19+
Type: SHT_PROGBITS
20+
Address: 0x0
21+
Flags: [SHF_ALLOC, SHF_EXECINSTR]
22+
Content: '50'
23+
- Name: .llvm_bb_addr_map.foo
24+
Type: SHT_LLVM_BB_ADDR_MAP
25+
Link: .text.foo
26+
Entries:
27+
- Version: 2
28+
Address: 0x0
29+
Feature: 0x1
30+
BBEntries:
31+
- ID: 3
32+
AddressOffset: 0x0
33+
Size: 0x1
34+
Metadata: 0x1
35+
PGOAnalyses:
36+
- FuncEntryCount: 1000
37+
Symbols:
38+
- Name: foo
39+
Section: .text.foo
40+
Value: 0x0
41+
42+
# ENTRYCOUNT: <foo>:
43+
# ENTRYCOUNT: <BB3> (Entry count: 1000):
44+
45+
# Check the case where we have entrypoints and block frequency information
46+
47+
# RUN: yaml2obj %s --docnum=2 -o %t2
48+
# RUN: llvm-objdump %t2 -d --symbolize-operands --no-show-raw-insn --no-leading-addr | \
49+
# RUN: FileCheck %s --check-prefix=ENTRYCOUNT-BLOCKFREQ
50+
51+
--- !ELF
52+
FileHeader:
53+
Class: ELFCLASS64
54+
Data: ELFDATA2LSB
55+
Type: ET_EXEC
56+
Machine: EM_X86_64
57+
Sections:
58+
- Name: .text.foo
59+
Type: SHT_PROGBITS
60+
Address: 0x0
61+
Flags: [SHF_ALLOC, SHF_EXECINSTR]
62+
Content: '503b0505200000907d02ebf5c3'
63+
- Name: .llvm_bb_addr_map.foo
64+
Type: SHT_LLVM_BB_ADDR_MAP
65+
Link: .text.foo
66+
Entries:
67+
- Version: 2
68+
Address: 0x0
69+
Feature: 0x3
70+
BBEntries:
71+
- ID: 3
72+
AddressOffset: 0x0
73+
Size: 0x1
74+
Metadata: 0x1
75+
- ID: 1
76+
AddressOffset: 0x0
77+
Size: 0x6
78+
Metadata: 0x0
79+
- ID: 2
80+
AddressOffset: 0x1
81+
Size: 0x4
82+
Metadata: 0x0
83+
- ID: 5
84+
AddressOffset: 0x0
85+
Size: 0x1
86+
Metadata: 0x2
87+
PGOAnalyses:
88+
- FuncEntryCount: 1000
89+
PGOBBEntries:
90+
- BBFreq: 1000
91+
- BBFreq: 133
92+
- BBFreq: 18
93+
- BBFreq: 1000
94+
Symbols:
95+
- Name: foo
96+
Section: .text.foo
97+
Value: 0x0
98+
99+
# ENTRYCOUNT-BLOCKFREQ: <foo>:
100+
# ENTRYCOUNT-BLOCKFREQ: <BB3> (Entry count: 1000, Frequency: 1000):
101+
# ENTRYCOUNT-BLOCKFREQ: <BB1> (Frequency: 133):
102+
# ENTRYCOUNT-BLOCKFREQ: <BB2> (Frequency: 18):
103+
# ENTRYCOUNT-BLOCKFREQ: <BB5> (Frequency: 1000):
104+
105+
# Check the case where we have entrypoints, block frequency, and branch
106+
# proabability information.
107+
108+
# RUN: yaml2obj %s --docnum=3 -o %t3
109+
# RUN: llvm-objdump %t3 -d --symbolize-operands --no-show-raw-insn --no-leading-addr | \
110+
# RUN: FileCheck %s --check-prefix=ENTRY-FREQ-PROB
111+
112+
--- !ELF
113+
FileHeader:
114+
Class: ELFCLASS64
115+
Data: ELFDATA2LSB
116+
Type: ET_EXEC
117+
Machine: EM_X86_64
118+
Sections:
119+
- Name: .text.foo
120+
Type: SHT_PROGBITS
121+
Address: 0x0
122+
Flags: [SHF_ALLOC, SHF_EXECINSTR]
123+
Content: '503b0505200000907d02ebf5c3'
124+
- Name: .llvm_bb_addr_map.foo
125+
Type: SHT_LLVM_BB_ADDR_MAP
126+
Link: .text.foo
127+
Entries:
128+
- Version: 2
129+
Address: 0x0
130+
Feature: 0x7
131+
BBEntries:
132+
- ID: 3
133+
AddressOffset: 0x0
134+
Size: 0x1
135+
Metadata: 0x1
136+
- ID: 1
137+
AddressOffset: 0x0
138+
Size: 0x6
139+
Metadata: 0x0
140+
- ID: 2
141+
AddressOffset: 0x1
142+
Size: 0x4
143+
Metadata: 0x0
144+
- ID: 5
145+
AddressOffset: 0x0
146+
Size: 0x1
147+
Metadata: 0x2
148+
PGOAnalyses:
149+
- FuncEntryCount: 1000
150+
PGOBBEntries:
151+
- BBFreq: 1000
152+
Successors:
153+
- ID: 1
154+
BrProb: 0x22222222
155+
- ID: 2
156+
BrProb: 0x33333333
157+
- ID: 3
158+
BrProb: 0xaaaaaaaa
159+
- BBFreq: 133
160+
Successors:
161+
- ID: 2
162+
BrProb: 0x11111111
163+
- ID: 3
164+
BrProb: 0xeeeeeeee
165+
- BBFreq: 18
166+
Successors:
167+
- ID: 3
168+
BrProb: 0xffffffff
169+
- BBFreq: 1000
170+
Successors: []
171+
Symbols:
172+
- Name: foo
173+
Section: .text.foo
174+
Value: 0x0
175+
176+
# ENTRY-FREQ-PROB: <foo>:
177+
# ENTRY-FREQ-PROB: <BB3> (Entry count: 1000, Frequency: 1000, Successors: BB1:22222222, BB2:33333333, BB3:aaaaaaaa):
178+
# ENTRY-FREQ-PROB: <BB1> (Frequency: 133, Successors: BB2:11111111, BB3:eeeeeeee):
179+
# ENTRY-FREQ-PROB: <BB2> (Frequency: 18, Successors: BB3:ffffffff):
180+
# ENTRY-FREQ-PROB: <BB5> (Frequency: 1000):
181+

llvm/tools/llvm-objdump/llvm-objdump.cpp

Lines changed: 86 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1264,10 +1264,53 @@ static SymbolInfoTy createDummySymbolInfo(const ObjectFile &Obj,
12641264
return SymbolInfoTy(Addr, Name, Type);
12651265
}
12661266

1267-
static void
1268-
collectBBAddrMapLabels(const std::unordered_map<uint64_t, BBAddrMap> &AddrToBBAddrMap,
1269-
uint64_t SectionAddr, uint64_t Start, uint64_t End,
1270-
std::unordered_map<uint64_t, std::vector<std::string>> &Labels) {
1267+
struct BBAddrMapLabel {
1268+
std::string BlockLabel;
1269+
std::string PGOAnalysis;
1270+
};
1271+
1272+
static void constructPGOLabelString(std::string &PGOString,
1273+
const PGOAnalysisMap &PGOMap,
1274+
size_t BBEntryIndex) {
1275+
raw_string_ostream PGOSS(PGOString);
1276+
1277+
PGOSS << " (";
1278+
if (PGOMap.FeatEnable.FuncEntryCount && BBEntryIndex == 0) {
1279+
PGOSS << "Entry count: " << Twine(PGOMap.FuncEntryCount);
1280+
if (PGOMap.FeatEnable.BBFreq || PGOMap.FeatEnable.BrProb) {
1281+
PGOSS << ", ";
1282+
}
1283+
}
1284+
1285+
if (PGOMap.FeatEnable.BBFreq || PGOMap.FeatEnable.BrProb) {
1286+
const PGOAnalysisMap::PGOBBEntry &PGOBBEntry =
1287+
PGOMap.BBEntries[BBEntryIndex];
1288+
1289+
if (PGOMap.FeatEnable.BBFreq) {
1290+
PGOSS << "Frequency: " << Twine(PGOBBEntry.BlockFreq.getFrequency());
1291+
if (PGOMap.FeatEnable.BrProb && PGOBBEntry.Successors.size() > 0) {
1292+
PGOSS << ", ";
1293+
}
1294+
}
1295+
if (PGOMap.FeatEnable.BrProb && PGOBBEntry.Successors.size() > 0) {
1296+
PGOSS << "Successors: ";
1297+
interleaveComma(
1298+
PGOBBEntry.Successors, PGOSS,
1299+
[&PGOSS](const PGOAnalysisMap::PGOBBEntry::SuccessorEntry &SE) {
1300+
PGOSS << "BB" << SE.ID << ":";
1301+
PGOSS.write_hex(SE.Prob.getNumerator());
1302+
});
1303+
}
1304+
}
1305+
PGOSS << ")";
1306+
}
1307+
1308+
static void collectBBAddrMapLabels(
1309+
const std::unordered_map<uint64_t, BBAddrMap> &AddrToBBAddrMap,
1310+
const std::unordered_map<uint64_t, PGOAnalysisMap> &AddrToPGOAnalysisMap,
1311+
uint64_t SectionAddr, uint64_t Start, uint64_t End,
1312+
std::unordered_map<uint64_t, std::vector<BBAddrMapLabel>> &Labels,
1313+
const StringRef FileName) {
12711314
if (AddrToBBAddrMap.empty())
12721315
return;
12731316
Labels.clear();
@@ -1276,11 +1319,27 @@ collectBBAddrMapLabels(const std::unordered_map<uint64_t, BBAddrMap> &AddrToBBAd
12761319
auto Iter = AddrToBBAddrMap.find(StartAddress);
12771320
if (Iter == AddrToBBAddrMap.end())
12781321
return;
1279-
for (const BBAddrMap::BBEntry &BBEntry : Iter->second.getBBEntries()) {
1322+
auto PGOIter = AddrToPGOAnalysisMap.find(StartAddress);
1323+
if (!AddrToPGOAnalysisMap.empty() && PGOIter == AddrToPGOAnalysisMap.end())
1324+
reportWarning("Expected BBAddrMap and PGOAnalysisMap to have information "
1325+
"on the same basic blocks",
1326+
FileName);
1327+
1328+
for (size_t I = 0; I < Iter->second.getBBEntries().size(); ++I) {
1329+
const BBAddrMap::BBEntry &BBEntry = Iter->second.getBBEntries()[I];
12801330
uint64_t BBAddress = BBEntry.Offset + Iter->second.getFunctionAddress();
12811331
if (BBAddress >= EndAddress)
12821332
continue;
1283-
Labels[BBAddress].push_back(("BB" + Twine(BBEntry.ID)).str());
1333+
1334+
std::string LabelString = ("BB" + Twine(BBEntry.ID)).str();
1335+
std::string PGOString;
1336+
1337+
if (!AddrToPGOAnalysisMap.empty() &&
1338+
PGOIter != AddrToPGOAnalysisMap.end() &&
1339+
PGOIter->second.FeatEnable.anyEnabled())
1340+
constructPGOLabelString(PGOString, PGOIter->second, I);
1341+
1342+
Labels[BBAddress].push_back({LabelString, PGOString});
12841343
}
12851344
}
12861345

@@ -1638,18 +1697,25 @@ disassembleObject(ObjectFile &Obj, const ObjectFile &DbgObj,
16381697
LLVM_DEBUG(LVP.dump());
16391698

16401699
std::unordered_map<uint64_t, BBAddrMap> AddrToBBAddrMap;
1700+
std::unordered_map<uint64_t, PGOAnalysisMap> AddrToPGOAnalysisMap;
16411701
auto ReadBBAddrMap = [&](std::optional<unsigned> SectionIndex =
16421702
std::nullopt) {
16431703
AddrToBBAddrMap.clear();
16441704
if (const auto *Elf = dyn_cast<ELFObjectFileBase>(&Obj)) {
1645-
auto BBAddrMapsOrErr = Elf->readBBAddrMap(SectionIndex);
1705+
std::vector<PGOAnalysisMap> PGOAnalyses;
1706+
auto BBAddrMapsOrErr = Elf->readBBAddrMap(SectionIndex, &PGOAnalyses);
16461707
if (!BBAddrMapsOrErr) {
16471708
reportWarning(toString(BBAddrMapsOrErr.takeError()), Obj.getFileName());
16481709
return;
16491710
}
1650-
for (auto &FunctionBBAddrMap : *BBAddrMapsOrErr)
1651-
AddrToBBAddrMap.emplace(FunctionBBAddrMap.Addr,
1652-
std::move(FunctionBBAddrMap));
1711+
for (size_t I = 0; I < (*BBAddrMapsOrErr).size(); ++I) {
1712+
uint64_t BBAddrMapAddr = (*BBAddrMapsOrErr)[I].Addr;
1713+
AddrToBBAddrMap.emplace(BBAddrMapAddr,
1714+
std::move((*BBAddrMapsOrErr)[I]));
1715+
if (PGOAnalyses.size() > 0)
1716+
AddrToPGOAnalysisMap.emplace(BBAddrMapAddr,
1717+
std::move(PGOAnalyses[I]));
1718+
}
16531719
}
16541720
};
16551721

@@ -1978,14 +2044,15 @@ disassembleObject(ObjectFile &Obj, const ObjectFile &DbgObj,
19782044
FOS.SetUnbuffered();
19792045

19802046
std::unordered_map<uint64_t, std::string> AllLabels;
1981-
std::unordered_map<uint64_t, std::vector<std::string>> BBAddrMapLabels;
2047+
std::unordered_map<uint64_t, std::vector<BBAddrMapLabel>> BBAddrMapLabels;
19822048
if (SymbolizeOperands) {
19832049
collectLocalBranchTargets(Bytes, DT->InstrAnalysis.get(),
19842050
DT->DisAsm.get(), DT->InstPrinter.get(),
19852051
PrimaryTarget.SubtargetInfo.get(),
19862052
SectionAddr, Index, End, AllLabels);
1987-
collectBBAddrMapLabels(AddrToBBAddrMap, SectionAddr, Index, End,
1988-
BBAddrMapLabels);
2053+
collectBBAddrMapLabels(AddrToBBAddrMap, AddrToPGOAnalysisMap,
2054+
SectionAddr, Index, End, BBAddrMapLabels,
2055+
FileName);
19892056
}
19902057

19912058
if (DT->InstrAnalysis)
@@ -2083,8 +2150,9 @@ disassembleObject(ObjectFile &Obj, const ObjectFile &DbgObj,
20832150
// Print local label if there's any.
20842151
auto Iter1 = BBAddrMapLabels.find(SectionAddr + Index);
20852152
if (Iter1 != BBAddrMapLabels.end()) {
2086-
for (StringRef Label : Iter1->second)
2087-
FOS << "<" << Label << ">:\n";
2153+
for (const auto &BBLabel : Iter1->second)
2154+
FOS << "<" << BBLabel.BlockLabel << ">" << BBLabel.PGOAnalysis
2155+
<< ":\n";
20882156
} else {
20892157
auto Iter2 = AllLabels.find(SectionAddr + Index);
20902158
if (Iter2 != AllLabels.end())
@@ -2261,7 +2329,7 @@ disassembleObject(ObjectFile &Obj, const ObjectFile &DbgObj,
22612329
} else if (!Disp) {
22622330
*TargetOS << TargetName;
22632331
} else if (BBAddrMapLabelAvailable) {
2264-
*TargetOS << BBAddrMapLabels[Target].front();
2332+
*TargetOS << BBAddrMapLabels[Target].front().BlockLabel;
22652333
} else if (LabelAvailable) {
22662334
*TargetOS << AllLabels[Target];
22672335
} else {
@@ -2277,7 +2345,8 @@ disassembleObject(ObjectFile &Obj, const ObjectFile &DbgObj,
22772345
}
22782346

22792347
} else if (BBAddrMapLabelAvailable) {
2280-
*TargetOS << " <" << BBAddrMapLabels[Target].front() << ">";
2348+
*TargetOS << " <" << BBAddrMapLabels[Target].front().BlockLabel
2349+
<< ">";
22812350
} else if (LabelAvailable) {
22822351
*TargetOS << " <" << AllLabels[Target] << ">";
22832352
}

0 commit comments

Comments
 (0)