[Mips] Restore the return address first in the R3000A epilogue (PS2-184) #8
Loading…
Reference in a new issue
No description provided.
Delete branch "r3000a-load-delay-fill"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
MIPS I has no load interlock, so a load directly before its use needs a nop. The return reads
$ra, and restoring it last put a nop before the jump in nearly every non-leaf function (1,501 of the 6,337 load-delay nops in RiptOPL's IOP code, against 194 for GCC).A new
ra-restore-firstsubtarget feature, implied byr3000aonly, restores$rafirst in the epilogue so the other restores fill its delay. It is implemented as arestoreCalleeSavedRegistersoverride inMipsSEFrameLowering; other CPUs keep the default order unless they ask for the feature. Test:CodeGen/Mips/r3000a-epilogue.ll(first onr3000aand with+ra-restore-first, last onmips1and with-ra-restore-first).Results (-Os, RiptOPL's 313 IOP objects): load-delay nops 6,900 -> 5,907 (GCC 3,761); the 46 IRX files total 755,046 -> 750,950 bytes (GCC 650,850, so +16.0% -> +15.4%). The effect is smaller than the epilogue count suggests because many functions already had another instruction between the restore and the jump.
Tested
Remaining load-delay nops (5,907 against GCC's 3,761) are mostly a load directly followed by its use inside one block; a pass that moves an earlier independent instruction into the slot removed only about 22 nops on the sdk-core modules, so it is not included.
🤖 Generated with Claude Code