AArch64: Optimize zero-resolving ADD relocations
AArch64 ADD relocations that resolve to zero are now optimized to MOV or NOP instructions.
This patch introduces an optimization for AArch64 AArch64 ADD instructions where the immediate value becomes zero after relocation. According to the ARM architecture specification, such instructions can be replaced with a MOV instruction (for different source and destination registers) or a NOP (for the same source and destination register). This optimization is applied conditionally, respecting the --no-relax linker option, and ensures that 32-bit operations correctly clear the upper bits.
- reviewer
Agrees with the patch but requests renaming the `optimize_add_zero` boolean to `optimize_relocations` for better future-proofing.
“Please rename the bool optimize_add_zero to optimize_relocations, wherever it occurs. This will be a more appropriate name if/when any further optimisations are implemented. Ok with that change.”
- proposer
Submitted a patch to optimize AArch64 ADD instructions that resolve to zero, replacing them with MOV or NOP.
“The "ELF for the Arm 64-bit Architecture" specification, section 5.7.9, recommends that linkers optimize ADD instructions whose immediate becomes zero after relocation. In particular: ADD x0, x1, 0 ADD x2, x2, 0 may be replaced with: MOV x0, x1 NOP”
Technical Tradeoffs
- Improves code density and potentially performance by replacing redundant ADD instructions.
- Adds complexity to the relocation handling logic.
- Ensures compatibility with `--no-relax` option.
In Details
This patch optimizes AArch64 ADD instructions that, after relocation, have an immediate value of zero. The optimization replaces ADD Rx, Ry, 0 with MOV Rx, Ry and ADD Rx, Rx, 0 with NOP. This is based on ELF for AArch64 spec section 5.7.9. The changes affect aarch64_relocate and aarch64_build_one_stub in elfnn-aarch64.c, honoring --no-relax. A test case is added to verify the behavior with --no-relax.
- AArch64
- The 64-bit ARM architecture.
- ADD relocation
- A relocation operation that modifies the immediate value of an ADD instruction after linking.
- MOV instruction
- A processor instruction that copies a value from a source operand to a destination operand.
- NOP
- No Operation. A processor instruction that does nothing but consume clock cycles.
- --no-relax
- A linker option that prevents relaxation, a process where the linker modifies instructions to optimize for code size or performance. In this context, it ensures that ADD instructions resolving to zero are not modified if relaxation is disabled.