mirror of git://gcc.gnu.org/git/gcc.git
re PR middle-end/55030 (gcc.c-torture/execute/builtins/memcpy-chk.c execution, -Os (et al))
PR middle-end/55030 * stmt.c (expand_nl_goto_receiver): Remove almost-copy of expand_builtin_setjmp_receiver. (expand_label): Adjust, call expand_builtin_setjmp_receiver with NULL for the label parameter. * builtins.c (expand_builtin_setjmp_receiver): Don't clobber the frame-pointer. Adjust comments. [HAVE_builtin_setjmp_receiver]: Emit builtin_setjmp_receiver only if LABEL is non-NULL. From-SVN: r200643
This commit is contained in:
parent
cbd7413b3c
commit
e90d156864
|
|
@ -1,3 +1,15 @@
|
||||||
|
2013-07-03 Hans-Peter Nilsson <hp@bitrange.com>
|
||||||
|
|
||||||
|
PR middle-end/55030
|
||||||
|
* stmt.c (expand_nl_goto_receiver): Remove almost-copy of
|
||||||
|
expand_builtin_setjmp_receiver.
|
||||||
|
(expand_label): Adjust, call expand_builtin_setjmp_receiver
|
||||||
|
with NULL for the label parameter.
|
||||||
|
* builtins.c (expand_builtin_setjmp_receiver): Don't clobber
|
||||||
|
the frame-pointer. Adjust comments.
|
||||||
|
[HAVE_builtin_setjmp_receiver]: Emit builtin_setjmp_receiver
|
||||||
|
only if LABEL is non-NULL.
|
||||||
|
|
||||||
2013-07-03 Yufeng Zhang <yufeng.zhang@arm.com>
|
2013-07-03 Yufeng Zhang <yufeng.zhang@arm.com>
|
||||||
|
|
||||||
* config/aarch64/aarch64.h (enum arm_abi_type): Remove.
|
* config/aarch64/aarch64.h (enum arm_abi_type): Remove.
|
||||||
|
|
|
||||||
|
|
@ -886,14 +886,15 @@ expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Construct the trailing part of a __builtin_setjmp call. This is
|
/* Construct the trailing part of a __builtin_setjmp call. This is
|
||||||
also called directly by the SJLJ exception handling code. */
|
also called directly by the SJLJ exception handling code.
|
||||||
|
If RECEIVER_LABEL is NULL, instead contruct a nonlocal goto handler. */
|
||||||
|
|
||||||
void
|
void
|
||||||
expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
|
expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
rtx chain;
|
rtx chain;
|
||||||
|
|
||||||
/* Clobber the FP when we get here, so we have to make sure it's
|
/* Mark the FP as used when we get here, so we have to make sure it's
|
||||||
marked as used by this function. */
|
marked as used by this function. */
|
||||||
emit_use (hard_frame_pointer_rtx);
|
emit_use (hard_frame_pointer_rtx);
|
||||||
|
|
||||||
|
|
@ -908,17 +909,28 @@ expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
|
||||||
#ifdef HAVE_nonlocal_goto
|
#ifdef HAVE_nonlocal_goto
|
||||||
if (! HAVE_nonlocal_goto)
|
if (! HAVE_nonlocal_goto)
|
||||||
#endif
|
#endif
|
||||||
{
|
/* First adjust our frame pointer to its actual value. It was
|
||||||
emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
|
previously set to the start of the virtual area corresponding to
|
||||||
/* This might change the hard frame pointer in ways that aren't
|
the stacked variables when we branched here and now needs to be
|
||||||
apparent to early optimization passes, so force a clobber. */
|
adjusted to the actual hardware fp value.
|
||||||
emit_clobber (hard_frame_pointer_rtx);
|
|
||||||
}
|
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);
|
||||||
|
|
||||||
#if !HARD_FRAME_POINTER_IS_ARG_POINTER
|
#if !HARD_FRAME_POINTER_IS_ARG_POINTER
|
||||||
if (fixed_regs[ARG_POINTER_REGNUM])
|
if (fixed_regs[ARG_POINTER_REGNUM])
|
||||||
{
|
{
|
||||||
#ifdef ELIMINABLE_REGS
|
#ifdef ELIMINABLE_REGS
|
||||||
|
/* If the argument pointer can be eliminated in favor of the
|
||||||
|
frame pointer, we don't need to restore it. We assume here
|
||||||
|
that if such an elimination is present, it can always be used.
|
||||||
|
This is the case on all known machines; if we don't make this
|
||||||
|
assumption, we do unnecessary saving on many machines. */
|
||||||
size_t i;
|
size_t i;
|
||||||
static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
|
static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
|
||||||
|
|
||||||
|
|
@ -939,7 +951,7 @@ expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_builtin_setjmp_receiver
|
#ifdef HAVE_builtin_setjmp_receiver
|
||||||
if (HAVE_builtin_setjmp_receiver)
|
if (receiver_label != NULL && HAVE_builtin_setjmp_receiver)
|
||||||
emit_insn (gen_builtin_setjmp_receiver (receiver_label));
|
emit_insn (gen_builtin_setjmp_receiver (receiver_label));
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
74
gcc/stmt.c
74
gcc/stmt.c
|
|
@ -104,7 +104,6 @@ extern basic_block label_to_block_fn (struct function *, tree);
|
||||||
|
|
||||||
static int n_occurrences (int, const char *);
|
static int n_occurrences (int, const char *);
|
||||||
static bool tree_conflicts_with_clobbers_p (tree, HARD_REG_SET *);
|
static bool tree_conflicts_with_clobbers_p (tree, HARD_REG_SET *);
|
||||||
static void expand_nl_goto_receiver (void);
|
|
||||||
static bool check_operand_nalternatives (tree, tree);
|
static bool check_operand_nalternatives (tree, tree);
|
||||||
static bool check_unique_operand_names (tree, tree, tree);
|
static bool check_unique_operand_names (tree, tree, tree);
|
||||||
static char *resolve_operand_name_1 (char *, tree, tree, tree);
|
static char *resolve_operand_name_1 (char *, tree, tree, tree);
|
||||||
|
|
@ -198,7 +197,7 @@ expand_label (tree label)
|
||||||
|
|
||||||
if (DECL_NONLOCAL (label))
|
if (DECL_NONLOCAL (label))
|
||||||
{
|
{
|
||||||
expand_nl_goto_receiver ();
|
expand_builtin_setjmp_receiver (NULL);
|
||||||
nonlocal_goto_handler_labels
|
nonlocal_goto_handler_labels
|
||||||
= gen_rtx_EXPR_LIST (VOIDmode, label_r,
|
= gen_rtx_EXPR_LIST (VOIDmode, label_r,
|
||||||
nonlocal_goto_handler_labels);
|
nonlocal_goto_handler_labels);
|
||||||
|
|
@ -1554,77 +1553,6 @@ expand_return (tree retval)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Emit code to restore vital registers at the beginning of a nonlocal goto
|
|
||||||
handler. */
|
|
||||||
static void
|
|
||||||
expand_nl_goto_receiver (void)
|
|
||||||
{
|
|
||||||
rtx chain;
|
|
||||||
|
|
||||||
/* Clobber the FP when we get here, so we have to make sure it's
|
|
||||||
marked as used by this function. */
|
|
||||||
emit_use (hard_frame_pointer_rtx);
|
|
||||||
|
|
||||||
/* Mark the static chain as clobbered here so life information
|
|
||||||
doesn't get messed up for it. */
|
|
||||||
chain = targetm.calls.static_chain (current_function_decl, true);
|
|
||||||
if (chain && REG_P (chain))
|
|
||||||
emit_clobber (chain);
|
|
||||||
|
|
||||||
#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);
|
|
||||||
|
|
||||||
#if !HARD_FRAME_POINTER_IS_ARG_POINTER
|
|
||||||
if (fixed_regs[ARG_POINTER_REGNUM])
|
|
||||||
{
|
|
||||||
#ifdef ELIMINABLE_REGS
|
|
||||||
/* If the argument pointer can be eliminated in favor of the
|
|
||||||
frame pointer, we don't need to restore it. We assume here
|
|
||||||
that if such an elimination is present, it can always be used.
|
|
||||||
This is the case on all known machines; if we don't make this
|
|
||||||
assumption, we do unnecessary saving on many machines. */
|
|
||||||
static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
|
|
||||||
if (elim_regs[i].from == ARG_POINTER_REGNUM
|
|
||||||
&& elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (i == ARRAY_SIZE (elim_regs))
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
/* Now restore our arg pointer from the address at which it
|
|
||||||
was saved in our stack frame. */
|
|
||||||
emit_move_insn (crtl->args.internal_arg_pointer,
|
|
||||||
copy_to_reg (get_arg_pointer_save_area ()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_nonlocal_goto_receiver
|
|
||||||
if (HAVE_nonlocal_goto_receiver)
|
|
||||||
emit_insn (gen_nonlocal_goto_receiver ());
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* 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. */
|
|
||||||
emit_insn (gen_blockage ());
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Emit code to save the current value of stack. */
|
/* Emit code to save the current value of stack. */
|
||||||
rtx
|
rtx
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue