mirror of
https://github.com/intel/llvm.git
synced 2026-01-13 11:02:04 +08:00
[BOLT][AArch64] Always cover veneers in lite mode (#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.
This commit is contained in:
@@ -2582,6 +2582,10 @@ public:
|
||||
/// Return true if the function is an AArch64 linker inserted veneer
|
||||
bool isAArch64Veneer() const;
|
||||
|
||||
/// Return true if the function signature matches veneer or it was established
|
||||
/// to be a veneer.
|
||||
bool isPossibleVeneer() const;
|
||||
|
||||
virtual ~BinaryFunction();
|
||||
};
|
||||
|
||||
|
||||
@@ -4829,6 +4829,11 @@ bool BinaryFunction::isAArch64Veneer() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BinaryFunction::isPossibleVeneer() const {
|
||||
return BC.isAArch64() &&
|
||||
(isAArch64Veneer() || getOneName().starts_with("__AArch64"));
|
||||
}
|
||||
|
||||
void BinaryFunction::addRelocation(uint64_t Address, MCSymbol *Symbol,
|
||||
uint32_t RelType, uint64_t Addend,
|
||||
uint64_t Value) {
|
||||
|
||||
@@ -29,10 +29,6 @@ static llvm::cl::opt<bool>
|
||||
namespace llvm {
|
||||
namespace bolt {
|
||||
|
||||
static bool isPossibleVeneer(const BinaryFunction &BF) {
|
||||
return BF.isAArch64Veneer() || BF.getOneName().starts_with("__AArch64");
|
||||
}
|
||||
|
||||
Error VeneerElimination::runOnFunctions(BinaryContext &BC) {
|
||||
if (!opts::EliminateVeneers || !BC.isAArch64())
|
||||
return Error::success();
|
||||
@@ -40,7 +36,7 @@ Error VeneerElimination::runOnFunctions(BinaryContext &BC) {
|
||||
std::unordered_map<const MCSymbol *, const MCSymbol *> VeneerDestinations;
|
||||
uint64_t NumEliminatedVeneers = 0;
|
||||
for (BinaryFunction &BF : llvm::make_second_range(BC.getBinaryFunctions())) {
|
||||
if (!isPossibleVeneer(BF))
|
||||
if (!BF.isPossibleVeneer())
|
||||
continue;
|
||||
|
||||
if (BF.isIgnored())
|
||||
|
||||
@@ -3374,6 +3374,11 @@ void RewriteInstance::selectFunctionsToProcess() {
|
||||
if (mustSkip(Function))
|
||||
return false;
|
||||
|
||||
// Include veneer functions as we want to replace veneer calls with direct
|
||||
// ones.
|
||||
if (Function.isPossibleVeneer())
|
||||
return true;
|
||||
|
||||
// If the list is not empty, only process functions from the list.
|
||||
if (!opts::ForceFunctionNames.empty() || !ForceFunctionsNR.empty()) {
|
||||
// Regex check (-funcs and -funcs-file options).
|
||||
|
||||
56
bolt/test/AArch64/veneer-bolt.s
Normal file
56
bolt/test/AArch64/veneer-bolt.s
Normal file
@@ -0,0 +1,56 @@
|
||||
## Check that llvm-bolt correctly handles veneers in lite mode.
|
||||
|
||||
# RUN: llvm-mc -filetype=obj -triple aarch64-unknown-unknown %s -o %t.o
|
||||
# RUN: link_fdata %s %t.o %t.fdata
|
||||
# RUN: llvm-strip --strip-unneeded %t.o
|
||||
# RUN: %clang %cflags %t.o -o %t.exe -nostdlib -Wl,-q
|
||||
# RUN: llvm-bolt %t.exe -o %t.bolt --lite=1 --data %t.fdata \
|
||||
# RUN: --print-normalized 2>&1 | FileCheck %s --check-prefix=CHECK-VENEER
|
||||
|
||||
## Constant islands at the end of functions foo(), bar(), and _start() make each
|
||||
## one of them ~112MB in size. Thus the total code size exceeds 300MB.
|
||||
|
||||
.text
|
||||
.global foo
|
||||
.type foo, %function
|
||||
foo:
|
||||
bl _start
|
||||
bl bar
|
||||
ret
|
||||
.space 0x7000000
|
||||
.size foo, .-foo
|
||||
|
||||
.global bar
|
||||
.type bar, %function
|
||||
bar:
|
||||
bl foo
|
||||
bl _start
|
||||
ret
|
||||
.space 0x7000000
|
||||
.size bar, .-bar
|
||||
|
||||
.global hot
|
||||
.type hot, %function
|
||||
hot:
|
||||
# FDATA: 0 [unknown] 0 1 hot 0 0 100
|
||||
bl foo
|
||||
bl bar
|
||||
bl _start
|
||||
ret
|
||||
.size hot, .-hot
|
||||
|
||||
## Check that BOLT sees the call to foo, not to its veneer.
|
||||
# CHECK-VENEER-LABEL: Binary Function "hot"
|
||||
# CHECK-VENEER: bl
|
||||
# CHECK-VENEER-SAME: {{[[:space:]]foo[[:space:]]}}
|
||||
|
||||
.global _start
|
||||
.type _start, %function
|
||||
_start:
|
||||
bl foo
|
||||
bl bar
|
||||
bl hot
|
||||
ret
|
||||
.space 0x7000000
|
||||
.size _start, .-_start
|
||||
|
||||
Reference in New Issue
Block a user