]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commit
LoongArch: Allow to relax instructions into NOPs after handling alignment
authorWANG Xuerui <git@xen0n.name>
Sun, 6 Jul 2025 01:06:20 +0000 (09:06 +0800)
committercailulu <cailulu@loongson.cn>
Mon, 7 Jul 2025 10:09:20 +0000 (18:09 +0800)
commit392f8c40f0d3d9cbd4ee38d94bde06cf1b845e9f
treeace47ee164950f0a220b6d7d9026787bd227e6d4
parent21e608528c38e8edea3235a78be9886b7016ad89
LoongArch: Allow to relax instructions into NOPs after handling alignment

Right now, LoongArch linker relaxation is 2-pass, since after alignment
is done, byte deletion can no longer happen. However, as the alignment
pass also shrinks text sections, new relaxation chances may well be
created after alignment is done. Although at this point we can no longer
delete unused instructions without disturbing alignment, we can still
replace them with NOPs; popular LoongArch micro-architectures can
eliminate NOPs during execution, so we can expect a (very) slight
performance improvement from those late-created relaxation chances.

To achieve this, the number of relax passes is raised to 3 for
LoongArch, and every relaxation handler except loongarch_relax_align is
migrated to a new helper loongarch_relax_delete_or_nop, that either
deletes bytes or fills the bytes to be "deleted" with NOPs, depending on
whether the containing section already has undergone alignment. Also,
since no byte can be deleted during this relax pass, in the pass the
pending_delete_ops structure is no longer allocated, and
loongarch_calc_relaxed_addr(x) degrades to the trivial "return x" in
this case.

In addition, previously when calculating distances to symbols, an
extra segment alignment must be considered, because alignment may
increase distance between sites. However in the newly added 3rd pass
code size can no longer increase for "closed" sections, so we can skip
the adjustment for them to allow for a few more relaxation chances.

A simple way to roughly measure this change's effectiveness is to check
how many pcalau12i + addi.d pairs are relaxed into pcaddi's. Taking a
Firefox 140.0.2 test build of mine as an example:

Before: 47842 pcaddi's in libxul.so
After: 48089

This is a 0.5% increase, which is kind of acceptable for a peephole
optimization like this; of which 9 are due to the "relax"ed symbol
distance treatment.

Signed-off-by: WANG Xuerui <git@xen0n.name>
bfd/elfnn-loongarch.c
ld/emultempl/loongarchelf.em
ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
ld/testsuite/ld-loongarch-elf/relax-after-alignment.d [new file with mode: 0644]
ld/testsuite/ld-loongarch-elf/relax-after-alignment.s [new file with mode: 0644]