tree-ssa-loop-niter.c (number_of_iterations_lt_to_ne): Clean up by removing computation of may_be_zero.

* tree-ssa-loop-niter.c (number_of_iterations_lt_to_ne): Clean up
	by removing computation of may_be_zero.

From-SVN: r238585
This commit is contained in:
Bin Cheng 2016-07-21 10:44:33 +00:00 committed by Bin Cheng
parent a1b01d3403
commit 106d07f8d2
2 changed files with 33 additions and 77 deletions

View File

@ -1,3 +1,8 @@
2016-07-21 Bin Cheng <bin.cheng@arm.com>
* tree-ssa-loop-niter.c (number_of_iterations_lt_to_ne): Clean up
by removing computation of may_be_zero.
2016-07-21 Jakub Jelinek <jakub@redhat.com> 2016-07-21 Jakub Jelinek <jakub@redhat.com>
* tree-object-size.c (unknown): Use HOST_WIDE_INT_M1U instead of -1. * tree-object-size.c (unknown): Use HOST_WIDE_INT_M1U instead of -1.

View File

@ -1072,12 +1072,8 @@ number_of_iterations_lt_to_ne (tree type, affine_iv *iv0, affine_iv *iv1,
tree niter_type = TREE_TYPE (step); tree niter_type = TREE_TYPE (step);
tree mod = fold_build2 (FLOOR_MOD_EXPR, niter_type, *delta, step); tree mod = fold_build2 (FLOOR_MOD_EXPR, niter_type, *delta, step);
tree tmod; tree tmod;
mpz_t mmod; tree assumption = boolean_true_node, bound;
tree assumption = boolean_true_node, bound, noloop; tree type1 = (POINTER_TYPE_P (type)) ? sizetype : type;
bool ret = false, fv_comp_no_overflow;
tree type1 = type;
if (POINTER_TYPE_P (type))
type1 = sizetype;
if (TREE_CODE (mod) != INTEGER_CST) if (TREE_CODE (mod) != INTEGER_CST)
return false; return false;
@ -1085,96 +1081,51 @@ number_of_iterations_lt_to_ne (tree type, affine_iv *iv0, affine_iv *iv1,
mod = fold_build2 (MINUS_EXPR, niter_type, step, mod); mod = fold_build2 (MINUS_EXPR, niter_type, step, mod);
tmod = fold_convert (type1, mod); tmod = fold_convert (type1, mod);
mpz_init (mmod);
wi::to_mpz (mod, mmod, UNSIGNED);
mpz_neg (mmod, mmod);
/* If the induction variable does not overflow and the exit is taken, /* If the induction variable does not overflow and the exit is taken,
then the computation of the final value does not overflow. This is then the computation of the final value does not overflow. There
also obviously the case if the new final value is equal to the are three cases:
current one. Finally, we postulate this for pointer type variables, 1) The case if the new final value is equal to the current one.
as the code cannot rely on the object to that the pointer points being 2) Induction varaible has pointer type, as the code cannot rely
placed at the end of the address space (and more pragmatically, on the object to that the pointer points being placed at the
TYPE_{MIN,MAX}_VALUE is not defined for pointers). */ end of the address space (and more pragmatically,
if (integer_zerop (mod) || POINTER_TYPE_P (type)) TYPE_{MIN,MAX}_VALUE is not defined for pointers).
fv_comp_no_overflow = true; 3) EXIT_MUST_BE_TAKEN is true, note it implies that the induction
else if (!exit_must_be_taken) variable does not overflow. */
fv_comp_no_overflow = false; if (!integer_zerop (mod) && !POINTER_TYPE_P (type) && !exit_must_be_taken)
else {
fv_comp_no_overflow =
(iv0->no_overflow && integer_nonzerop (iv0->step))
|| (iv1->no_overflow && integer_nonzerop (iv1->step));
if (integer_nonzerop (iv0->step)) if (integer_nonzerop (iv0->step))
{ {
/* The final value of the iv is iv1->base + MOD, assuming that this /* The final value of the iv is iv1->base + MOD, assuming
computation does not overflow, and that that this computation does not overflow, and that
iv0->base <= iv1->base + MOD. */ iv0->base <= iv1->base + MOD. */
if (!fv_comp_no_overflow)
{
bound = fold_build2 (MINUS_EXPR, type1, bound = fold_build2 (MINUS_EXPR, type1,
TYPE_MAX_VALUE (type1), tmod); TYPE_MAX_VALUE (type1), tmod);
assumption = fold_build2 (LE_EXPR, boolean_type_node, assumption = fold_build2 (LE_EXPR, boolean_type_node,
iv1->base, bound); iv1->base, bound);
if (integer_zerop (assumption))
goto end;
}
if (mpz_cmp (mmod, bnds->below) < 0)
noloop = boolean_false_node;
else if (POINTER_TYPE_P (type))
noloop = fold_build2 (GT_EXPR, boolean_type_node,
iv0->base,
fold_build_pointer_plus (iv1->base, tmod));
else
noloop = fold_build2 (GT_EXPR, boolean_type_node,
iv0->base,
fold_build2 (PLUS_EXPR, type1,
iv1->base, tmod));
} }
else else
{ {
/* The final value of the iv is iv0->base - MOD, assuming that this /* The final value of the iv is iv0->base - MOD, assuming
computation does not overflow, and that that this computation does not overflow, and that
iv0->base - MOD <= iv1->base. */ iv0->base - MOD <= iv1->base. */
if (!fv_comp_no_overflow)
{
bound = fold_build2 (PLUS_EXPR, type1, bound = fold_build2 (PLUS_EXPR, type1,
TYPE_MIN_VALUE (type1), tmod); TYPE_MIN_VALUE (type1), tmod);
assumption = fold_build2 (GE_EXPR, boolean_type_node, assumption = fold_build2 (GE_EXPR, boolean_type_node,
iv0->base, bound); iv0->base, bound);
if (integer_zerop (assumption))
goto end;
} }
if (mpz_cmp (mmod, bnds->below) < 0) if (integer_zerop (assumption))
noloop = boolean_false_node; return false;
else if (POINTER_TYPE_P (type)) else if (!integer_nonzerop (assumption))
noloop = fold_build2 (GT_EXPR, boolean_type_node, niter->assumptions = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
fold_build_pointer_plus (iv0->base, niter->assumptions, assumption);
fold_build1 (NEGATE_EXPR,
type1, tmod)),
iv1->base);
else
noloop = fold_build2 (GT_EXPR, boolean_type_node,
fold_build2 (MINUS_EXPR, type1,
iv0->base, tmod),
iv1->base);
} }
if (!integer_nonzerop (assumption)) /* Since we are transforming LT to NE and DELTA is constant, there
niter->assumptions = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, is no need to compute may_be_zero because this loop must roll. */
niter->assumptions,
assumption);
if (!integer_zerop (noloop))
niter->may_be_zero = fold_build2 (TRUTH_OR_EXPR, boolean_type_node,
niter->may_be_zero,
noloop);
bounds_add (bnds, wi::to_widest (mod), type); bounds_add (bnds, wi::to_widest (mod), type);
*delta = fold_build2 (PLUS_EXPR, niter_type, *delta, mod); *delta = fold_build2 (PLUS_EXPR, niter_type, *delta, mod);
return true;
ret = true;
end:
mpz_clear (mmod);
return ret;
} }
/* Add assertions to NITER that ensure that the control variable of the loop /* Add assertions to NITER that ensure that the control variable of the loop