Skip to content

Commit c4c4e17

Browse files
authored
[BOLT] Use heuristic for matching split local functions (#90424)
Use known order of BOLT split function symbols: fragment symbols immediately precede the parent fragment symbol. Depends On: #89648 Test Plan: Added register-fragments-bolt-symbols.s
1 parent 1b70580 commit c4c4e17

File tree

2 files changed

+50
-0
lines changed

2 files changed

+50
-0
lines changed

bolt/lib/Rewrite/RewriteInstance.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1513,6 +1513,23 @@ void RewriteInstance::registerFragments() {
15131513
StopSymbol = *FSI;
15141514

15151515
uint64_t ParentAddress{0};
1516+
1517+
// BOLT split fragment symbols are emitted just before the main function
1518+
// symbol.
1519+
for (ELFSymbolRef NextSymbol = Symbol; NextSymbol < StopSymbol;
1520+
NextSymbol.moveNext()) {
1521+
StringRef Name = cantFail(NextSymbol.getName());
1522+
if (Name == ParentName) {
1523+
ParentAddress = cantFail(NextSymbol.getValue());
1524+
goto registerParent;
1525+
}
1526+
if (Name.starts_with(ParentName))
1527+
// With multi-way splitting, there are multiple fragments with different
1528+
// suffixes. Parent follows the last fragment.
1529+
continue;
1530+
break;
1531+
}
1532+
15161533
// Iterate over local file symbols and check symbol names to match parent.
15171534
for (ELFSymbolRef Symbol(FSI[-1]); Symbol < StopSymbol; Symbol.moveNext()) {
15181535
if (cantFail(Symbol.getName()) == ParentName) {
@@ -1521,6 +1538,7 @@ void RewriteInstance::registerFragments() {
15211538
}
15221539
}
15231540

1541+
registerParent:
15241542
// No local parent is found, use global parent function.
15251543
if (!ParentAddress)
15261544
if (BinaryData *ParentBD = BC->getBinaryDataByName(ParentName))
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Test the heuristics for matching BOLT-added split functions.
2+
3+
# RUN: llvm-mc --filetype=obj --triple x86_64-unknown-unknown %S/cdsplit-symbol-names.s -o %t.main.o
4+
# RUN: llvm-mc --filetype=obj --triple x86_64-unknown-unknown %s -o %t.chain.o
5+
# RUN: link_fdata %S/cdsplit-symbol-names.s %t.main.o %t.fdata
6+
# RUN: sed -i 's|chain|chain/2|g' %t.fdata
7+
# RUN: llvm-strip --strip-unneeded %t.main.o
8+
# RUN: llvm-objcopy --localize-symbol=chain %t.main.o
9+
# RUN: %clang %cflags %t.chain.o %t.main.o -o %t.exe -Wl,-q
10+
# RUN: llvm-bolt %t.exe -o %t.bolt --split-functions --split-strategy=randomN \
11+
# RUN: --reorder-blocks=ext-tsp --enable-bat --bolt-seed=7 --data=%t.fdata
12+
# RUN: llvm-objdump --syms %t.bolt | FileCheck %s --check-prefix=CHECK-SYMS
13+
14+
# RUN: link_fdata %s %t.bolt %t.preagg PREAGG
15+
# PREAGG: B X:0 #chain.cold.0# 1 0
16+
# RUN: perf2bolt %t.bolt -p %t.preagg --pa -o %t.bat.fdata -w %t.bat.yaml -v=1 \
17+
# RUN: | FileCheck %s --check-prefix=CHECK-REGISTER
18+
19+
# CHECK-SYMS: l df *ABS* [[#]] chain.s
20+
# CHECK-SYMS: l F .bolt.org.text [[#]] chain
21+
# CHECK-SYMS: l F .text.cold [[#]] chain.cold.0
22+
# CHECK-SYMS: l F .text [[#]] chain
23+
# CHECK-SYMS: l df *ABS* [[#]] bolt-pseudo.o
24+
25+
# CHECK-REGISTER: BOLT-INFO: marking chain.cold.0/1(*2) as a fragment of chain/2(*2)
26+
27+
.file "chain.s"
28+
.text
29+
.type chain, @function
30+
chain:
31+
ret
32+
.size chain, .-chain

0 commit comments

Comments
 (0)