loop-iv.c (simplify_using_condition): A condition of the form (EQ REG CONST) can...
authorBernd Schmidt <bernd.schmidt@analog.com>
Tue, 31 Mar 2009 15:16:41 +0000 (15:16 +0000)
committerBernd Schmidt <bernds@gcc.gnu.org>
Tue, 31 Mar 2009 15:16:41 +0000 (15:16 +0000)
* loop-iv.c (simplify_using_condition): A condition of the form
(EQ REG CONST) can be used to simply make a substitution.
(simplify_using_initial_values): Keep track of conditions we have seen
and keep using them to simplify new expressions, while applying the
same substitutions to them as to the expression.

From-SVN: r145352

gcc/ChangeLog
gcc/loop-iv.c

index 007b00e..d4686fd 100644 (file)
@@ -9,6 +9,12 @@
        (simplify_using_initial_values): Deal with altered regs here and track
        more precisely the effect they have on the validity of our expression.
 
+       * loop-iv.c (simplify_using_condition): A condition of the form
+       (EQ REG CONST) can be used to simply make a substitution.
+       (simplify_using_initial_values): Keep track of conditions we have seen
+       and keep using them to simplify new expressions, while applying the
+       same substitutions to them as to the expression.
+
 2009-03-31  Ramana Radhakrishnan  <ramana.radhakrishnan@arm.com>
 
         PR target/27237
index 483a868..123e37c 100644 (file)
@@ -1636,15 +1636,22 @@ simplify_using_condition (rtx cond, rtx *expr, regset altered)
 {
   rtx rev, reve, exp = *expr;
 
-  if (!COMPARISON_P (exp))
-    return;
-
   /* If some register gets altered later, we do not really speak about its
      value at the time of comparison.  */
   if (altered
       && for_each_rtx (&cond, altered_reg_used, altered))
     return;
 
+  if (GET_CODE (cond) == EQ
+      && REG_P (XEXP (cond, 0)) && CONSTANT_P (XEXP (cond, 1)))
+    {
+      *expr = simplify_replace_rtx (*expr, XEXP (cond, 0), XEXP (cond, 1));
+      return;
+    }
+
+  if (!COMPARISON_P (exp))
+    return;
+
   rev = reversed_condition (cond);
   reve = reversed_condition (exp);
 
@@ -1661,7 +1668,6 @@ simplify_using_condition (rtx cond, rtx *expr, regset altered)
       return;
     }
 
-
   if (rev && rtx_equal_p (exp, rev))
     {
       *expr = const0_rtx;
@@ -1746,7 +1752,7 @@ static void
 simplify_using_initial_values (struct loop *loop, enum rtx_code op, rtx *expr)
 {
   bool expression_valid;
-  rtx head, tail, insn, last_valid_expr;
+  rtx head, tail, insn, cond_list, last_valid_expr;
   rtx neutral, aggr;
   regset altered, this_altered;
   edge e;
@@ -1817,26 +1823,40 @@ simplify_using_initial_values (struct loop *loop, enum rtx_code op, rtx *expr)
 
   expression_valid = true;
   last_valid_expr = *expr;
+  cond_list = NULL_RTX;
   while (1)
     {
       insn = BB_END (e->src);
       if (any_condjump_p (insn))
        {
          rtx cond = get_condition (BB_END (e->src), NULL, false, true);
-      
+
          if (cond && (e->flags & EDGE_FALLTHRU))
            cond = reversed_condition (cond);
          if (cond)
            {
+             rtx old = *expr;
              simplify_using_condition (cond, expr, altered);
-             if (CONSTANT_P (*expr))
-               goto out;
+             if (old != *expr)
+               {
+                 rtx note;
+                 if (CONSTANT_P (*expr))
+                   goto out;
+                 for (note = cond_list; note; note = XEXP (note, 1))
+                   {
+                     simplify_using_condition (XEXP (note, 0), expr, altered);
+                     if (CONSTANT_P (*expr))
+                       goto out;
+                   }
+               }
+             cond_list = alloc_EXPR_LIST (0, cond, cond_list);
            }
        }
 
       FOR_BB_INSNS_REVERSE (e->src, insn)
        {
          rtx src, dest;
+         rtx old = *expr;
 
          if (!INSN_P (insn))
            continue;
@@ -1855,9 +1875,34 @@ simplify_using_initial_values (struct loop *loop, enum rtx_code op, rtx *expr)
 
          if (suitable_set_for_replacement (insn, &dest, &src))
            {
+             rtx *pnote, *pnote_next;
+
              *expr = simplify_replace_rtx (*expr, dest, src);
              if (CONSTANT_P (*expr))
                goto out;
+
+             for (pnote = &cond_list; *pnote; pnote = pnote_next)
+               {
+                 rtx note = *pnote;
+                 rtx old_cond = XEXP (note, 0);
+
+                 pnote_next = &XEXP (note, 1);
+                 XEXP (note, 0) = simplify_replace_rtx (XEXP (note, 0), dest,
+                                                        src);
+                 /* We can no longer use a condition that has been simplified
+                    to a constant, and simplify_using_condition will abort if
+                    we try.  */
+                 if (CONSTANT_P (XEXP (note, 0)))
+                   {
+                     *pnote = *pnote_next;
+                     pnote_next = pnote;
+                     free_EXPR_LIST_node (note);
+                   }
+                 /* Retry simplifications with this condition if either the
+                    expression or the condition changed.  */
+                 else if (old_cond != XEXP (note, 0) || old != *expr)
+                   simplify_using_condition (XEXP (note, 0), expr, altered);
+               }
            }
          else
            /* If we did not use this insn to make a replacement, any overlap
@@ -1866,6 +1911,9 @@ simplify_using_initial_values (struct loop *loop, enum rtx_code op, rtx *expr)
            if (for_each_rtx (expr, altered_reg_used, this_altered))
              goto out;
 
+         if (CONSTANT_P (*expr))
+           goto out;
+
          IOR_REG_SET (altered, this_altered);
 
          /* If the expression now contains regs that have been altered, we
@@ -1885,6 +1933,7 @@ simplify_using_initial_values (struct loop *loop, enum rtx_code op, rtx *expr)
     }
 
  out:
+  free_EXPR_LIST_list (&cond_list);
   if (!CONSTANT_P (*expr))
     *expr = last_valid_expr;
   FREE_REG_SET (altered);