mirror of
git://gcc.gnu.org/git/gcc.git
synced 2024-12-24 05:58:56 +08:00
regmove.c (try_apply_stack_adjustment): Remove now redundant sanity checks.
* regmove.c (try_apply_stack_adjustment): Remove now redundant sanity checks. (combine_stack_adjustments_for_block): Don't combine stack allocation followed by deallocations. Handle grow-up stacks. Co-Authored-By: Richard Henderson <rth@redhat.com> From-SVN: r41707
This commit is contained in:
parent
dad362764f
commit
595c229027
@ -1,3 +1,11 @@
|
||||
2001-04-30 Jan Hubicka <jh@suse.cz>
|
||||
Richard Henderson <rth@redhat.com>
|
||||
|
||||
* regmove.c (try_apply_stack_adjustment): Remove now redundant
|
||||
sanity checks.
|
||||
(combine_stack_adjustments_for_block): Don't combine stack
|
||||
allocation followed by deallocations. Handle grow-up stacks.
|
||||
|
||||
2001-04-30 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
* fdl.texi: New file.
|
||||
|
@ -42,6 +42,15 @@ Boston, MA 02111-1307, USA. */
|
||||
#include "toplev.h"
|
||||
#include "reload.h"
|
||||
|
||||
|
||||
/* Turn STACK_GROWS_DOWNWARD into a boolean. */
|
||||
#ifdef STACK_GROWS_DOWNWARD
|
||||
#undef STACK_GROWS_DOWNWARD
|
||||
#define STACK_GROWS_DOWNWARD 1
|
||||
#else
|
||||
#define STACK_GROWS_DOWNWARD 0
|
||||
#endif
|
||||
|
||||
static int perhaps_ends_bb_p PARAMS ((rtx));
|
||||
static int optimize_reg_copy_1 PARAMS ((rtx, rtx, rtx));
|
||||
static void optimize_reg_copy_2 PARAMS ((rtx, rtx, rtx));
|
||||
@ -2231,14 +2240,6 @@ try_apply_stack_adjustment (insn, memlist, new_adjust, delta)
|
||||
struct csa_memlist *ml;
|
||||
rtx set;
|
||||
|
||||
/* We know INSN matches single_set_for_csa, because that's what we
|
||||
recognized earlier. However, if INSN is not single_set, it is
|
||||
doing double duty as a barrier for frame pointer memory accesses,
|
||||
which we are not recording. Therefore, an adjust insn that is not
|
||||
single_set may not have a positive delta applied. */
|
||||
|
||||
if (delta > 0 && ! single_set (insn))
|
||||
return 0;
|
||||
set = single_set_for_csa (insn);
|
||||
validate_change (insn, &XEXP (SET_SRC (set), 1), GEN_INT (new_adjust), 1);
|
||||
|
||||
@ -2248,13 +2249,6 @@ try_apply_stack_adjustment (insn, memlist, new_adjust, delta)
|
||||
rtx new = gen_rtx_MEM (GET_MODE (*ml->mem),
|
||||
plus_constant (stack_pointer_rtx, c));
|
||||
|
||||
/* Don't reference memory below the stack pointer. */
|
||||
if (c < 0)
|
||||
{
|
||||
cancel_changes (0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
MEM_COPY_ATTRIBUTES (new, *ml->mem);
|
||||
validate_change (ml->insn, ml->mem, new, 1);
|
||||
}
|
||||
@ -2369,11 +2363,59 @@ combine_stack_adjustments_for_block (bb)
|
||||
|
||||
/* If not all recorded memrefs can be adjusted, or the
|
||||
adjustment is now too large for a constant addition,
|
||||
we cannot merge the two stack adjustments. */
|
||||
if (! try_apply_stack_adjustment (last_sp_set, memlist,
|
||||
we cannot merge the two stack adjustments.
|
||||
|
||||
Also we need to be carefull to not move stack pointer
|
||||
such that we create stack accesses outside the allocated
|
||||
area. We can combine an allocation into the first insn,
|
||||
or a deallocation into the second insn. We can not
|
||||
combine an allocation followed by a deallocation.
|
||||
|
||||
The only somewhat frequent ocurrence of the later is when
|
||||
a function allocates a stack frame but does not use it.
|
||||
For this case, we would need to analyze rtl stream to be
|
||||
sure that allocated area is really unused. This means not
|
||||
only checking the memory references, but also all registers
|
||||
or global memory references possibly containing a stack
|
||||
frame address.
|
||||
|
||||
Perhaps the best way to address this problem is to teach
|
||||
gcc not to allocate stack for objects never used. */
|
||||
|
||||
/* Combine an allocation into the first instruction. */
|
||||
if (STACK_GROWS_DOWNWARD ? this_adjust <= 0 : this_adjust >= 0)
|
||||
{
|
||||
if (try_apply_stack_adjustment (last_sp_set, memlist,
|
||||
last_sp_adjust + this_adjust,
|
||||
this_adjust))
|
||||
{
|
||||
/* It worked! */
|
||||
pending_delete = insn;
|
||||
last_sp_adjust += this_adjust;
|
||||
goto processed;
|
||||
}
|
||||
}
|
||||
|
||||
/* Otherwise we have a deallocation. Do not combine with
|
||||
a previous allocation. Combine into the second insn. */
|
||||
else if (STACK_GROWS_DOWNWARD
|
||||
? last_sp_adjust >= 0 : last_sp_adjust <= 0)
|
||||
{
|
||||
if (try_apply_stack_adjustment (insn, memlist,
|
||||
last_sp_adjust + this_adjust,
|
||||
-last_sp_adjust))
|
||||
{
|
||||
/* It worked! */
|
||||
flow_delete_insn (last_sp_set);
|
||||
last_sp_set = insn;
|
||||
last_sp_adjust += this_adjust;
|
||||
free_csa_memlist (memlist);
|
||||
memlist = NULL;
|
||||
goto processed;
|
||||
}
|
||||
}
|
||||
|
||||
/* Combination failed. Restart processing from here. */
|
||||
free_csa_memlist (memlist);
|
||||
memlist = NULL;
|
||||
last_sp_set = insn;
|
||||
@ -2381,26 +2423,6 @@ combine_stack_adjustments_for_block (bb)
|
||||
goto processed;
|
||||
}
|
||||
|
||||
/* It worked! */
|
||||
pending_delete = insn;
|
||||
last_sp_adjust += this_adjust;
|
||||
|
||||
/* If, by some accident, the adjustments cancel out,
|
||||
delete both insns and start from scratch. */
|
||||
if (last_sp_adjust == 0)
|
||||
{
|
||||
if (last_sp_set == bb->head)
|
||||
bb->head = NEXT_INSN (last_sp_set);
|
||||
flow_delete_insn (last_sp_set);
|
||||
|
||||
free_csa_memlist (memlist);
|
||||
memlist = NULL;
|
||||
last_sp_set = NULL_RTX;
|
||||
}
|
||||
|
||||
goto processed;
|
||||
}
|
||||
|
||||
/* Find a predecrement of exactly the previous adjustment and
|
||||
turn it into a direct store. Obviously we can't do this if
|
||||
there were any intervening uses of the stack pointer. */
|
||||
|
Loading…
Reference in New Issue
Block a user