Skip to content

Commit 28ff941

Browse files
authored
[BOLT][AArch64] Always cover veneers in lite mode (llvm#171534)
If a veneer is not disassembled in lite mode, the veneer elimination pass will not recognize it as such and the call to such veneer will remain unchanged. Later, we may need to insert a new veneer for such code ending up with a double veneer. To avoid such suboptimal code generation, always disassemble veneers and guarantee that they are converted to direct calls in BOLT.
1 parent 3ece662 commit 28ff941

File tree

5 files changed

+71
-5
lines changed

5 files changed

+71
-5
lines changed

bolt/include/bolt/Core/BinaryFunction.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2582,6 +2582,10 @@ class BinaryFunction {
25822582
/// Return true if the function is an AArch64 linker inserted veneer
25832583
bool isAArch64Veneer() const;
25842584

2585+
/// Return true if the function signature matches veneer or it was established
2586+
/// to be a veneer.
2587+
bool isPossibleVeneer() const;
2588+
25852589
virtual ~BinaryFunction();
25862590
};
25872591

bolt/lib/Core/BinaryFunction.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4829,6 +4829,11 @@ bool BinaryFunction::isAArch64Veneer() const {
48294829
return true;
48304830
}
48314831

4832+
bool BinaryFunction::isPossibleVeneer() const {
4833+
return BC.isAArch64() &&
4834+
(isAArch64Veneer() || getOneName().starts_with("__AArch64"));
4835+
}
4836+
48324837
void BinaryFunction::addRelocation(uint64_t Address, MCSymbol *Symbol,
48334838
uint32_t RelType, uint64_t Addend,
48344839
uint64_t Value) {

bolt/lib/Passes/VeneerElimination.cpp

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,18 +29,14 @@ static llvm::cl::opt<bool>
2929
namespace llvm {
3030
namespace bolt {
3131

32-
static bool isPossibleVeneer(const BinaryFunction &BF) {
33-
return BF.isAArch64Veneer() || BF.getOneName().starts_with("__AArch64");
34-
}
35-
3632
Error VeneerElimination::runOnFunctions(BinaryContext &BC) {
3733
if (!opts::EliminateVeneers || !BC.isAArch64())
3834
return Error::success();
3935

4036
std::unordered_map<const MCSymbol *, const MCSymbol *> VeneerDestinations;
4137
uint64_t NumEliminatedVeneers = 0;
4238
for (BinaryFunction &BF : llvm::make_second_range(BC.getBinaryFunctions())) {
43-
if (!isPossibleVeneer(BF))
39+
if (!BF.isPossibleVeneer())
4440
continue;
4541

4642
if (BF.isIgnored())

bolt/lib/Rewrite/RewriteInstance.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3374,6 +3374,11 @@ void RewriteInstance::selectFunctionsToProcess() {
33743374
if (mustSkip(Function))
33753375
return false;
33763376

3377+
// Include veneer functions as we want to replace veneer calls with direct
3378+
// ones.
3379+
if (Function.isPossibleVeneer())
3380+
return true;
3381+
33773382
// If the list is not empty, only process functions from the list.
33783383
if (!opts::ForceFunctionNames.empty() || !ForceFunctionsNR.empty()) {
33793384
// Regex check (-funcs and -funcs-file options).

bolt/test/AArch64/veneer-bolt.s

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
## Check that llvm-bolt correctly handles veneers in lite mode.
2+
3+
# RUN: llvm-mc -filetype=obj -triple aarch64-unknown-unknown %s -o %t.o
4+
# RUN: link_fdata %s %t.o %t.fdata
5+
# RUN: llvm-strip --strip-unneeded %t.o
6+
# RUN: %clang %cflags %t.o -o %t.exe -nostdlib -Wl,-q
7+
# RUN: llvm-bolt %t.exe -o %t.bolt --lite=1 --data %t.fdata \
8+
# RUN: --print-normalized 2>&1 | FileCheck %s --check-prefix=CHECK-VENEER
9+
10+
## Constant islands at the end of functions foo(), bar(), and _start() make each
11+
## one of them ~112MB in size. Thus the total code size exceeds 300MB.
12+
13+
.text
14+
.global foo
15+
.type foo, %function
16+
foo:
17+
bl _start
18+
bl bar
19+
ret
20+
.space 0x7000000
21+
.size foo, .-foo
22+
23+
.global bar
24+
.type bar, %function
25+
bar:
26+
bl foo
27+
bl _start
28+
ret
29+
.space 0x7000000
30+
.size bar, .-bar
31+
32+
.global hot
33+
.type hot, %function
34+
hot:
35+
# FDATA: 0 [unknown] 0 1 hot 0 0 100
36+
bl foo
37+
bl bar
38+
bl _start
39+
ret
40+
.size hot, .-hot
41+
42+
## Check that BOLT sees the call to foo, not to its veneer.
43+
# CHECK-VENEER-LABEL: Binary Function "hot"
44+
# CHECK-VENEER: bl
45+
# CHECK-VENEER-SAME: {{[[:space:]]foo[[:space:]]}}
46+
47+
.global _start
48+
.type _start, %function
49+
_start:
50+
bl foo
51+
bl bar
52+
bl hot
53+
ret
54+
.space 0x7000000
55+
.size _start, .-_start
56+

0 commit comments

Comments
 (0)