[gnu.gcc.bug] misc. strength reduction fixes

wilson@ji.Berkeley.EDU (James E. Wilson) (04/10/89)

These patches assume that all of the previous patches by Matthew Self
(self@bayes.arc.nasa.gov) have already been applied.  The following 
patches fix miscellaneous bugs in the strength reduction code.  Most
of the changes have comments which indicate why I believe the change
is necessary.

*** loop.c.orig	Sun Apr  9 16:41:04 1989
--- loop.c	Sun Apr  9 21:31:12 1989
***************
*** 1915,1921 ****
    int regno;                   /* Pseudo reg which is the biv.  */
    int biv_count;               /* Number of insns setting this reg.  */
    struct induction *biv;       /* List of all insns that set this reg.  */
!   int giv_count;               /* Number of givs computed from this biv.  */
    struct induction *giv;       /* List of all insns that compute a giv
  				  from this reg.  */
    int total_benefit;           /* Sum of BENEFITs of all those givs */
--- 1915,1923 ----
    int regno;                   /* Pseudo reg which is the biv.  */
    int biv_count;               /* Number of insns setting this reg.  */
    struct induction *biv;       /* List of all insns that set this reg.  */
!   int giv_count;               /* Number of DEST_REG givs computed from this
! 				  biv, the resulting count is only used in
! 				  check_dbra_loop () */
    struct induction *giv;       /* List of all insns that compute a giv
  				  from this reg.  */
    int total_benefit;           /* Sum of BENEFITs of all those givs */
***************
*** 2483,2492 ****
  	      fprintf (loop_dump_stream,
  		       "Cannot eliminate biv %d: used outside the loop.\n",
  		       bl->regno);
  	      fprintf (loop_dump_stream,
  		       "First use: insn %d, last use: insn %d.\n",
! 		       uid_luid[regno_first_uid[bl->regno]],
! 		       uid_luid[regno_last_uid[bl->regno]]);
  	    }
  	}
  
--- 2485,2495 ----
  	      fprintf (loop_dump_stream,
  		       "Cannot eliminate biv %d: used outside the loop.\n",
  		       bl->regno);
+ 	      /* was printing luid values of insns, but that was confusing */
  	      fprintf (loop_dump_stream,
  		       "First use: insn %d, last use: insn %d.\n",
! 		       regno_first_uid[bl->regno],
! 		       regno_last_uid[bl->regno]);
  	    }
  	}
  
***************
*** 2562,2567 ****
--- 2565,2571 ----
  		fprintf (loop_dump_stream, "giv of insn %d, no benefit\n",
  			 INSN_UID (v->insn));
  	      v->ignore = 1;
+ 	      all_reduced = 0;
  	    }
  
  	  if (v->lifetime * threshold * benefit < insn_count)
***************
*** 2572,2577 ****
--- 2576,2582 ----
  			 INSN_UID (v->insn),
  			 v->lifetime * threshold * benefit, insn_count);
  	      v->ignore = 1;
+ 	      all_reduced = 0;
  	    }
  
  	  /* Now check that we can increment the reduced giv
***************
*** 2592,2597 ****
--- 2597,2603 ----
  			     "giv of insn %d: would need a multiply.\n",
  			     INSN_UID (v->insn));
  		  v->ignore = 1;
+ 		  all_reduced = 0;
  		}
  	    }
  	}
***************
*** 2688,2700 ****
  	  else if (v->new_reg == 0)
  	    {
  	      /* This giv wasn't reduced and is not worth reducing.  */
  
  	      for (tv = v; tv; tv = tv->same)
  		if (loop_dump_stream)
! 		  fprintf (loop_dump_stream, "giv at %d not reduced\n",
  			   INSN_UID (tv->insn));
  
! 	      all_reduced = 0;
  	    }
  	}
  
--- 2694,2710 ----
  	  else if (v->new_reg == 0)
  	    {
  	      /* This giv wasn't reduced and is not worth reducing.  */
+ 	      /* These are insns which are 'forced' by other insns.  */
  
  	      for (tv = v; tv; tv = tv->same)
  		if (loop_dump_stream)
! 		  fprintf (loop_dump_stream, "giv at %d ignored\n",
  			   INSN_UID (tv->insn));
  
! 	      /* clearing all_reduced here is incorrect, the test correctly
! 		 handles insns which have the ignore flag set above, but
! 		 not those whose ignore flags are set in record_giv(),
! 		 all_reduced is now cleared above */
  	    }
  	}
  
