aboutsummaryrefslogtreecommitdiff
path: root/gcc/config.gcc
diff options
context:
space:
mode:
authorAndrew Burgess <andrew.burgess@embecosm.com>2019-10-28 16:26:19 +0000
committerAndrew Burgess <aburgess@gcc.gnu.org>2019-10-28 16:26:19 +0000
commite18a6d1441cfb5d43d3193a2643207fc3f95fd5a (patch)
tree317e4993f74123551321eccf1c21bdb9b15ab169 /gcc/config.gcc
parent4b0ab0d9588f6c63f7102e70de52684cdda49de8 (diff)
downloadgcc-e18a6d1441cfb5d43d3193a2643207fc3f95fd5a.zip
gcc-e18a6d1441cfb5d43d3193a2643207fc3f95fd5a.tar.gz
gcc-e18a6d1441cfb5d43d3193a2643207fc3f95fd5a.tar.bz2
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
Diffstat (limited to 'gcc/config.gcc')
-rw-r--r--gcc/config.gcc2
1 files changed, 1 insertions, 1 deletions
diff --git a/gcc/config.gcc b/gcc/config.gcc
index bdc2253..b444087 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -523,7 +523,7 @@ pru-*-*)
;;
riscv*)
cpu_type=riscv
- extra_objs="riscv-builtins.o riscv-c.o"
+ extra_objs="riscv-builtins.o riscv-c.o riscv-sr.o"
d_target_objs="riscv-d.o"
;;
rs6000*-*-*)