This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: PATCH: Fix 20000724-1.c
On Mon, Apr 30, 2001 at 02:13:20PM -0700, Mark Mitchell wrote:
> Will you revert my bogus test-case change if you find the patch, too,
> please? Thank you!
Done.
The following is a slight re-work of
http://gcc.gnu.org/ml/gcc-patches/2000-12/msg00875.html
Of particular note is doing the right thing for !STACK_GROWS_DOWN.
I don't think we have any targets for which this would matter; as
far as I can tell all of our !STACK_GROWS_DOWN targets also set
ACCUMULATE_OUTGOING_ARGS, in which case this code is not run.
Nevertheless, it wanted fixing.
Tested on i686 on 3.0 branch; applied to both branches.
r~
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.
Index: regmove.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/regmove.c,v
retrieving revision 1.96.2.1
diff -c -p -d -r1.96.2.1 regmove.c
*** regmove.c 2001/04/30 15:01:47 1.96.2.1
--- regmove.c 2001/04/30 23:18:22
*************** Boston, MA 02111-1307, USA. */
*** 41,46 ****
--- 41,55 ----
#include "basic-block.h"
#include "toplev.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));
*************** try_apply_stack_adjustment (insn, memlis
*** 2225,2238 ****
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);
--- 2234,2239 ----
*************** try_apply_stack_adjustment (insn, memlis
*** 2242,2254 ****
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);
}
--- 2243,2248 ----
*************** combine_stack_adjustments_for_block (bb)
*** 2363,2397 ****
/* 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,
! last_sp_adjust + this_adjust,
! this_adjust))
! {
! free_csa_memlist (memlist);
! memlist = NULL;
! last_sp_set = insn;
! last_sp_adjust = this_adjust;
! 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;
}
--- 2357,2419 ----
/* 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.
! 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;
+ last_sp_adjust = this_adjust;
goto processed;
}