***************
*** 3000,3006 ****
      {
        v->family = bl->giv;
        bl->giv = v;
!       bl->giv_count++;
        bl->total_benefit += benefit;
      }
    else
--- 3010,3020 ----
      {
        v->family = bl->giv;
        bl->giv = v;
!       /* don't count DEST_ADDR, this is supposed to count the number of
! 	 insns that calculate givs, the count is only used in
! 	 check_dbra_loop () */
!       if (type == DEST_REG)
! 	bl->giv_count++;
        bl->total_benefit += benefit;
      }
    else
***************
*** 4020,4030 ****
  	emit_insn_before (gen_rtx (SET, VOIDmode, reg, a),
  			  loop_start);
        else
  	emit_insn_before (gen_rtx (SET, VOIDmode, reg,
  				   gen_rtx (PLUS, GET_MODE (reg),
  					    gen_rtx (CONST_INT, VOIDmode,
! 						     const_val),
! 					    a)),
  			loop_start);
        break;
  
--- 4034,4045 ----
  	emit_insn_before (gen_rtx (SET, VOIDmode, reg, a),
  			  loop_start);
        else
+ 	/* the const_int should be the second arg of the plus rtl */
  	emit_insn_before (gen_rtx (SET, VOIDmode, reg,
  				   gen_rtx (PLUS, GET_MODE (reg),
+ 					    a,
  					    gen_rtx (CONST_INT, VOIDmode,
! 						     const_val))),
  			loop_start);
        break;
  
***************
*** 4341,4347 ****
  		  branch_code
  		    = GET_CODE (XEXP (SET_SRC (PATTERN (PREV_INSN (loop_end))), 0));
  		  src_two_before_end
! 		    = PATTERN (PREV_INSN (PREV_INSN (loop_end)));
  
  		  if (bl->initial_value == const0_rtx
  		      && (branch_code == LT || branch_code == LE)
--- 4356,4362 ----
  		  branch_code
  		    = GET_CODE (XEXP (SET_SRC (PATTERN (PREV_INSN (loop_end))), 0));
  		  src_two_before_end
! 		    = SET_SRC (PATTERN (PREV_INSN (PREV_INSN (loop_end))));
  
  		  if (bl->initial_value == const0_rtx
  		      && (branch_code == LT || branch_code == LE)
***************
*** 4477,4487 ****
      {
        /* a test insn */
      case REG:
!       /* Can replace with any giv that has (MULT_VAL != 0) and (ADD_VAL == 0)
! 	 and make sure it was strength reduced by checking for NEW_REG != 0 */
  
        for (v = bl->giv; v; v = v->family)
! 	if (v->mult_val != const0_rtx && v->add_val == const0_rtx
  	    && ((v->giv_type == DEST_REG
  		 && GET_MODE (SET_DEST (PATTERN (v->insn))) == mode)
  		|| (v->giv_type == DEST_ADDR
--- 4492,4504 ----
      {
        /* a test insn */
      case REG:
!       /* Can replace with any giv that has (MULT_VAL != 0) and (ADD_VAL == 0) */
!       /* Can not accept an arbitrary register for the mult_val, since the
! 	 register could be zero, hence, force mult_val to be a constant */
  
        for (v = bl->giv; v; v = v->family)
! 	if (GET_CODE(v->mult_val) == CONST_INT && v->mult_val != const0_rtx
! 	    && v->add_val == const0_rtx
  	    && ((v->giv_type == DEST_REG
  		 && GET_MODE (SET_DEST (PATTERN (v->insn))) == mode)
  		|| (v->giv_type == DEST_ADDR
***************
*** 4490,4498 ****
  
        /* Look for a giv with (MULT_VAL != 0) and (ADD_VAL != 0);
  	 replace test insn with a compare insn (cmp REDUCED_GIV ADD_VAL) */
  
        for (v = bl->giv; v; v = v->family)
! 	if (v->mult_val != const0_rtx
  	    && ((v->giv_type == DEST_REG
  		 && GET_MODE (SET_DEST (PATTERN (v->insn))) == mode)
  		|| (v->giv_type == DEST_ADDR
--- 4507,4517 ----
  
        /* Look for a giv with (MULT_VAL != 0) and (ADD_VAL != 0);
  	 replace test insn with a compare insn (cmp REDUCED_GIV ADD_VAL) */
+       /* Can not accept an arbitrary register for the mult_val, since the
+ 	 register could be zero, hence, force mult_val to be a constant */
  
        for (v = bl->giv; v; v = v->family)
! 	if (GET_CODE(v->mult_val) == CONST_INT && v->mult_val != const0_rtx
  	    && ((v->giv_type == DEST_REG
  		 && GET_MODE (SET_DEST (PATTERN (v->insn))) == mode)
  		|| (v->giv_type == DEST_ADDR
***************
*** 4616,4626 ****
      {
        /* a test insn */
      case REG:
!       /* Can replace with any giv
! 	 that has (MULT_VAL != 0) and (ADD_VAL == 0).  */
  
        for (v = bl->giv; v; v = v->family)
! 	if (v->mult_val != const0_rtx && v->add_val == const0_rtx
  	    && v->new_reg != 0
  	    && ((v->giv_type == DEST_REG
  		 && GET_MODE (SET_DEST (PATTERN (v->insn))) == mode)
--- 4635,4648 ----
      {
        /* a test insn */
      case REG:
!       /* Can replace with any giv that has (MULT_VAL != 0) and (ADD_VAL == 0),
!        	 and make sure it was strength reduced by checking for NEW_REG != 0 */
!       /* Can not accept an arbitrary register for the mult_val, since the
! 	 register could be zero, hence force mult_val to be a constant */
  
        for (v = bl->giv; v; v = v->family)
! 	if (GET_CODE(v->mult_val) == CONST_INT && v->mult_val != const0_rtx
! 	    && v->add_val == const0_rtx
  	    && v->new_reg != 0
  	    && ((v->giv_type == DEST_REG
  		 && GET_MODE (SET_DEST (PATTERN (v->insn))) == mode)
***************
*** 4636,4644 ****
  
        /* Look for a giv with (MULT_VAL != 0) and (ADD_VAL != 0);
  	 replace test insn with a compare insn (cmp REDUCED_GIV ADD_VAL) */
  
        for (v = bl->giv; v; v = v->family)
! 	if (v->mult_val != const0_rtx && v->new_reg != 0
  	    && ((v->giv_type == DEST_REG
  		 && GET_MODE (SET_DEST (PATTERN (v->insn))) == mode)
  		|| (v->giv_type == DEST_ADDR
--- 4658,4669 ----
  
        /* Look for a giv with (MULT_VAL != 0) and (ADD_VAL != 0);
  	 replace test insn with a compare insn (cmp REDUCED_GIV ADD_VAL) */
+       /* Can not accept an arbitrary register for the mult_val, since the
+ 	 register could be zero, hence, force mult_val to be a constant */
  
        for (v = bl->giv; v; v = v->family)
! 	if (GET_CODE(v->mult_val) == CONST_INT && v->mult_val != const0_rtx
! 	    && v->new_reg != 0
  	    && ((v->giv_type == DEST_REG
  		 && GET_MODE (SET_DEST (PATTERN (v->insn))) == mode)
  		|| (v->giv_type == DEST_ADDR
*** rtl.c.orig	Sun Apr  9 16:38:33 1989
--- rtl.c	Sun Apr  9 16:38:53 1989
***************
*** 140,146 ****
  			   "NOTE_INSN_BLOCK_BEG", "NOTE_INSN_BLOCK_END",
  			   "NOTE_INSN_LOOP_BEG", "NOTE_INSN_LOOP_END" };
  
! char *reg_note_name[] = { "REG_DEAD", "REG_INC", "REG_EQUIV", "REG_WAS_0",
  			  "REG_EQUAL", "REG_RETVAL", "REG_LIBCALL",
  			  "REG_NONNEG", "REG_ASM_LINE", "REG_ASM_FILE" };
  
--- 140,147 ----
  			   "NOTE_INSN_BLOCK_BEG", "NOTE_INSN_BLOCK_END",
  			   "NOTE_INSN_LOOP_BEG", "NOTE_INSN_LOOP_END" };
  
! /* the reg note names start at index 1 */
! char *reg_note_name[] = { "", "REG_DEAD", "REG_INC", "REG_EQUIV", "REG_WAS_0",
  			  "REG_EQUAL", "REG_RETVAL", "REG_LIBCALL",
  			  "REG_NONNEG", "REG_ASM_LINE", "REG_ASM_FILE" };
  

Jim Wilson                          | And if a man tried to spend his time on 
Internet: wilson@ernie.Berkeley.EDU | earth, to show before he died, what one
Usenet:  ...!ucbvax!ucbernie!wilson | man's life could be worth, yes, I wonder
                                    | what would happen to this world.