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:
parent
bebc6e07b1
commit
ed853664c5
@ -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
|
||||
|
108
gcc/loop-iv.c
108
gcc/loop-iv.c
@ -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 (®_obstack);
|
||||
this_altered = ALLOC_REG_SET (®_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
|
||||
|
Loading…
Reference in New Issue
Block a user