Skip to content

Commit 1efb537

Browse files
authored
[BOLT][AArch64] Enable safe ICF (#170172)
All the pieces required seem to have already been in place so just need to enable the option. Also added one more string prefix for vtable recognition.
1 parent 186c9a7 commit 1efb537

File tree

2 files changed

+78
-3
lines changed

2 files changed

+78
-3
lines changed

bolt/lib/Passes/IdenticalCodeFolding.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,8 @@ namespace bolt {
377377
void IdenticalCodeFolding::initVTableReferences(const BinaryContext &BC) {
378378
for (const auto &[Address, Data] : BC.getBinaryData()) {
379379
// Filter out all symbols that are not vtables.
380-
if (!Data->getName().starts_with("_ZTV"))
380+
if (!Data->getName().starts_with("_ZTV") && // vtable
381+
!Data->getName().starts_with("_ZTCN")) // construction vtable
381382
continue;
382383
for (uint64_t I = Address, End = I + Data->getSize(); I < End; I += 8)
383384
setAddressUsedInVTable(I);
@@ -437,8 +438,9 @@ void IdenticalCodeFolding::markFunctionsUnsafeToFold(BinaryContext &BC) {
437438
NamedRegionTimer MarkFunctionsUnsafeToFoldTimer(
438439
"markFunctionsUnsafeToFold", "markFunctionsUnsafeToFold", "ICF breakdown",
439440
"ICF breakdown", opts::TimeICF);
440-
if (!BC.isX86())
441-
BC.outs() << "BOLT-WARNING: safe ICF is only supported for x86\n";
441+
if (!BC.isX86() && !BC.isAArch64())
442+
BC.outs()
443+
<< "BOLT-WARNING: safe ICF is only supported for x86 and AArch64\n";
442444
analyzeDataRelocations(BC);
443445
analyzeFunctions(BC);
444446
}

bolt/test/AArch64/safe-icf.s

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# Test BOLT can do safe ICF for AArch64.
2+
3+
# REQUIRES: system-linux,asserts
4+
5+
# RUN: %clang %cflags -x assembler-with-cpp %s -o %t1.so -Wl,-q \
6+
# RUN: -Wl,-z,notext -DREF_BY_NON_CONTROL_FLOW_INSTR
7+
# RUN: %clang %cflags -x assembler-with-cpp %s -o %t2.so -Wl,-q \
8+
# RUN: -Wl,-z,notext -DREF_IN_RW_DATA_SEC
9+
# RUN: %clang %cflags -x assembler-with-cpp %s -o %t3.so -Wl,-q \
10+
# RUN: -Wl,-z,notext -DNO_DUMMY_TEXT_RELOC
11+
12+
# RUN: llvm-bolt %t1.so -o %t.bolt --no-threads --debug-only=bolt-icf \
13+
# RUN: --icf=all 2>&1 | FileCheck %s --check-prefix=ICF-ALL
14+
# RUN: llvm-bolt %t2.so -o %t.bolt --no-threads --debug-only=bolt-icf \
15+
# RUN: --icf=all 2>&1 | FileCheck %s --check-prefix=ICF-ALL
16+
# RUN: llvm-bolt %t3.so -o %t.bolt --no-threads --debug-only=bolt-icf \
17+
# RUN: --icf=all 2>&1 | FileCheck %s --check-prefix=ICF-ALL
18+
19+
# RUN: llvm-bolt %t1.so -o %t.bolt --no-threads --debug-only=bolt-icf \
20+
# RUN: --icf=safe 2>&1 | FileCheck %s --check-prefix=ICF-SAFE
21+
# RUN: llvm-bolt %t2.so -o %t.bolt --no-threads --debug-only=bolt-icf \
22+
# RUN: --icf=safe 2>&1 | FileCheck %s --check-prefix=ICF-SAFE
23+
24+
# RUN: not llvm-bolt %t3.so -o %t.bolt --icf=safe 2>&1 | FileCheck %s \
25+
# RUN: --check-prefix=ERROR
26+
27+
# ICF-ALL: folding bar into foo
28+
# ICF-SAFE: skipping function with reference taken foo
29+
# ERROR: binary built without relocations. Safe ICF is not supported
30+
31+
.text
32+
33+
.global foo
34+
.type foo, %function
35+
foo:
36+
mov x0, #0x10
37+
ret
38+
39+
.global bar
40+
.type bar, %function
41+
bar:
42+
mov x0, #0x10
43+
ret
44+
45+
#if defined(REF_IN_RW_DATA_SEC) && !defined(NO_DUMMY_TEXT_RELOC)
46+
# Dummy relocation to force relocation mode
47+
.reloc 0, R_AARCH64_NONE
48+
#endif
49+
50+
#if defined(REF_BY_NON_CONTROL_FLOW_INSTR)
51+
.global random
52+
.type random, %function
53+
random:
54+
adrp x8, foo
55+
add x8, x8, :lo12:goo
56+
br x8
57+
#endif
58+
59+
#if defined(REF_IN_RW_DATA_SEC)
60+
.data
61+
.balign 8
62+
.global funcptr
63+
funcptr:
64+
.xword foo
65+
#endif
66+
67+
.section .rodata
68+
.global _ZTVxx
69+
.balign 8
70+
_ZTVxx:
71+
.xword foo
72+
.xword bar
73+
.size _ZTVxx, .-_ZTVxx

0 commit comments

Comments
 (0)