mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-01-26 05:24:03 +08:00
explow.c (allocate_dynamic_stack_space SETJMP_VIA_SAVE_AREA): Kill setjmpless_size.
* explow.c (allocate_dynamic_stack_space SETJMP_VIA_SAVE_AREA): Kill setjmpless_size. current_function_calls_setjmp is completely computed when we are called, so just use the optimized size value instead of using REG_SAVE_AREA notes. (optimize_save_area_alloca): Delete.... * rtl.h (optimize_save_area_alloca): Likewise... * passes.c (rest_of_compilation): and don't call it any more. * reg-notes.def (SAVE_AREA): Delete. From-SVN: r98861
This commit is contained in:
parent
25b9575bc2
commit
d0828b3113
@ -1,3 +1,14 @@
|
||||
2005-04-27 David S. Miller <davem@davemloft.net>
|
||||
|
||||
* explow.c (allocate_dynamic_stack_space SETJMP_VIA_SAVE_AREA):
|
||||
Kill setjmpless_size. current_function_calls_setjmp is completely
|
||||
computed when we are called, so just use the optimized size value
|
||||
instead of using REG_SAVE_AREA notes.
|
||||
(optimize_save_area_alloca): Delete....
|
||||
* rtl.h (optimize_save_area_alloca): Likewise...
|
||||
* passes.c (rest_of_compilation): and don't call it any more.
|
||||
* reg-notes.def (SAVE_AREA): Delete.
|
||||
|
||||
2005-04-27 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
* config/fp-bit.c (abort): Add noreturn attribute.
|
||||
|
167
gcc/explow.c
167
gcc/explow.c
@ -1017,83 +1017,6 @@ update_nonlocal_goto_save_area (void)
|
||||
emit_stack_save (SAVE_NONLOCAL, &r_save, NULL_RTX);
|
||||
}
|
||||
|
||||
#ifdef SETJMP_VIA_SAVE_AREA
|
||||
/* Optimize RTL generated by allocate_dynamic_stack_space for targets
|
||||
where SETJMP_VIA_SAVE_AREA is true. The problem is that on these
|
||||
platforms, the dynamic stack space used can corrupt the original
|
||||
frame, thus causing a crash if a longjmp unwinds to it. */
|
||||
|
||||
void
|
||||
optimize_save_area_alloca (void)
|
||||
{
|
||||
rtx insn;
|
||||
|
||||
for (insn = get_insns (); insn; insn = NEXT_INSN(insn))
|
||||
{
|
||||
rtx note;
|
||||
|
||||
if (!NONJUMP_INSN_P (insn))
|
||||
continue;
|
||||
|
||||
for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
|
||||
{
|
||||
if (REG_NOTE_KIND (note) != REG_SAVE_AREA)
|
||||
continue;
|
||||
|
||||
if (!current_function_calls_setjmp)
|
||||
{
|
||||
rtx pat = PATTERN (insn);
|
||||
|
||||
/* If we do not see the note in a pattern matching
|
||||
these precise characteristics, we did something
|
||||
entirely wrong in allocate_dynamic_stack_space.
|
||||
|
||||
Note, one way this could happen is if SETJMP_VIA_SAVE_AREA
|
||||
was defined on a machine where stacks grow towards higher
|
||||
addresses.
|
||||
|
||||
Right now only supported port with stack that grow upward
|
||||
is the HPPA and it does not define SETJMP_VIA_SAVE_AREA. */
|
||||
gcc_assert (GET_CODE (pat) == SET
|
||||
&& SET_DEST (pat) == stack_pointer_rtx
|
||||
&& GET_CODE (SET_SRC (pat)) == MINUS
|
||||
&& XEXP (SET_SRC (pat), 0) == stack_pointer_rtx);
|
||||
|
||||
/* This will now be transformed into a (set REG REG)
|
||||
so we can just blow away all the other notes. */
|
||||
XEXP (SET_SRC (pat), 1) = XEXP (note, 0);
|
||||
REG_NOTES (insn) = NULL_RTX;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* setjmp was called, we must remove the REG_SAVE_AREA
|
||||
note so that later passes do not get confused by its
|
||||
presence. */
|
||||
if (note == REG_NOTES (insn))
|
||||
{
|
||||
REG_NOTES (insn) = XEXP (note, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
rtx srch;
|
||||
|
||||
for (srch = REG_NOTES (insn); srch; srch = XEXP (srch, 1))
|
||||
if (XEXP (srch, 1) == note)
|
||||
break;
|
||||
|
||||
gcc_assert (srch);
|
||||
|
||||
XEXP (srch, 1) = XEXP (note, 1);
|
||||
}
|
||||
}
|
||||
/* Once we've seen the note of interest, we need not look at
|
||||
the rest of them. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* SETJMP_VIA_SAVE_AREA */
|
||||
|
||||
/* Return an rtx representing the address of an area of memory dynamically
|
||||
pushed on the stack. This region of memory is always aligned to
|
||||
a multiple of BIGGEST_ALIGNMENT.
|
||||
@ -1108,10 +1031,6 @@ optimize_save_area_alloca (void)
|
||||
rtx
|
||||
allocate_dynamic_stack_space (rtx size, rtx target, int known_align)
|
||||
{
|
||||
#ifdef SETJMP_VIA_SAVE_AREA
|
||||
rtx setjmpless_size = NULL_RTX;
|
||||
#endif
|
||||
|
||||
/* If we're asking for zero bytes, it doesn't matter what we point
|
||||
to since we can't dereference it. But return a reasonable
|
||||
address anyway. */
|
||||
@ -1160,51 +1079,47 @@ allocate_dynamic_stack_space (rtx size, rtx target, int known_align)
|
||||
avoid clobbering the reg save area. Note that the offset of
|
||||
virtual_incoming_args_rtx includes the preallocated stack args space.
|
||||
It would be no problem to clobber that, but it's on the wrong side
|
||||
of the old save area. */
|
||||
{
|
||||
rtx dynamic_offset
|
||||
= expand_binop (Pmode, sub_optab, virtual_stack_dynamic_rtx,
|
||||
stack_pointer_rtx, NULL_RTX, 1, OPTAB_LIB_WIDEN);
|
||||
of the old save area.
|
||||
|
||||
if (!current_function_calls_setjmp)
|
||||
{
|
||||
int align = PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT;
|
||||
What used to happen is that, since we did not know for sure
|
||||
whether setjmp() was invoked until after RTL generation, we
|
||||
would use reg notes to store the "optimized" size and fix things
|
||||
up later. These days we know this information before we ever
|
||||
start building RTL so the reg notes are unnecessary. */
|
||||
if (!current_function_calls_setjmp)
|
||||
{
|
||||
int align = PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT;
|
||||
|
||||
/* See optimize_save_area_alloca to understand what is being
|
||||
set up here. */
|
||||
/* ??? Code below assumes that the save area needs maximal
|
||||
alignment. This constraint may be too strong. */
|
||||
gcc_assert (PREFERRED_STACK_BOUNDARY == BIGGEST_ALIGNMENT);
|
||||
|
||||
/* ??? Code below assumes that the save area needs maximal
|
||||
alignment. This constraint may be too strong. */
|
||||
gcc_assert (PREFERRED_STACK_BOUNDARY == BIGGEST_ALIGNMENT);
|
||||
if (GET_CODE (size) == CONST_INT)
|
||||
{
|
||||
HOST_WIDE_INT new = INTVAL (size) / align * align;
|
||||
|
||||
if (GET_CODE (size) == CONST_INT)
|
||||
{
|
||||
HOST_WIDE_INT new = INTVAL (size) / align * align;
|
||||
if (INTVAL (size) != new)
|
||||
size = GEN_INT (new);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Since we know overflow is not possible, we avoid using
|
||||
CEIL_DIV_EXPR and use TRUNC_DIV_EXPR instead. */
|
||||
size = expand_divmod (0, TRUNC_DIV_EXPR, Pmode, size,
|
||||
GEN_INT (align), NULL_RTX, 1);
|
||||
size = expand_mult (Pmode, size,
|
||||
GEN_INT (align), NULL_RTX, 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rtx dynamic_offset
|
||||
= expand_binop (Pmode, sub_optab, virtual_stack_dynamic_rtx,
|
||||
stack_pointer_rtx, NULL_RTX, 1, OPTAB_LIB_WIDEN);
|
||||
|
||||
if (INTVAL (size) != new)
|
||||
setjmpless_size = GEN_INT (new);
|
||||
else
|
||||
setjmpless_size = size;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Since we know overflow is not possible, we avoid using
|
||||
CEIL_DIV_EXPR and use TRUNC_DIV_EXPR instead. */
|
||||
setjmpless_size = expand_divmod (0, TRUNC_DIV_EXPR, Pmode, size,
|
||||
GEN_INT (align), NULL_RTX, 1);
|
||||
setjmpless_size = expand_mult (Pmode, setjmpless_size,
|
||||
GEN_INT (align), NULL_RTX, 1);
|
||||
}
|
||||
/* Our optimization works based upon being able to perform a simple
|
||||
transformation of this RTL into a (set REG REG) so make sure things
|
||||
did in fact end up in a REG. */
|
||||
if (!register_operand (setjmpless_size, Pmode))
|
||||
setjmpless_size = force_reg (Pmode, setjmpless_size);
|
||||
}
|
||||
|
||||
size = expand_binop (Pmode, add_optab, size, dynamic_offset,
|
||||
NULL_RTX, 1, OPTAB_LIB_WIDEN);
|
||||
}
|
||||
size = expand_binop (Pmode, add_optab, size, dynamic_offset,
|
||||
NULL_RTX, 1, OPTAB_LIB_WIDEN);
|
||||
}
|
||||
#endif /* SETJMP_VIA_SAVE_AREA */
|
||||
|
||||
/* Round the size to a multiple of the required stack alignment.
|
||||
@ -1304,16 +1219,6 @@ allocate_dynamic_stack_space (rtx size, rtx target, int known_align)
|
||||
}
|
||||
|
||||
anti_adjust_stack (size);
|
||||
#ifdef SETJMP_VIA_SAVE_AREA
|
||||
if (setjmpless_size != NULL_RTX)
|
||||
{
|
||||
rtx note_target = get_last_insn ();
|
||||
|
||||
REG_NOTES (note_target)
|
||||
= gen_rtx_EXPR_LIST (REG_SAVE_AREA, setjmpless_size,
|
||||
REG_NOTES (note_target));
|
||||
}
|
||||
#endif /* SETJMP_VIA_SAVE_AREA */
|
||||
|
||||
#ifdef STACK_GROWS_DOWNWARD
|
||||
emit_move_insn (target, virtual_stack_dynamic_rtx);
|
||||
|
@ -1558,15 +1558,6 @@ rest_of_compilation (void)
|
||||
/* Copy any shared structure that should not be shared. */
|
||||
unshare_all_rtl ();
|
||||
|
||||
#ifdef SETJMP_VIA_SAVE_AREA
|
||||
/* This must be performed before virtual register instantiation.
|
||||
Please be aware that everything in the compiler that can look
|
||||
at the RTL up to this point must understand that REG_SAVE_AREA
|
||||
is just like a use of the REG contained inside. */
|
||||
if (current_function_calls_alloca)
|
||||
optimize_save_area_alloca ();
|
||||
#endif
|
||||
|
||||
/* Instantiate all virtual registers. */
|
||||
instantiate_virtual_regs ();
|
||||
|
||||
|
@ -117,10 +117,6 @@ REG_NOTE (VALUE_PROFILE)
|
||||
that the pointer returned cannot alias anything else. */
|
||||
REG_NOTE (NOALIAS)
|
||||
|
||||
/* Used to optimize rtl generated by dynamic stack allocations for
|
||||
targets where SETJMP_VIA_SAVE_AREA is true. */
|
||||
REG_NOTE (SAVE_AREA)
|
||||
|
||||
/* REG_BR_PRED is attached to JUMP_INSNs and CALL_INSNSs. It contains
|
||||
CONCAT of two integer value. First specifies the branch predictor
|
||||
that added the note, second specifies the predicted hitrate of
|
||||
|
@ -1320,7 +1320,6 @@ extern rtx expand_builtin_expect_jump (tree, rtx, rtx);
|
||||
extern void set_stack_check_libfunc (rtx);
|
||||
extern HOST_WIDE_INT trunc_int_for_mode (HOST_WIDE_INT, enum machine_mode);
|
||||
extern rtx plus_constant (rtx, HOST_WIDE_INT);
|
||||
extern void optimize_save_area_alloca (void);
|
||||
|
||||
/* In emit-rtl.c */
|
||||
extern rtvec gen_rtvec (int, ...);
|
||||
|
Loading…
Reference in New Issue
Block a user