OSDN Git Service

* toplev.h (NO_FRONT_END_DIAG, ATTRIBUTE_GCC_FE_DIAG): Define.
[pf3gnuchains/gcc-fork.git] / gcc / loop-iv.c
index 0e416c4..e739a85 100644 (file)
@@ -222,6 +222,7 @@ simple_set_p (rtx lhs, rtx rhs)
     case PLUS:
     case MINUS:
     case MULT:
+    case ASHIFT:
       op0 = XEXP (rhs, 0);
       op1 = XEXP (rhs, 1);
 
@@ -238,6 +239,10 @@ simple_set_p (rtx lhs, rtx rhs)
          && !CONSTANT_P (op1))
        return false;
 
+      if (GET_CODE (rhs) == ASHIFT
+         && CONSTANT_P (op0))
+       return false;
+
       return true;
 
     default:
@@ -589,6 +594,31 @@ iv_mult (struct rtx_iv *iv, rtx mby)
   return true;
 }
 
+/* Evaluates shift of IV by constant CST.  */
+
+static bool
+iv_shift (struct rtx_iv *iv, rtx mby)
+{
+  enum machine_mode mode = iv->extend_mode;
+
+  if (GET_MODE (mby) != VOIDmode
+      && GET_MODE (mby) != mode)
+    return false;
+
+  if (iv->extend == NIL)
+    {
+      iv->base = simplify_gen_binary (ASHIFT, mode, iv->base, mby);
+      iv->step = simplify_gen_binary (ASHIFT, mode, iv->step, mby);
+    }
+  else
+    {
+      iv->delta = simplify_gen_binary (ASHIFT, mode, iv->delta, mby);
+      iv->mult = simplify_gen_binary (ASHIFT, mode, iv->mult, mby);
+    }
+
+  return true;
+}
+
 /* The recursive part of get_biv_step.  Gets the value of the single value
    defined in INSN wrto initial value of REG inside loop, in shape described
    at get_biv_step.  */
@@ -1032,7 +1062,14 @@ iv_analyze (rtx insn, rtx def, struct rtx_iv *iv)
              mby = tmp;
            }
          break;
-           
+
+       case ASHIFT:
+         if (CONSTANT_P (XEXP (rhs, 0)))
+           abort ();
+         op0 = XEXP (rhs, 0);
+         mby = XEXP (rhs, 1);
+         break;
+
        default:
          abort ();
        }
@@ -1088,6 +1125,11 @@ iv_analyze (rtx insn, rtx def, struct rtx_iv *iv)
        goto end;
       break;
 
+    case ASHIFT:
+      if (!iv_shift (&iv0, mby))
+       goto end;
+      break;
+
     default:
       break;
     }
@@ -1321,7 +1363,7 @@ simplify_using_assignment (rtx insn, rtx *expr, regset altered)
   if (set)
     {
       lhs = SET_DEST (set);
-      if (GET_CODE (lhs) != REG
+      if (!REG_P (lhs)
          || altered_reg_used (&lhs, altered))
        ret = true;
     }