Commit 1569e190 by Bernd Schmidt Committed by Bernd Schmidt

loop-iv.c (simplify_using_condition): A condition of the form (EQ REG CONST) can…

loop-iv.c (simplify_using_condition): A condition of the form (EQ REG CONST) can be used to simply make a substitution.

	* 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
parent ed853664
...@@ -9,6 +9,12 @@ ...@@ -9,6 +9,12 @@
(simplify_using_initial_values): Deal with altered regs here and track (simplify_using_initial_values): Deal with altered regs here and track
more precisely the effect they have on the validity of our expression. 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> 2009-03-31 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
PR target/27237 PR target/27237
......
...@@ -1636,15 +1636,22 @@ simplify_using_condition (rtx cond, rtx *expr, regset altered) ...@@ -1636,15 +1636,22 @@ simplify_using_condition (rtx cond, rtx *expr, regset altered)
{ {
rtx rev, reve, exp = *expr; rtx rev, reve, exp = *expr;
if (!COMPARISON_P (exp))
return;
/* If some register gets altered later, we do not really speak about its /* If some register gets altered later, we do not really speak about its
value at the time of comparison. */ value at the time of comparison. */
if (altered if (altered
&& for_each_rtx (&cond, altered_reg_used, altered)) && for_each_rtx (&cond, altered_reg_used, altered))
return; 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); rev = reversed_condition (cond);
reve = reversed_condition (exp); reve = reversed_condition (exp);
...@@ -1661,7 +1668,6 @@ simplify_using_condition (rtx cond, rtx *expr, regset altered) ...@@ -1661,7 +1668,6 @@ simplify_using_condition (rtx cond, rtx *expr, regset altered)
return; return;
} }
if (rev && rtx_equal_p (exp, rev)) if (rev && rtx_equal_p (exp, rev))
{ {
*expr = const0_rtx; *expr = const0_rtx;
...@@ -1746,7 +1752,7 @@ static void ...@@ -1746,7 +1752,7 @@ static void
simplify_using_initial_values (struct loop *loop, enum rtx_code op, rtx *expr) simplify_using_initial_values (struct loop *loop, enum rtx_code op, rtx *expr)
{ {
bool expression_valid; bool expression_valid;
rtx head, tail, insn, last_valid_expr; rtx head, tail, insn, cond_list, last_valid_expr;
rtx neutral, aggr; rtx neutral, aggr;
regset altered, this_altered; regset altered, this_altered;
edge e; edge e;
...@@ -1817,26 +1823,40 @@ simplify_using_initial_values (struct loop *loop, enum rtx_code op, rtx *expr) ...@@ -1817,26 +1823,40 @@ simplify_using_initial_values (struct loop *loop, enum rtx_code op, rtx *expr)
expression_valid = true; expression_valid = true;
last_valid_expr = *expr; last_valid_expr = *expr;
cond_list = NULL_RTX;
while (1) while (1)
{ {
insn = BB_END (e->src); insn = BB_END (e->src);
if (any_condjump_p (insn)) if (any_condjump_p (insn))
{ {
rtx cond = get_condition (BB_END (e->src), NULL, false, true); rtx cond = get_condition (BB_END (e->src), NULL, false, true);
if (cond && (e->flags & EDGE_FALLTHRU)) if (cond && (e->flags & EDGE_FALLTHRU))
cond = reversed_condition (cond); cond = reversed_condition (cond);
if (cond) if (cond)
{ {
rtx old = *expr;
simplify_using_condition (cond, expr, altered); simplify_using_condition (cond, expr, altered);
if (CONSTANT_P (*expr)) if (old != *expr)
goto out; {
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) FOR_BB_INSNS_REVERSE (e->src, insn)
{ {
rtx src, dest; rtx src, dest;
rtx old = *expr;
if (!INSN_P (insn)) if (!INSN_P (insn))
continue; continue;
...@@ -1855,9 +1875,34 @@ simplify_using_initial_values (struct loop *loop, enum rtx_code op, rtx *expr) ...@@ -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)) if (suitable_set_for_replacement (insn, &dest, &src))
{ {
rtx *pnote, *pnote_next;
*expr = simplify_replace_rtx (*expr, dest, src); *expr = simplify_replace_rtx (*expr, dest, src);
if (CONSTANT_P (*expr)) if (CONSTANT_P (*expr))
goto out; 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 else
/* If we did not use this insn to make a replacement, any overlap /* 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) ...@@ -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)) if (for_each_rtx (expr, altered_reg_used, this_altered))
goto out; goto out;
if (CONSTANT_P (*expr))
goto out;
IOR_REG_SET (altered, this_altered); IOR_REG_SET (altered, this_altered);
/* If the expression now contains regs that have been altered, we /* 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) ...@@ -1885,6 +1933,7 @@ simplify_using_initial_values (struct loop *loop, enum rtx_code op, rtx *expr)
} }
out: out:
free_EXPR_LIST_list (&cond_list);
if (!CONSTANT_P (*expr)) if (!CONSTANT_P (*expr))
*expr = last_valid_expr; *expr = last_valid_expr;
FREE_REG_SET (altered); FREE_REG_SET (altered);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment