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:
parent
a1b01d3403
commit
106d07f8d2
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue