loop-iv.c (replace_single_def_regs, [...]): New static functions.
authorBernd Schmidt <bernd.schmidt@analog.com>
Tue, 31 Mar 2009 15:24:24 +0000 (15:24 +0000)
committerBernd Schmidt <bernds@gcc.gnu.org>
Tue, 31 Mar 2009 15:24:24 +0000 (15:24 +0000)
* loop-iv.c (replace_single_def_regs, replace_in_expr): New static
functions.
(simplify_using_assignment, simplify_using_initial_values): Call
replace_in_expr to make replacements.  Call replace_single_def_regs
once on the initial version of the expression.

From-SVN: r145357

gcc/ChangeLog
gcc/loop-iv.c

index f5360a5..3ac7f56 100644 (file)
 
        * loop-iv.c (simple_rhs_p): Allow more kinds of expressions.
 
+       * loop-iv.c (replace_single_def_regs, replace_in_expr): New static
+       functions.
+       (simplify_using_assignment, simplify_using_initial_values): Call 
+       replace_in_expr to make replacements.  Call replace_single_def_regs
+       once on the initial version of the expression.
+
 2009-03-31  Ramana Radhakrishnan  <ramana.radhakrishnan@arm.com>
 
         PR target/27237
index 67d1ebd..9403736 100644 (file)
@@ -1368,6 +1368,34 @@ simple_rhs_p (rtx rhs)
     }
 }
 
+/* If REG has a single definition, replace it with its known value in EXPR.
+   Callback for for_each_rtx.  */
+
+static int
+replace_single_def_regs (rtx *reg, void *expr1)
+{
+  unsigned regno;
+  df_ref adef;
+  rtx set;
+  rtx *expr = (rtx *)expr1;
+
+  if (!REG_P (*reg))
+    return 0;
+
+  regno = REGNO (*reg);
+  adef = DF_REG_DEF_CHAIN (regno);
+  if (adef == NULL || DF_REF_NEXT_REG (adef) != NULL
+      || DF_REF_IS_ARTIFICIAL (adef))
+    return -1;
+
+  set = single_set (DF_REF_INSN (adef));
+  if (set == NULL || SET_DEST (set) != *reg || !CONSTANT_P (SET_SRC (set)))
+    return -1;
+
+  *expr = simplify_replace_rtx (*expr, *reg, SET_SRC (set));
+  return 1;
+}
+
 /* A subroutine of simplify_using_initial_values, this function examines INSN
    to see if it contains a suitable set that we can use to make a replacement.
    If it is suitable, return true and set DEST and SRC to the lhs and rhs of
@@ -1400,6 +1428,20 @@ suitable_set_for_replacement (rtx insn, rtx *dest, rtx *src)
   return true;
 }
 
+/* Using the data returned by suitable_set_for_replacement, replace DEST
+   with SRC in *EXPR and return the new expression.  Also call
+   replace_single_def_regs if the replacement changed something.  */
+static void
+replace_in_expr (rtx *expr, rtx dest, rtx src)
+{
+  rtx old = *expr;
+  *expr = simplify_replace_rtx (*expr, dest, src);
+  if (old == *expr)
+    return;
+  while (for_each_rtx (expr, replace_single_def_regs, expr) != 0)
+    continue;
+}
+
 /* Checks whether A implies B.  */
 
 static bool
@@ -1818,6 +1860,12 @@ simplify_using_initial_values (struct loop *loop, enum rtx_code op, rtx *expr)
 
   gcc_assert (op == UNKNOWN);
 
+  for (;;)
+    if (for_each_rtx (expr, replace_single_def_regs, expr) == 0)
+      break;
+  if (CONSTANT_P (*expr))
+    return;
+
   e = loop_preheader_edge (loop);
   if (e->src == ENTRY_BLOCK_PTR)
     return;
@@ -1881,7 +1929,7 @@ simplify_using_initial_values (struct loop *loop, enum rtx_code op, rtx *expr)
            {
              rtx *pnote, *pnote_next;
 
-             *expr = simplify_replace_rtx (*expr, dest, src);
+             replace_in_expr (expr, dest, src);
              if (CONSTANT_P (*expr))
                goto out;
 
@@ -1891,8 +1939,8 @@ simplify_using_initial_values (struct loop *loop, enum rtx_code op, rtx *expr)
                  rtx old_cond = XEXP (note, 0);
 
                  pnote_next = &XEXP (note, 1);
-                 XEXP (note, 0) = simplify_replace_rtx (XEXP (note, 0), dest,
-                                                        src);
+                 replace_in_expr (&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.  */