From: Richard Sandiford Date: Fri, 9 May 2014 10:16:14 +0000 (+0000) Subject: builtins.c (expand_builtin_setjmp_receiver): Emit a use of the hard frame pointer. X-Git-Tag: releases/gcc-4.8.3~75 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2ea73289ae7897c3f22a027f2d32351b942986ab;p=thirdparty%2Fgcc.git builtins.c (expand_builtin_setjmp_receiver): Emit a use of the hard frame pointer. gcc/ * builtins.c (expand_builtin_setjmp_receiver): Emit a use of the hard frame pointer. Synchronize commentary with mainline. * cse.c (cse_insn): Only check for volatile asms. * cselib.c (cselib_process_insn): Likewise. * dse.c (scan_insn): Likewise. * stmt.c (expand_nl_goto_receiver): Emit a use and a clobber of the hard frame pointer. From-SVN: r210266 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1de14a0691c7..c2960259e3b6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2014-05-09 Richard Sandiford + + * builtins.c (expand_builtin_setjmp_receiver): Emit a use of + the hard frame pointer. Synchronize commentary with mainline. + * cse.c (cse_insn): Only check for volatile asms. + * cselib.c (cselib_process_insn): Likewise. + * dse.c (scan_insn): Likewise. + * stmt.c (expand_nl_goto_receiver): Emit a use and a clobber of + the hard frame pointer. + 2014-05-08 Manuel López-Ibáñez Matthias Klose diff --git a/gcc/builtins.c b/gcc/builtins.c index 8851142a80c1..bb6c664394bc 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -905,9 +905,24 @@ expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED) if (! HAVE_nonlocal_goto) #endif { + /* First adjust our frame pointer to its actual value. It was + previously set to the start of the virtual area corresponding to + the stacked variables when we branched here and now needs to be + adjusted to the actual hardware fp value. + + Assignments to virtual registers are converted by + instantiate_virtual_regs into the corresponding assignment + to the underlying register (fp in this case) that makes + the original assignment true. + So the following insn will actually be decrementing fp by + STARTING_FRAME_OFFSET. */ emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx); - /* This might change the hard frame pointer in ways that aren't - apparent to early optimization passes, so force a clobber. */ + + /* Restoring the frame pointer also modifies the hard frame pointer. + Mark it used (so that the previous assignment remains live once + the frame pointer is eliminated) and clobbered (to represent the + implicit update from the assignment). */ + emit_use (hard_frame_pointer_rtx); emit_clobber (hard_frame_pointer_rtx); } @@ -948,8 +963,7 @@ expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED) /* We must not allow the code we just generated to be reordered by scheduling. Specifically, the update of the frame pointer must - happen immediately, not later. Similarly, we must block - (frame-related) register values to be used across this code. */ + happen immediately, not later. */ emit_insn (gen_blockage ()); } diff --git a/gcc/cse.c b/gcc/cse.c index 40105a9b1999..eb17f6979f9c 100644 --- a/gcc/cse.c +++ b/gcc/cse.c @@ -5659,9 +5659,10 @@ cse_insn (rtx insn) invalidate (XEXP (dest, 0), GET_MODE (dest)); } - /* A volatile ASM or an UNSPEC_VOLATILE invalidates everything. */ + /* A volatile ASM invalidates everything. */ if (NONJUMP_INSN_P (insn) - && volatile_insn_p (PATTERN (insn))) + && GET_CODE (PATTERN (insn)) == ASM_OPERANDS + && MEM_VOLATILE_P (PATTERN (insn))) flush_hash_table (); /* Don't cse over a call to setjmp; on some machines (eg VAX) diff --git a/gcc/cselib.c b/gcc/cselib.c index 334d9552abf7..1e59f3a1b42b 100644 --- a/gcc/cselib.c +++ b/gcc/cselib.c @@ -2623,12 +2623,13 @@ cselib_process_insn (rtx insn) cselib_current_insn = insn; - /* Forget everything at a CODE_LABEL, a volatile insn, or a setjmp. */ + /* Forget everything at a CODE_LABEL, a volatile asm, or a setjmp. */ if ((LABEL_P (insn) || (CALL_P (insn) && find_reg_note (insn, REG_SETJMP, NULL)) || (NONJUMP_INSN_P (insn) - && volatile_insn_p (PATTERN (insn)))) + && GET_CODE (PATTERN (insn)) == ASM_OPERANDS + && MEM_VOLATILE_P (PATTERN (insn)))) && !cselib_preserve_constants) { cselib_reset_table (next_uid); diff --git a/gcc/dse.c b/gcc/dse.c index 080822292e40..e853b411848f 100644 --- a/gcc/dse.c +++ b/gcc/dse.c @@ -2518,7 +2518,8 @@ scan_insn (bb_info_t bb_info, rtx insn) /* Cselib clears the table for this case, so we have to essentially do the same. */ if (NONJUMP_INSN_P (insn) - && volatile_insn_p (PATTERN (insn))) + && GET_CODE (PATTERN (insn)) == ASM_OPERANDS + && MEM_VOLATILE_P (PATTERN (insn))) { add_wild_read (bb_info); insn_info->cannot_delete = true; diff --git a/gcc/stmt.c b/gcc/stmt.c index 7bdc9329bdf0..da9a335b1c70 100644 --- a/gcc/stmt.c +++ b/gcc/stmt.c @@ -1602,18 +1602,27 @@ expand_nl_goto_receiver (void) #ifdef HAVE_nonlocal_goto if (! HAVE_nonlocal_goto) #endif - /* First adjust our frame pointer to its actual value. It was - previously set to the start of the virtual area corresponding to - the stacked variables when we branched here and now needs to be - adjusted to the actual hardware fp value. - - Assignments are to virtual registers are converted by - instantiate_virtual_regs into the corresponding assignment - to the underlying register (fp in this case) that makes - the original assignment true. - So the following insn will actually be - decrementing fp by STARTING_FRAME_OFFSET. */ - emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx); + { + /* First adjust our frame pointer to its actual value. It was + previously set to the start of the virtual area corresponding to + the stacked variables when we branched here and now needs to be + adjusted to the actual hardware fp value. + + Assignments to virtual registers are converted by + instantiate_virtual_regs into the corresponding assignment + to the underlying register (fp in this case) that makes + the original assignment true. + So the following insn will actually be decrementing fp by + STARTING_FRAME_OFFSET. */ + emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx); + + /* Restoring the frame pointer also modifies the hard frame pointer. + Mark it used (so that the previous assignment remains live once + the frame pointer is eliminated) and clobbered (to represent the + implicit update from the assignment). */ + emit_use (hard_frame_pointer_rtx); + emit_clobber (hard_frame_pointer_rtx); + } #if !HARD_FRAME_POINTER_IS_ARG_POINTER if (fixed_regs[ARG_POINTER_REGNUM])