expr.c (store_expr): When converting expression to promoted equivalent type...
authorRichard Kenner <kenner@gcc.gnu.org>
Fri, 22 Feb 2002 21:18:25 +0000 (16:18 -0500)
committerRichard Kenner <kenner@gcc.gnu.org>
Fri, 22 Feb 2002 21:18:25 +0000 (16:18 -0500)
* 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.

From-SVN: r49972

gcc/config/alpha/alpha.c
gcc/config/alpha/alpha.md
gcc/expr.c
gcc/loop.c

index 69f7870eeb17f5577a740d849b09e27c58578300..7710be58b60e1526ffe837f72d35a45ceac55028 100644 (file)
@@ -48,9 +48,6 @@ Boston, MA 02111-1307, USA.  */
 #include "target-def.h"
 #include "debug.h"
 
-/* External data.  */
-extern int rtx_equal_function_value_matters;
-
 /* Specify which cpu to schedule for.  */
 
 enum processor_type alpha_cpu;
@@ -2231,15 +2228,29 @@ alpha_emit_set_const (target, mode, c, n)
      HOST_WIDE_INT c;
      int n;
 {
-  rtx pat;
+  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; i++)
-    if ((pat = alpha_emit_set_const_1 (target, mode, c, i)) != 0)
-      return pat;
+  for (i = 1; i <= n && result == 0; i++)
+    result = alpha_emit_set_const_1 (target, mode, c, i);
 
-  return 0;
+  /* Allow for the case where we changed the mode of TARGET.  */
+  if (result == target)
+    result = orig_target;
+
+  return result;
 }
 
 /* Internal routine for the above to check for N or below insns.  */
@@ -2255,8 +2266,7 @@ alpha_emit_set_const_1 (target, mode, c, n)
   int i, bits;
   /* Use a pseudo if highly optimizing and still generating RTL.  */
   rtx subtarget
-    = (flag_expensive_optimizations && rtx_equal_function_value_matters
-       ? 0 : target);
+    = (flag_expensive_optimizations && !no_new_pseudos ? 0 : target);
   rtx temp;
 
 #if HOST_BITS_PER_WIDE_INT == 64
@@ -2321,8 +2331,7 @@ alpha_emit_set_const_1 (target, mode, c, n)
      we can't make pseudos, we can't do anything since the expand_binop
      and expand_unop calls will widen and try to make pseudos.  */
 
-  if (n == 1
-      || (mode == SImode && ! rtx_equal_function_value_matters))
+  if (n == 1 || (mode == SImode && no_new_pseudos))
     return 0;
 
   /* Next, see if we can load a related constant and then shift and possibly
@@ -5857,7 +5866,7 @@ alpha_sa_mask (imaskP, fmaskP)
      the regular part of the compiler.  In the ASM_OUTPUT_MI_THUNK case
      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)
+  if (current_function_is_thunk && !no_new_pseudos)
     {
       *imaskP = 0;
       *fmaskP = 0;
index 48ac0f775774b0728d9b5e895a7443ad853751fd..06c272b6890e607af4e8972a93a2416cb4d2279b 100644 (file)
@@ -518,31 +518,14 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
        (sign_extend:DI (match_dup 1)))]
   "")
 
-;; 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.
+;; 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" "")))]
-  ""
-{
-  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;
-    }
-})
+  "! optimize"
+  "")
 
 (define_insn "*addsi_internal"
   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
@@ -844,24 +827,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
   [(set (match_operand:SI 0 "register_operand" "")
        (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;
-    }
-})
+  "! optimize"
+  "")
 
 (define_insn "*subsi_internal"
   [(set (match_operand:SI 0 "register_operand" "=r")
index b7304350b7f648efb20f6609b82e2a3ada1816e8..bcc76bc26049dbc3ffcb4c0d15014ebe2a0ab623 100644 (file)
@@ -3989,6 +3989,8 @@ store_expr (exp, target, want_value)
        and then convert to the wider mode.  Our value is the computed
        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
         in two steps: first change the signedness, if needed, then
@@ -4009,9 +4011,11 @@ store_expr (exp, target, want_value)
          exp = convert (type_for_mode (GET_MODE (SUBREG_REG (target)),
                                        SUBREG_PROMOTED_UNSIGNED_P (target)),
                         exp);
+
+         inner_target = SUBREG_REG (target);
        }
 
-      temp = expand_expr (exp, NULL_RTX, VOIDmode, 0);
+      temp = expand_expr (exp, inner_target, VOIDmode, 0);
 
       /* If TEMP is a volatile MEM and we want a result value, make
         the access now so it gets done only once.  Likewise if
index f675a87f0debcbc19be4262b25c6553dcc3e465f..68ef43906cb964b9006d5cf986f228864f5c33ca 100644 (file)
@@ -6127,13 +6127,13 @@ basic_induction_var (loop, x, mode, dest_reg, p, inc_val, mult_val, location)
       return 1;
 
     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;
+      /* 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:
       /* If this register is assigned in a previous insn, look at its