combine_stack_adjustments patch

Richard Henderson rth@cygnus.com
Mon Mar 20 14:51:00 GMT 2000


There was a stupid typo in stack_memref_p that caused much of the
optimization it was supposed to do to be ignored.  Fixing that 
exposed a bug elsewhere that would mis-handle insns like

	mov %esp,8(%esp)

that show up in nested function calls.

In private mail, Uli noticed oddities in functions like

	int b(int x, int y) { return e(x, y); }

that would get compiled to

	subl $12,%esp
	addl $12,%esp
	jmp e

This happened because there were dead instructions in between
that were later removed by flow2.  Fixed by running this pass
after flow2 instead.

Bootstrapped on i686-pc-linux-gnu.



r~

	* regmove.c (stack_memref_p): Fix typo, reorg for readability.
	(combine_stack_adjustments_for_block): Don't allow sp references
	in the side of a set we're not fixing up.
	* toplev.c (rest_of_compilation): Run combine_stack_adjustments
	after life_analysis.

Index: regmove.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/regmove.c,v
retrieving revision 1.82
diff -c -p -d -r1.82 regmove.c
*** regmove.c	2000/03/14 14:38:52	1.82
--- regmove.c	2000/03/20 22:42:47
*************** combine_stack_adjustments ()
*** 2116,2129 ****
  /* Recognize a MEM of the form (sp) or (plus sp const).  */
  
  static int
! stack_memref_p (mem)
!      rtx mem;
  {
!   return (GET_CODE (mem) == MEM
! 	  && (XEXP (mem, 0) == stack_pointer_rtx
! 	      || (GET_CODE (XEXP (mem, 0)) == PLUS
! 		  && XEXP (XEXP (mem, 0), 0) == stack_pointer_rtx
! 		  && GET_CODE (XEXP (XEXP (mem, 0), 0)) == CONST_INT)));
  }
  
  /* Recognize either normal single_set or the hack in i386.md for
--- 2116,2136 ----
  /* Recognize a MEM of the form (sp) or (plus sp const).  */
  
  static int
! stack_memref_p (x)
!      rtx x;
  {
!   if (GET_CODE (x) != MEM)
!     return 0;
!   x = XEXP (x, 0);
! 
!   if (x == stack_pointer_rtx)
!     return 1;
!   if (GET_CODE (x) == PLUS
!       && XEXP (x, 0) == stack_pointer_rtx
!       && GET_CODE (XEXP (x, 1)) == CONST_INT)
!     return 1;
! 
!   return 0;
  }
  
  /* Recognize either normal single_set or the hack in i386.md for
*************** combine_stack_adjustments_for_block (bb)
*** 2330,2343 ****
  	    }
  
  	  /* Find loads from stack memory and record them.  */
! 	  if (last_sp_set && stack_memref_p (src))
  	    {
  	      memlist = record_one_stack_memref (insn, src, memlist);
  	      goto processed;
  	    }
  
  	  /* Find stores to stack memory and record them.  */
! 	  if (last_sp_set && stack_memref_p (dest))
  	    {
  	      memlist = record_one_stack_memref (insn, dest, memlist);
  	      goto processed;
--- 2337,2352 ----
  	    }
  
  	  /* Find loads from stack memory and record them.  */
! 	  if (last_sp_set && stack_memref_p (src)
! 	      && ! reg_mentioned_p (stack_pointer_rtx, dest))
  	    {
  	      memlist = record_one_stack_memref (insn, src, memlist);
  	      goto processed;
  	    }
  
  	  /* Find stores to stack memory and record them.  */
! 	  if (last_sp_set && stack_memref_p (dest)
! 	      && ! reg_mentioned_p (stack_pointer_rtx, src))
  	    {
  	      memlist = record_one_stack_memref (insn, dest, memlist);
  	      goto processed;
*************** combine_stack_adjustments_for_block (bb)
*** 2351,2356 ****
--- 2360,2366 ----
  	      && GET_CODE (dest) == MEM
  	      && GET_CODE (XEXP (dest, 0)) == PRE_DEC
  	      && XEXP (XEXP (dest, 0), 0) == stack_pointer_rtx
+ 	      && ! reg_mentioned_p (stack_pointer_rtx, src)
  	      && validate_change (insn, &SET_DEST (set),
  				  change_address (dest, VOIDmode,
  						  stack_pointer_rtx), 0))
Index: toplev.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/toplev.c,v
retrieving revision 1.307
diff -c -p -d -r1.307 toplev.c
*** toplev.c	2000/03/19 05:26:48	1.307
--- toplev.c	2000/03/20 22:42:47
*************** rest_of_compilation (decl)
*** 3555,3570 ****
  
    if (optimize)
      {
!       TIMEVAR (flow2_time, { cleanup_cfg (insns); });
  
  #ifndef ACCUMULATE_OUTGOING_ARGS
        TIMEVAR (flow2_time, { combine_stack_adjustments (); });
  #endif
- 
-       TIMEVAR (flow2_time, 
- 	       {
- 		 life_analysis (insns, max_reg_num (), rtl_dump_file, 1);
- 	       });
  
        if (ggc_p)
  	ggc_collect ();
--- 3555,3569 ----
  
    if (optimize)
      {
!       TIMEVAR (flow2_time,
! 	       {
! 		 cleanup_cfg (insns);
! 		 life_analysis (insns, max_reg_num (), rtl_dump_file, 1);
! 	       });
  
  #ifndef ACCUMULATE_OUTGOING_ARGS
        TIMEVAR (flow2_time, { combine_stack_adjustments (); });
  #endif
  
        if (ggc_p)
  	ggc_collect ();


More information about the Gcc-patches mailing list