Skip to content

Commit

Permalink
[BOLT][AArch64] Remove nops in functions with defined control flow (l…
Browse files Browse the repository at this point in the history
…lvm#124705)

When a function has an indirect branch with unknown control flow, we
preserve nops in order to keep all instruction offsets (from the start
of the function) the same in case the indirect branch is used by a
PC-relative jump table. However, when we know the control flow of the
function, we should be able to safely remove nops.
  • Loading branch information
maksfb authored Jan 28, 2025
1 parent 1d5ce61 commit ef232a7
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 1 deletion.
5 changes: 4 additions & 1 deletion bolt/lib/Core/BinaryFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -795,7 +795,6 @@ BinaryFunction::processIndirectBranch(MCInst &Instruction, unsigned Size,

auto Begin = Instructions.begin();
if (BC.isAArch64()) {
PreserveNops = BC.HasRelocations;
// Start at the last label as an approximation of the current basic block.
// This is a heuristic, since the full set of labels have yet to be
// determined
Expand Down Expand Up @@ -2300,6 +2299,10 @@ Error BinaryFunction::buildCFG(MCPlusBuilder::AllocatorIdTy AllocatorId) {
BC.errs() << "BOLT-WARNING: failed to post-process indirect branches for "
<< *this << '\n';
}

if (BC.isAArch64())
PreserveNops = BC.HasRelocations;

// In relocation mode we want to keep processing the function but avoid
// optimizing it.
setSimple(false);
Expand Down
28 changes: 28 additions & 0 deletions bolt/test/AArch64/remove-nops.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
## Verify that llvm-bolt removes nop instructions from functions with indirect
## branches that have defined control flow.

# REQUIRES: system-linux

# RUN: llvm-mc -filetype=obj -triple aarch64-unknown-unknown %s -o %t.o
# RUN: %clang %cflags --target=aarch64-unknown-linux %t.o -o %t.exe -Wl,-q
# RUN: llvm-bolt %t.exe -o %t.bolt --print-normalized 2>&1 | FileCheck %s
# RUN: llvm-objdump -d --disassemble-symbols=_start %t.bolt \
# RUN: | FileCheck %s --check-prefix=CHECK-OBJDUMP

# CHECK-OBJDUMP-LABEL: _start
# CHECK-OBJDUMP-NOT: nop

.section .text
.align 4
.globl _start
.type _start, %function
_start:
# CHECK-LABEL: Binary Function "_start"
nop
# CHECK-NOT: nop
br x0
# CHECK: br x0 # TAILCALL
.size _start, .-_start

## Force relocation mode.
.reloc 0, R_AARCH64_NONE

0 comments on commit ef232a7

Please sign in to comment.