This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

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;
  	    }
  


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]