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 @@
(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
......
......@@ -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,6 +1823,7 @@ 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);
......@@ -1828,15 +1835,28 @@ simplify_using_initial_values (struct loop *loop, enum rtx_code op, rtx *expr)
cond = reversed_condition (cond);
if (cond)
{
rtx old = *expr;
simplify_using_condition (cond, expr, altered);
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);
......
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