[PATCH] LoongArch: Allow to relax instructions into NOPs after handling alignment
WANG Xuerui
i.swmail@xen0n.name
Mon Jun 30 08:03:37 GMT 2025
On 6/30/25 14:40, Xi Ruoyao wrote:
> On Mon, 2025-06-30 at 01:33 +0800, WANG Xuerui wrote:
>> From: WANG Xuerui <git@xen0n.name>
>>
>> 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.
> IMO in pass 3 we can also be more aggressive estimating the distance r -
> l. I.e. now we have code snippets like:
>
> /* If pc and symbol not in the same segment, add/sub segment alignment. */
> if (!loongarch_two_sections_in_same_segment (info->output_bfd,
> sec->output_section,
> sym_sec->output_section))
> max_alignment = info->maxpagesize > max_alignment ? info->maxpagesize
> : max_alignment;
>
> if (symval > pc)
> pc -= (max_alignment > 4 ? max_alignment : 0);
> else if (symval < pc)
> pc += (max_alignment > 4 ? max_alignment : 0);
>
> This is because if we delete some byte before l, the distance between l
> and r may increase (as r may be unmoved due to some alignment
> requirement). But it shouldn't happen anymore in pass 3.
Ah I see, seems a good idea! I'll fix the test case and several comments
and send v2.
More information about the Binutils
mailing list