re PR rtl-optimization/32283 (Missed induction variable optimization)
PR rtl-optimization/32283 * tree-ssa-loop-niter.c (scev_probably_wraps_p): Use type of the base of the induction variable to decide whether it may wrap. * tree-ssa-loop-ivopts.c (rewrite_use_compare): Emit the initialization of the bound before the loop. * simplify-rtx.c (simplify_binary_operation_1): Add two simplifications regarding AND. (simplify_plus_minus): Only fail if no simplification is possible. * loop-iv.c (simple_rhs_p): Consider reg + reg and reg << cst simple. From-SVN: r142035
This commit is contained in:
parent
f9487002a4
commit
dc5b3407f2
|
@ -1,3 +1,15 @@
|
|||
2008-11-19 Zdenek Dvorak <ook@ucw.cz>
|
||||
|
||||
PR rtl-optimization/32283
|
||||
* tree-ssa-loop-niter.c (scev_probably_wraps_p): Use type of the base
|
||||
of the induction variable to decide whether it may wrap.
|
||||
* tree-ssa-loop-ivopts.c (rewrite_use_compare): Emit the initialization
|
||||
of the bound before the loop.
|
||||
* simplify-rtx.c (simplify_binary_operation_1): Add two simplifications
|
||||
regarding AND.
|
||||
(simplify_plus_minus): Only fail if no simplification is possible.
|
||||
* loop-iv.c (simple_rhs_p): Consider reg + reg and reg << cst simple.
|
||||
|
||||
2008-11-20 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR c++/36631
|
||||
|
|
|
@ -1337,13 +1337,26 @@ simple_rhs_p (rtx rhs)
|
|||
case MINUS:
|
||||
op0 = XEXP (rhs, 0);
|
||||
op1 = XEXP (rhs, 1);
|
||||
/* Allow reg + const sets only. */
|
||||
if (REG_P (op0) && !HARD_REGISTER_P (op0) && CONSTANT_P (op1))
|
||||
return true;
|
||||
if (REG_P (op1) && !HARD_REGISTER_P (op1) && CONSTANT_P (op0))
|
||||
return true;
|
||||
/* Allow reg + const and reg + reg. */
|
||||
if (!(REG_P (op0) && !HARD_REGISTER_P (op0))
|
||||
&& !CONSTANT_P (op0))
|
||||
return false;
|
||||
if (!(REG_P (op1) && !HARD_REGISTER_P (op1))
|
||||
&& !CONSTANT_P (op1))
|
||||
return false;
|
||||
|
||||
return false;
|
||||
return true;
|
||||
|
||||
case ASHIFT:
|
||||
op0 = XEXP (rhs, 0);
|
||||
op1 = XEXP (rhs, 1);
|
||||
/* Allow reg << const. */
|
||||
if (!(REG_P (op0) && !HARD_REGISTER_P (op0)))
|
||||
return false;
|
||||
if (!CONSTANT_P (op1))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
|
|
|
@ -2304,12 +2304,19 @@ simplify_binary_operation_1 (enum rtx_code code, enum machine_mode mode,
|
|||
case AND:
|
||||
if (trueop1 == CONST0_RTX (mode) && ! side_effects_p (op0))
|
||||
return trueop1;
|
||||
/* If we are turning off bits already known off in OP0, we need
|
||||
not do an AND. */
|
||||
if (GET_CODE (trueop1) == CONST_INT
|
||||
&& GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
|
||||
&& (nonzero_bits (trueop0, mode) & ~INTVAL (trueop1)) == 0)
|
||||
return op0;
|
||||
&& GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
|
||||
{
|
||||
HOST_WIDE_INT nzop0 = nonzero_bits (trueop0, mode);
|
||||
HOST_WIDE_INT val1 = INTVAL (trueop1);
|
||||
/* If we are turning off bits already known off in OP0, we need
|
||||
not do an AND. */
|
||||
if ((nzop0 & ~val1) == 0)
|
||||
return op0;
|
||||
/* If we are clearing all the nonzero bits, the result is zero. */
|
||||
if ((val1 & nzop0) == 0 && !side_effects_p (op0))
|
||||
return CONST0_RTX (mode);
|
||||
}
|
||||
if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0)
|
||||
&& GET_MODE_CLASS (mode) != MODE_CC)
|
||||
return op0;
|
||||
|
@ -2391,7 +2398,9 @@ simplify_binary_operation_1 (enum rtx_code code, enum machine_mode mode,
|
|||
((A & N) + B) & M -> (A + B) & M
|
||||
Similarly if (N & M) == 0,
|
||||
((A | N) + B) & M -> (A + B) & M
|
||||
and for - instead of + and/or ^ instead of |. */
|
||||
and for - instead of + and/or ^ instead of |.
|
||||
Also, if (N & M) == 0, then
|
||||
(A +- N) & M -> A & M. */
|
||||
if (GET_CODE (trueop1) == CONST_INT
|
||||
&& GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
|
||||
&& ~INTVAL (trueop1)
|
||||
|
@ -2404,6 +2413,10 @@ simplify_binary_operation_1 (enum rtx_code code, enum machine_mode mode,
|
|||
pmop[0] = XEXP (op0, 0);
|
||||
pmop[1] = XEXP (op0, 1);
|
||||
|
||||
if (GET_CODE (pmop[1]) == CONST_INT
|
||||
&& (INTVAL (pmop[1]) & INTVAL (trueop1)) == 0)
|
||||
return simplify_gen_binary (AND, mode, pmop[0], op1);
|
||||
|
||||
for (which = 0; which < 2; which++)
|
||||
{
|
||||
tem = pmop[which];
|
||||
|
@ -3591,10 +3604,6 @@ simplify_plus_minus (enum rtx_code code, enum machine_mode mode, rtx op0,
|
|||
ops[j + 1] = save;
|
||||
}
|
||||
|
||||
/* This is only useful the first time through. */
|
||||
if (!canonicalized)
|
||||
return NULL_RTX;
|
||||
|
||||
changed = 0;
|
||||
for (i = n_ops - 1; i > 0; i--)
|
||||
for (j = i - 1; j >= 0; j--)
|
||||
|
@ -3650,10 +3659,15 @@ simplify_plus_minus (enum rtx_code code, enum machine_mode mode, rtx op0,
|
|||
ops[i].neg = lneg;
|
||||
ops[j].op = NULL_RTX;
|
||||
changed = 1;
|
||||
canonicalized = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If nothing changed, fail. */
|
||||
if (!canonicalized)
|
||||
return NULL_RTX;
|
||||
|
||||
/* Pack all the operands to the lower-numbered entries. */
|
||||
for (i = 0, j = 0; j < n_ops; j++)
|
||||
if (ops[j].op)
|
||||
|
|
|
@ -5323,11 +5323,15 @@ rewrite_use_compare (struct ivopts_data *data,
|
|||
{
|
||||
tree var = var_at_stmt (data->current_loop, cand, use->stmt);
|
||||
tree var_type = TREE_TYPE (var);
|
||||
gimple_seq stmts;
|
||||
|
||||
compare = iv_elimination_compare (data, use);
|
||||
bound = unshare_expr (fold_convert (var_type, bound));
|
||||
op = force_gimple_operand_gsi (&bsi, bound, true, NULL_TREE,
|
||||
true, GSI_SAME_STMT);
|
||||
op = force_gimple_operand (bound, &stmts, true, NULL_TREE);
|
||||
if (stmts)
|
||||
gsi_insert_seq_on_edge_immediate (
|
||||
loop_preheader_edge (data->current_loop),
|
||||
stmts);
|
||||
|
||||
gimple_cond_set_lhs (use->stmt, var);
|
||||
gimple_cond_set_code (use->stmt, compare);
|
||||
|
|
|
@ -3053,7 +3053,7 @@ scev_probably_wraps_p (tree base, tree step,
|
|||
|
||||
/* If we can use the fact that signed and pointer arithmetics does not
|
||||
wrap, we are done. */
|
||||
if (use_overflow_semantics && nowrap_type_p (type))
|
||||
if (use_overflow_semantics && nowrap_type_p (TREE_TYPE (base)))
|
||||
return false;
|
||||
|
||||
/* To be able to use estimates on number of iterations of the loop,
|
||||
|
|
Loading…
Reference in New Issue