+2014-05-09 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * 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 <manu@gcc.gnu.org>
Matthias Klose <doko@ubuntu.com>
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);
}
/* 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 ());
}
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)
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);
/* 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;
#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])