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 to reduce register pressure from strength reduction


> I came across this problem trying to bootstrap on x86-linux with the
> following
> flags "-O9 -march=pentiumpro -mcpu=pentiumpro -funroll-loops
> -fomit-frame-pointer".
> The bootstrap fails when compiling gcc/reload1.c using the stage1/cc1
> compiler 
> due to access violation caused by a giv_inc being 0 when passed to
> INTVAL() macro.

I have made a patch for this problem:

Thu Jan 28 18:52:02 1999  J"orn Rennecke <amylaar@cygnus.co.uk>

	* loop.c (recombine_givs): New parameter unroll_p.  If set, don't
	generate complex adds.  Changed caller.
	Don't generate adds that cost more than the original one.
	(strength_reduce): Warnig fixes.

Index: loop.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/loop.c,v
retrieving revision 1.116
diff -p -r1.116 loop.c
*** loop.c	1999/01/27 15:45:45	1.116
--- loop.c	1999/01/28 19:18:13
*************** static rtx combine_givs_p PROTO((struct 
*** 325,331 ****
  static void combine_givs PROTO((struct iv_class *));
  struct recombine_givs_stats;
  static int find_life_end (rtx,  struct recombine_givs_stats *, rtx, rtx);
! static void recombine_givs PROTO((struct iv_class *, rtx, rtx));
  static int product_cheap_p PROTO((rtx, rtx));
  static int maybe_eliminate_biv PROTO((struct iv_class *, rtx, rtx, int, int, int));
  static int maybe_eliminate_biv_1 PROTO((rtx, rtx, struct iv_class *, int, rtx));
--- 325,331 ----
  static void combine_givs PROTO((struct iv_class *));
  struct recombine_givs_stats;
  static int find_life_end (rtx,  struct recombine_givs_stats *, rtx, rtx);
! static void recombine_givs PROTO((struct iv_class *, rtx, rtx, int));
  static int product_cheap_p PROTO((rtx, rtx));
  static int maybe_eliminate_biv PROTO((struct iv_class *, rtx, rtx, int, int, int));
  static int maybe_eliminate_biv_1 PROTO((rtx, rtx, struct iv_class *, int, rtx));
*************** strength_reduce (scan_start, end, loop_t
*** 3924,3930 ****
    /* Look at the each biv and see if we can say anything better about its
       initial value from any initializing insns set up above.  (This is done
       in two passes to avoid missing SETs in a PARALLEL.)  */
!   for (backbl = &loop_iv_list; bl = *backbl; backbl = &bl->next)
      {
        rtx src;
        rtx note;
--- 3924,3930 ----
    /* Look at the each biv and see if we can say anything better about its
       initial value from any initializing insns set up above.  (This is done
       in two passes to avoid missing SETs in a PARALLEL.)  */
!   for (backbl = &loop_iv_list; (bl = *backbl); backbl = &bl->next)
      {
        rtx src;
        rtx note;
*************** strength_reduce (scan_start, end, loop_t
*** 4019,4025 ****
  	    {
  	      int loop_num = uid_loop_num[INSN_UID (loop_start)];
  	      rtx dominator = loop_number_cont_dominator[loop_num];
- 	      rtx cont = loop_number_loop_cont[loop_num];
  	      rtx giv = bl->biv->src_reg;
  	      rtx giv_insn = bl->biv->insn;
  	      rtx after_giv = NEXT_INSN (giv_insn);
--- 4019,4024 ----
*************** strength_reduce (scan_start, end, loop_t
*** 4584,4590 ****
  
        /* Now that we know which givs will be reduced, try to rearrange the
           combinations to reduce register pressure.  */
!       recombine_givs (bl, loop_start, loop_end);
  
        /* Reduce each giv that we decided to reduce.  */
  
--- 4583,4589 ----
  
        /* Now that we know which givs will be reduced, try to rearrange the
           combinations to reduce register pressure.  */
!       recombine_givs (bl, loop_start, loop_end, unroll_p);
  
        /* Reduce each giv that we decided to reduce.  */
  
*************** find_life_end (x, stats, insn, biv)
*** 7030,7038 ****
     This tends to shorten giv lifetimes, and helps the next step:
     try to derive givs from other givs.  */
  static void
! recombine_givs (bl, loop_start, loop_end)
       struct iv_class *bl;
       rtx loop_start, loop_end;
  {
    struct induction *v, **giv_array, *last_giv;
    struct recombine_givs_stats *stats;
--- 7029,7038 ----
     This tends to shorten giv lifetimes, and helps the next step:
     try to derive givs from other givs.  */
  static void
! recombine_givs (bl, loop_start, loop_end, unroll_p)
       struct iv_class *bl;
       rtx loop_start, loop_end;
+      int unroll_p;
  {
    struct induction *v, **giv_array, *last_giv;
    struct recombine_givs_stats *stats;
*************** recombine_givs (bl, loop_start, loop_end
*** 7284,7289 ****
--- 7284,7300 ----
  		 validity of last_giv.  */
  	      && (v->always_executed || ! v->combined_with)
  	      && (sum = express_from (last_giv, v))
+ 	      /* Make sure we don't make the add more expensive.  ADD_COST
+ 		 doesn't take different costs of registers and constants into
+ 		 account, so compare the cost of the actual SET_SRCs.  */
+ 	      && (rtx_cost (sum, SET)
+ 		  <= rtx_cost (SET_SRC (single_set (v->insn)), SET))
+ 	      /* ??? unroll can't understand anything but reg + const_int
+ 		 sums.  It would be cleaner to fix unroll.  */
+ 	      && ((GET_CODE (sum) == PLUS
+ 		   && GET_CODE (XEXP (sum, 0)) == REG
+ 		   && GET_CODE (XEXP (sum, 1)) == CONST_INT)
+ 		  || ! unroll_p)
  	      && validate_change (v->insn, &PATTERN (v->insn),
  				  gen_rtx_SET (GET_MODE (v->dest_reg),
  					       v->dest_reg, sum), 0))


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