gcc/riscv: Add a mechanism to remove some calls to _riscv_save_0
When using the -msave-restore flag we end up with calls to
_riscv_save_0 and _riscv_restore_0. These functions adjust the stack
and save or restore the return address. Due to grouping multiple
save/restore stub functions together the save/restore 0 calls actually
save s0, s1, s2, and the return address, but only the return address
actually matters. Leaf functions don't call the save/restore stubs,
so whenever we do see a call to the save/restore stubs, the store of
the return address is required.
If we look in gcc/config/riscv/riscv.c at the function
riscv_expand_prologue and riscv_expand_epilogue we can see that it
would be reasonably easy to adjust these functions to avoid the calls
to the save/restore stubs for those cases where we are about to call
_riscv_save_0 and _riscv_restore_0, however, the actual code size
saving this would give is debatable, with linker relaxation, the calls
to save/restore are often just 4-bytes, and can sometimes even be
2-bytes, while leaving the stack adjust and return address save inline
is always going to be 4-bytes.
The interesting case is when we call _riscv_save_0 and
_riscv_restore_0, and also have a frame that would (without
save/restore) have resulted in a tail call. In this case if we could
remove the save/restore calls, and restore the tail call then we would
get a real size saving.
The problem is that the choice of generating a tail call or not is
done during the gimple expand pass, at which point we don't know how
many registers we need to save (or restore).
The solution presented in this patch offers a partial solution to this
problem. By using the TARGET_MACHINE_DEPENDENT_REORG pass to
implement a very limited pattern matching we identify functions that
call _riscv_save_0 and _riscv_restore_0, and which could be converted
to make use of a tail call. These functions are then converted to the
non save/restore tail call form.
This should result in a code size reduction when compiling with -Os
and with the -msave-restore flag.
gcc/ChangeLog:
* config.gcc: Add riscv-sr.o to extra_objs for riscv.
* config/riscv/riscv-sr.c: New file.
* config/riscv/riscv.c (riscv_reorg): New function.
(TARGET_MACHINE_DEPENDENT_REORG): Define.
* config/riscv/riscv.h (SIBCALL_REG_P): Define.
(riscv_remove_unneeded_save_restore_calls): Declare.
* config/riscv/t-riscv (riscv-sr.o): New build rule.
gcc/testsuite/ChangeLog:
* gcc.target/riscv/save-restore-2.c: New file.
* gcc.target/riscv/save-restore-3.c: New file.
* gcc.target/riscv/save-restore-4.c: New file.
* gcc.target/riscv/save-restore-5.c: New file.
* gcc.target/riscv/save-restore-6.c: New file.
* gcc.target/riscv/save-restore-7.c: New file.
* gcc.target/riscv/save-restore-8.c: New file.
From-SVN: r277527
14 files changed: