Fix BIV detection with promoted loop indexes

Richard Kenner kenner@vlsi1.ultra.nyu.edu
Fri Feb 22 14:56:00 GMT 2002


The code in basic_induction_variable has what it expects an increment of
a promoted variable to look like, but that isn't actually what it looks
like.  This patch changes slightly what it expects and slightly what
it does indeed look like.  For Alpha, an additional problem is
that if it has an addsi3 insn, this is used for an HImode add, but
that will cause two separate extensions: from 16 to 32 bits to do the
addsi3 and then from 32 to 64 within the addsi3.

Tested on alphaev56-dec-osf4.,0c.

Fri Feb 22 14:42:47 2002  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>

	* expr.c (store_expr): When converting expression to promoted
	equivalent type, allow using SUBREG_REG of TARGET as the target
	of the expansion of EXP.
	* loop.c (basic_induction_var, case SUBREG): Always look inside.
	* config/alpha/alpha.c (rtx_equiv_function_matters): Delete decl.
	(alpha_emit_set_const): Handle SImode when can't make new pseudos.
	(alpha_emit_set_const_1, alpha_sa_mask): Use no_new_pseudos.
	* config/alpha/alpha.md (addsi3, subsi3): Don't use if optimizing.

*** expr.c	2002/02/21 23:06:15	1.422
--- expr.c	2002/02/22 18:26:34
*************** store_expr (exp, target, want_value)
*** 3990,3993 ****
--- 3990,3995 ----
         expression.  */
      {
+       rtx inner_target = 0;
+ 
        /* If we don't want a value, we can do the conversion inside EXP,
  	 which will often result in some optimizations.  Do the conversion
*************** store_expr (exp, target, want_value)
*** 4010,4016 ****
  					SUBREG_PROMOTED_UNSIGNED_P (target)),
  			 exp);
  	}
  
!       temp = expand_expr (exp, NULL_RTX, VOIDmode, 0);
  
        /* If TEMP is a volatile MEM and we want a result value, make
--- 4012,4020 ----
  					SUBREG_PROMOTED_UNSIGNED_P (target)),
  			 exp);
+ 
+ 	  inner_target = SUBREG_REG (target);
  	}
  
!       temp = expand_expr (exp, inner_target, VOIDmode, 0);
  
        /* If TEMP is a volatile MEM and we want a result value, make
*** loop.c	2002/02/08 03:36:35	1.387
--- loop.c	2002/02/22 18:26:56
*************** basic_induction_var (loop, x, mode, dest
*** 6128,6138 ****
  
      case SUBREG:
!       /* If this is a SUBREG for a promoted variable, check the inner
! 	 value.  */
!       if (SUBREG_PROMOTED_VAR_P (x))
! 	return basic_induction_var (loop, SUBREG_REG (x),
! 				    GET_MODE (SUBREG_REG (x)),
! 				    dest_reg, p, inc_val, mult_val, location);
!       return 0;
  
      case REG:
--- 6128,6138 ----
  
      case SUBREG:
!       /* If what's inside the SUBREG is a BIV, then the SUBREG.  This will
! 	 handle addition of promoted variables.
! 	 ??? The comment at the start of this function is wrong: promoted
! 	 variable increments don't look like it says they do.  */
!       return basic_induction_var (loop, SUBREG_REG (x),
! 				  GET_MODE (SUBREG_REG (x)),
! 				  dest_reg, p, inc_val, mult_val, location);
  
      case REG:
*** config/alpha/alpha.c	2002/02/21 21:11:01	1.232
--- config/alpha/alpha.c	2002/02/22 18:27:13
*************** Boston, MA 02111-1307, USA.  */
*** 49,55 ****
  #include "debug.h"
  
- /* External data.  */
- extern int rtx_equal_function_value_matters;
- 
  /* Specify which cpu to schedule for.  */
  
--- 49,52 ----
*************** alpha_emit_set_const (target, mode, c, n
*** 2232,2244 ****
       int n;
  {
!   rtx pat;
    int i;
  
    /* Try 1 insn, then 2, then up to N.  */
!   for (i = 1; i <= n; i++)
!     if ((pat = alpha_emit_set_const_1 (target, mode, c, i)) != 0)
!       return pat;
  
!   return 0;
  }
  
--- 2229,2255 ----
       int n;
  {
!   rtx result = 0;
!   rtx orig_target = target;
    int i;
  
+   /* If we can't make any pseudos, TARGET is an SImode hard register, we
+      can't load this constant in one insn, do this in DImode.  */
+   if (no_new_pseudos && mode == SImode
+       && GET_CODE (target) == REG && REGNO (target) < FIRST_PSEUDO_REGISTER
+       && (result = alpha_emit_set_const_1 (target, mode, c, 1)) == 0)
+     {
+       target = gen_lowpart (DImode, target);
+       mode = DImode;
+     }
+ 
    /* Try 1 insn, then 2, then up to N.  */
!   for (i = 1; i <= n && result == 0; i++)
!     result = alpha_emit_set_const_1 (target, mode, c, i);
  
!   /* Allow for the case where we changed the mode of TARGET.  */
!   if (result == target)
!     result = orig_target;
! 
!   return result;
  }
  
*************** alpha_emit_set_const_1 (target, mode, c,
*** 2256,2261 ****
    /* Use a pseudo if highly optimizing and still generating RTL.  */
    rtx subtarget
!     = (flag_expensive_optimizations && rtx_equal_function_value_matters
!        ? 0 : target);
    rtx temp;
  
--- 2267,2271 ----
    /* Use a pseudo if highly optimizing and still generating RTL.  */
    rtx subtarget
!     = (flag_expensive_optimizations && !no_new_pseudos ? 0 : target);
    rtx temp;
  
*************** alpha_emit_set_const_1 (target, mode, c,
*** 2322,2327 ****
       and expand_unop calls will widen and try to make pseudos.  */
  
!   if (n == 1
!       || (mode == SImode && ! rtx_equal_function_value_matters))
      return 0;
  
--- 2332,2336 ----
       and expand_unop calls will widen and try to make pseudos.  */
  
!   if (n == 1 || (mode == SImode && no_new_pseudos))
      return 0;
  
*************** alpha_sa_mask (imaskP, fmaskP)
*** 5858,5862 ****
       we don't have valid register life info, but assemble_start_function
       wants to output .frame and .mask directives.  */
!   if (current_function_is_thunk && rtx_equal_function_value_matters)
      {
        *imaskP = 0;
--- 5867,5871 ----
       we don't have valid register life info, but assemble_start_function
       wants to output .frame and .mask directives.  */
!   if (current_function_is_thunk && !no_new_pseudos)
      {
        *imaskP = 0;
*** config/alpha/alpha.md	2002/02/18 01:07:52	1.180
--- config/alpha/alpha.md	2002/02/22 18:27:27
*************** fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi
*** 519,547 ****
    "")
  
! ;; Do addsi3 the way expand_binop would do if we didn't have one.  This
! ;; generates better code.  We have the anonymous addsi3 pattern below in
! ;; case combine wants to make it.
  (define_expand "addsi3"
    [(set (match_operand:SI 0 "register_operand" "")
  	(plus:SI (match_operand:SI 1 "reg_or_0_operand" "")
  		 (match_operand:SI 2 "add_operand" "")))]
!   ""
! {
!   if (optimize)
!     {
!       rtx op1 = gen_lowpart (DImode, operands[1]);
!       rtx op2 = gen_lowpart (DImode, operands[2]);
! 
!       if (! cse_not_expected)
!         {
!           rtx tmp = gen_reg_rtx (DImode);
!           emit_insn (gen_adddi3 (tmp, op1, op2));
!           emit_move_insn (gen_lowpart (DImode, operands[0]), tmp);
!         }
!       else
!         emit_insn (gen_adddi3 (gen_lowpart (DImode, operands[0]), op1, op2));
!       DONE;
!     }
! })
  
  (define_insn "*addsi_internal"
--- 519,530 ----
    "")
  
! ;; Don't say we have addsi3 if optimizing.  This generates better code.  We
! ;; have the anonymous addsi3 pattern below in case combine wants to make it.
  (define_expand "addsi3"
    [(set (match_operand:SI 0 "register_operand" "")
  	(plus:SI (match_operand:SI 1 "reg_or_0_operand" "")
  		 (match_operand:SI 2 "add_operand" "")))]
!   "! optimize"
!   "")
  
  (define_insn "*addsi_internal"
*************** fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi
*** 845,866 ****
  	(minus:SI (match_operand:SI 1 "reg_or_0_operand" "")
  		  (match_operand:SI 2 "reg_or_8bit_operand" "")))]
!   ""
! {
!   if (optimize)
!     {
!       rtx op1 = gen_lowpart (DImode, operands[1]);
!       rtx op2 = gen_lowpart (DImode, operands[2]);
! 
!       if (! cse_not_expected)
!         {
!           rtx tmp = gen_reg_rtx (DImode);
!           emit_insn (gen_subdi3 (tmp, op1, op2));
!           emit_move_insn (gen_lowpart (DImode, operands[0]), tmp);
!         }
!       else
!         emit_insn (gen_subdi3 (gen_lowpart (DImode, operands[0]), op1, op2));
!       DONE;
!     }
! })
  
  (define_insn "*subsi_internal"
--- 828,833 ----
  	(minus:SI (match_operand:SI 1 "reg_or_0_operand" "")
  		  (match_operand:SI 2 "reg_or_8bit_operand" "")))]
!   "! optimize"
!   "")
  
  (define_insn "*subsi_internal"



More information about the Gcc-patches mailing list