aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorBernd Schmidt <bernd.schmidt@analog.com>2009-03-31 15:24:24 +0000
committerBernd Schmidt <bernds@gcc.gnu.org>2009-03-31 15:24:24 +0000
commit60081874a02512aa6ed5958953f65d47aeff3325 (patch)
treec9521ba6180b753de1b62d9c5182ce626c3049d1 /gcc
parentb30321cd329761db5fbf4e0e719983e3faef03e3 (diff)
downloadgcc-60081874a02512aa6ed5958953f65d47aeff3325.zip
gcc-60081874a02512aa6ed5958953f65d47aeff3325.tar.gz
gcc-60081874a02512aa6ed5958953f65d47aeff3325.tar.bz2
loop-iv.c (replace_single_def_regs, [...]): New static functions.
* 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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/loop-iv.c54
2 files changed, 57 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f5360a5..3ac7f56 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -25,6 +25,12 @@
* 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
diff --git a/gcc/loop-iv.c b/gcc/loop-iv.c
index 67d1ebd..9403736 100644
--- a/gcc/loop-iv.c
+++ b/gcc/loop-iv.c
@@ -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. */