loop-iv.c (suitable_set_for_replacement): Renamed from simplify_using_assignment...

* loop-iv.c (suitable_set_for_replacement): Renamed from
	simplify_using_assignment; changed to return bool and to accept new
	args DEST and SRC.  Return true iff we find a source/destination pair
	that can be used to make a replacement, and fill SRC and DEST if so.
	Remove arg ALTERED.  Don't deal with altered regs here.  All callers
	changed.
	(simplify_using_initial_values): Deal with altered regs here and track
	more precisely the effect they have on the validity of our expression.

From-SVN: r145351
This commit is contained in:
Bernd Schmidt 2009-03-31 15:15:04 +00:00 committed by Bernd Schmidt
parent bebc6e07b1
commit ed853664c5
2 changed files with 72 additions and 47 deletions

View File

@ -1,3 +1,14 @@
2009-03-31 Bernd Schmidt <bernd.schmidt@analog.com>
* loop-iv.c (suitable_set_for_replacement): Renamed from
simplify_using_assignment; changed to return bool and to accept new
args DEST and SRC. Return true iff we find a source/destination pair
that can be used to make a replacement, and fill SRC and DEST if so.
Remove arg ALTERED. Don't deal with altered regs here. All callers
changed.
(simplify_using_initial_values): Deal with altered regs here and track
more precisely the effect they have on the validity of our expression.
2009-03-31 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
PR target/27237

View File

@ -1364,39 +1364,23 @@ simple_rhs_p (rtx rhs)
}
}
/* Simplifies *EXPR using assignment in INSN. ALTERED is the set of registers
altered so far. */
/* 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
the set; return false otherwise. */
static void
simplify_using_assignment (rtx insn, rtx *expr, regset altered)
static bool
suitable_set_for_replacement (rtx insn, rtx *dest, rtx *src)
{
rtx set = single_set (insn);
rtx lhs = NULL_RTX, rhs;
bool ret = false;
if (set)
{
lhs = SET_DEST (set);
if (!REG_P (lhs)
|| altered_reg_used (&lhs, altered))
ret = true;
}
else
ret = true;
if (!set)
return false;
note_stores (PATTERN (insn), mark_altered, altered);
if (CALL_P (insn))
{
int i;
/* Kill all call clobbered registers. */
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
if (TEST_HARD_REG_BIT (regs_invalidated_by_call, i))
SET_REGNO_REG_SET (altered, i);
}
if (ret)
return;
lhs = SET_DEST (set);
if (!REG_P (lhs))
return false;
rhs = find_reg_equal_equiv_note (insn);
if (rhs)
@ -1405,12 +1389,11 @@ simplify_using_assignment (rtx insn, rtx *expr, regset altered)
rhs = SET_SRC (set);
if (!simple_rhs_p (rhs))
return;
return false;
if (for_each_rtx (&rhs, altered_reg_used, altered))
return;
*expr = simplify_replace_rtx (*expr, lhs, rhs);
*dest = lhs;
*src = rhs;
return true;
}
/* Checks whether A implies B. */
@ -1762,9 +1745,10 @@ eliminate_implied_conditions (enum rtx_code op, rtx *head, rtx tail)
static void
simplify_using_initial_values (struct loop *loop, enum rtx_code op, rtx *expr)
{
rtx head, tail, insn;
bool expression_valid;
rtx head, tail, insn, last_valid_expr;
rtx neutral, aggr;
regset altered;
regset altered, this_altered;
edge e;
if (!*expr)
@ -1829,7 +1813,10 @@ simplify_using_initial_values (struct loop *loop, enum rtx_code op, rtx *expr)
return;
altered = ALLOC_REG_SET (&reg_obstack);
this_altered = ALLOC_REG_SET (&reg_obstack);
expression_valid = true;
last_valid_expr = *expr;
while (1)
{
insn = BB_END (e->src);
@ -1843,29 +1830,52 @@ simplify_using_initial_values (struct loop *loop, enum rtx_code op, rtx *expr)
{
simplify_using_condition (cond, expr, altered);
if (CONSTANT_P (*expr))
{
FREE_REG_SET (altered);
return;
}
goto out;
}
}
FOR_BB_INSNS_REVERSE (e->src, insn)
{
rtx src, dest;
if (!INSN_P (insn))
continue;
simplify_using_assignment (insn, expr, altered);
if (CONSTANT_P (*expr))
CLEAR_REG_SET (this_altered);
note_stores (PATTERN (insn), mark_altered, this_altered);
if (CALL_P (insn))
{
FREE_REG_SET (altered);
return;
int i;
/* Kill all call clobbered registers. */
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
if (TEST_HARD_REG_BIT (regs_invalidated_by_call, i))
SET_REGNO_REG_SET (this_altered, i);
}
if (suitable_set_for_replacement (insn, &dest, &src))
{
*expr = simplify_replace_rtx (*expr, dest, src);
if (CONSTANT_P (*expr))
goto out;
}
else
/* If we did not use this insn to make a replacement, any overlap
between stores in this insn and our expression will cause the
expression to become invalid. */
if (for_each_rtx (expr, altered_reg_used, this_altered))
goto out;
IOR_REG_SET (altered, this_altered);
/* If the expression now contains regs that have been altered, we
can't return it to the caller. However, it is still valid for
further simplification, so keep searching to see if we can
eventually turn it into a constant. */
if (for_each_rtx (expr, altered_reg_used, altered))
{
FREE_REG_SET (altered);
return;
}
expression_valid = false;
if (expression_valid)
last_valid_expr = *expr;
}
if (!single_pred_p (e->src)
@ -1874,7 +1884,11 @@ simplify_using_initial_values (struct loop *loop, enum rtx_code op, rtx *expr)
e = single_pred_edge (e->src);
}
out:
if (!CONSTANT_P (*expr))
*expr = last_valid_expr;
FREE_REG_SET (altered);
FREE_REG_SET (this_altered);
}
/* Transforms invariant IV into MODE. Adds assumptions based on the fact