aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/pa/pa.md
diff options
context:
space:
mode:
authorWilco Dijkstra <wdijkstr@arm.com>2019-06-19 12:52:43 +0000
committerWilco Dijkstra <wilco@gcc.gnu.org>2019-06-19 12:52:43 +0000
commit25403c416e5f12d681d1fc45a8789d19ab40297f (patch)
tree6474f549d25800480316cfea891569617209bd25 /gcc/config/pa/pa.md
parent2e83f583c27ef7a9d3b0fb0b5ed372439d6222a8 (diff)
downloadgcc-25403c416e5f12d681d1fc45a8789d19ab40297f.zip
gcc-25403c416e5f12d681d1fc45a8789d19ab40297f.tar.gz
gcc-25403c416e5f12d681d1fc45a8789d19ab40297f.tar.bz2
Simplify setjmp and non-local goto implementation (PR84521)
This fixes and simplifies the setjmp and non-local goto implementation. Currently the virtual frame pointer is saved when using __builtin_setjmp or a non-local goto. Depending on whether a frame pointer is used, this may either save SP or FP with an immediate offset. However the goto or longjmp always updates the hard frame pointer. A receiver veneer in the original function then assigns the hard frame pointer to the virtual frame pointer, which should, if it works correctly, again assign SP or FP. However the special elimination code in eliminate_regs_in_insn doesn't do this correctly unless the frame pointer is used, and even if it worked by writing SP, the frame pointer would still be corrupted. A much simpler implementation is to always save and restore the hard frame pointer. This avoids 2 redundant instructions which add/subtract the virtual frame offset. A large amount of code can be removed as a result, including all implementations of TARGET_BUILTIN_SETJMP_FRAME_VALUE (all of which already use the hard frame pointer). The expansion of nonlocal_goto on PA can be simplied to just restore the hard frame pointer. This fixes the most obvious issues, however there are still issues on targets which define HARD_FRAME_POINTER_IS_FRAME_POINTER (arm, mips). Each function could have a different hard frame pointer, so a non-local goto may restore the wrong frame pointer (TARGET_BUILTIN_SETJMP_FRAME_VALUE could be useful for this). The i386 TARGET_BUILTIN_SETJMP_FRAME_VALUE was incorrect: if stack_realign_fp is true, it would save the hard frame pointer value but restore the virtual frame pointer which according to ix86_initial_elimination_offset can have a non-zero offset from the hard frame pointer. The ia64 implementation of nonlocal_goto seems incorrect since the helper function moves the the frame pointer value into the static chain register (so this patch does nothing to make it better or worse). AArch64 + x86-64 bootstrap OK, new test passes on AArch64, x86-64 and Arm. gcc/ PR middle-end/84521 * builtins.c (expand_builtin_setjmp_setup): Save hard_frame_pointer_rtx. (expand_builtin_setjmp_receiver): Do not emit sfp = fp move since we restore fp. * function.c (expand_function_start): Save hard_frame_pointer_rtx for non-local goto. * lra-eliminations.c (eliminate_regs_in_insn): Remove sfp = fp elimination code. (remove_reg_equal_offset_note): Remove unused function. * reload1.c (eliminate_regs_in_insn): Remove sfp = hfp elimination code. * config/arc/arc.c (TARGET_BUILTIN_SETJMP_FRAME_VALUE): Remove. (arc_builtin_setjmp_frame_value): Remove function. * config/avr/avr.c (TARGET_BUILTIN_SETJMP_FRAME_VALUE): Remove. (avr_builtin_setjmp_frame_value): Remove function. * config/i386/i386.c (TARGET_BUILTIN_SETJMP_FRAME_VALUE): Remove. (ix86_builtin_setjmp_frame_value): Remove function. * config/pa/pa.md (nonlocal_goto): Remove FP adjustment. * config/sparc/sparc.c (TARGET_BUILTIN_SETJMP_FRAME_VALUE): Remove. (sparc_builtin_setjmp_frame_value): Remove function. * config/vax/vax.c (TARGET_BUILTIN_SETJMP_FRAME_VALUE): Remove. (vax_builtin_setjmp_frame_value): Remove function. * config/xtensa/xtensa.c (xtensa_frame_pointer_required): Force frame pointer if has_nonlocal_label. testsuite/ PR middle-end/84521 * gcc.c-torture/execute/pr84521.c: New test. From-SVN: r272473
Diffstat (limited to 'gcc/config/pa/pa.md')
-rw-r--r--gcc/config/pa/pa.md7
1 files changed, 2 insertions, 5 deletions
diff --git a/gcc/config/pa/pa.md b/gcc/config/pa/pa.md
index 84630ad..a568e79 100644
--- a/gcc/config/pa/pa.md
+++ b/gcc/config/pa/pa.md
@@ -6909,10 +6909,7 @@
lab = copy_to_reg (lab);
- /* Restore the stack and frame pointers. The virtual_stack_vars_rtx
- is saved instead of the hard_frame_pointer_rtx in the save area.
- As a result, an extra instruction is needed to adjust for the offset
- of the virtual stack variables and the hard frame pointer. */
+ /* Restore the stack and frame pointers. */
fp = copy_to_reg (fp);
emit_stack_restore (SAVE_NONLOCAL, stack);
@@ -6920,7 +6917,7 @@
emit_insn (gen_blockage ());
emit_clobber (hard_frame_pointer_rtx);
emit_clobber (frame_pointer_rtx);
- emit_move_insn (hard_frame_pointer_rtx, plus_constant (Pmode, fp, -8));
+ emit_move_insn (hard_frame_pointer_rtx, fp);
emit_use (hard_frame_pointer_rtx);
emit_use (stack_pointer_rtx);