[PATCH] LoongArch: Add new relocation R_LARCH_CALL36
WANG Xuerui
i.swmail@xen0n.name
Fri Nov 17 04:44:15 GMT 2023
On 11/17/23 09:40, mengqinggang wrote:
> We will add call36 and tail36 pseudo instructions in gas:
> call36 f -> pcaddu18i $ra, %call36(f) + jirl $ra, $ra, 0
> tail36 f -> pcaddu18i $t0, %call36(f) + jirl $zero, $t0, 0
>
>
> 在 2023/11/8 下午7:04, Xi Ruoyao 写道:
>> On Wed, 2023-11-08 at 01:34 +0800, WANG Xuerui wrote:
>>> On 11/7/23 20:16, Xi Ruoyao wrote:
>>>> I'd like to have some pseudo instructions:
>>>>
>>>> - call36 r0, t0, func -> pcaddu18i t0, func + jirl r0, t0, func
>>>> - call36 t0, func -> pcaddu18i t0, func + jirl t0, t0, func
>>>> - call36 func -> pcaddu18i ra, func + jirl ra, ra, func
>>>>
>>>> These will make the work of the compiler (or assembly programmer)
>>>> easier. Anyway with R_LARCH_CALL36 the pcaddu18i instruction and the
>>>> jirl instruction must be adjacent, so there is no benefit for the
>>>> compiler or programmer to use them separately to make a function call.
>>>>
>>>> And the last one can be annotated with R_LARCH_RELAX so we may
>>>> relax it
>>>> into a bl instruction if possible.
>>> The suggestion sounds reasonable! Although IMO a name like "call.36"
>>> might look better, the name "call36" also works for me.
>>>
>>> And regarding the proposed "call36 func" reusing the $ra for the
>>> temporary -- IIUC this will break the subroutine return prediction. I
>>> think we've been hit by similar regalloc in GCC and have since fixed
>>> that: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=11013.
>> The URL is wrong, PR 11013 is 20-years old.
>>
>>> So maybe it's necessary to specify a different temp register after
>>> all...
>> I think for a normal call (call36 $ra, $ra, func or just call36 $ra) it
>> should be OK, but for a sibcall (call36 $zero, $ra, func) it will
>> confuse the return predictor and we better use another temp register.
Hmm I found out the correct bug number (it was a copy-paste mistake):
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110136
So the main point is: is any jirl in the "jirl <any>, $ra, <any>" form
able to trigger the return stack optimization, or is it just "jirl
$zero, $ra, 0" i.e. "ret"? If the branch predictors in popular LoongArch
models are smart enough to not consider "jirl $ra, $ra, 0" also as a
"ret", then re-using the $ra as scratch space is okay. Otherwise we have
to make the pseudo-insn take another temp register (and optionally
disallow/warn usage of $ra in that place).
BTW, could we have the RISC-V-like bare "call" and "tail" too? It could
be useful for more uniform asm among different code models ("bl" vs
"pcaddu18i + jirl" vs "lu12i + addi + lu32i + lu52i + jirl"), apart from
lowering learning curve for those with some RISC-V asm background. We
could make "call" and "tail" behavior vary based on the code model
chosen, and also provide explicit control via more pseudo-insns like
"{call,tail}26" and "{call,tail}64" apart from "{call,tail}36".
(The above is a suggestion for you to consider; it's not immediately
necessary for the medium code model work at hand, just for symmetry and
enabling users to gain more control over their asm.)
More information about the Binutils
mailing list