tree-chrec.c (chrec_fold_plus_poly_poly, [...]): Use fold_convert or build_int_cst_type instead od fonvert.

* tree-chrec.c (chrec_fold_plus_poly_poly, chrec_fold_plus_1,
	chrec_fold_multiply): Use fold_convert or build_int_cst_type instead
	od fonvert.
	* tree-scalar-evolution.c (compute_overall_effect_of_inner_loop,
	add_to_evolution, set_nb_iterations_in_loop, follow_ssa_edge_in_rhs,
	follow_ssa_edge_in_rhs): Ditto.
	* tree-ssa-loop-ivopts.c (struct iv): Add base_object field.
	(dump_iv): Dump base_object.
	(dump_use, dump_cand): Use dump_iv.
	(determine_base_object): New function.
	(alloc_iv): Initialize base_object field.
	(record_use): Clear the ssa_name field of iv.
	(get_computation_cost_at): Do not use difference of addresses of
	two different objects.
	(may_eliminate_iv): Do not require the loop to have just single exit.
	* tree-ssa-loop-niter.c (zero_p): Do not check for overflows.
	(nonzero_p): New function.
	(inverse, number_of_iterations_cond, simplify_using_outer_evolutions,
	tree_simplify_using_condition, simplify_using_initial_conditions,
	loop_niter_by_eval, find_loop_niter_by_eval,
	estimate_numbers_of_iterations_loop, compare_trees,
	upper_bound_in_type, lower_bound_in_type,
	can_count_iv_in_wider_type_bound): Use buildN instead of build.  Use
	fold_convert or build_int_cst_type instead of convert.  Use (non)zero_p
	instead of integer_(non)zerop.

From-SVN: r88388
This commit is contained in:
Zdenek Dvorak 2004-10-01 11:06:06 +02:00 committed by Zdenek Dvorak
parent 5496b36fc2
commit e6845c2382
5 changed files with 266 additions and 179 deletions

View File

@ -1,3 +1,31 @@
2004-10-01 Zdenek Dvorak <dvorakz@suse.cz>
* tree-chrec.c (chrec_fold_plus_poly_poly, chrec_fold_plus_1,
chrec_fold_multiply): Use fold_convert or build_int_cst_type instead
od fonvert.
* tree-scalar-evolution.c (compute_overall_effect_of_inner_loop,
add_to_evolution, set_nb_iterations_in_loop, follow_ssa_edge_in_rhs,
follow_ssa_edge_in_rhs): Ditto.
* tree-ssa-loop-ivopts.c (struct iv): Add base_object field.
(dump_iv): Dump base_object.
(dump_use, dump_cand): Use dump_iv.
(determine_base_object): New function.
(alloc_iv): Initialize base_object field.
(record_use): Clear the ssa_name field of iv.
(get_computation_cost_at): Do not use difference of addresses of
two different objects.
(may_eliminate_iv): Do not require the loop to have just single exit.
* tree-ssa-loop-niter.c (zero_p): Do not check for overflows.
(nonzero_p): New function.
(inverse, number_of_iterations_cond, simplify_using_outer_evolutions,
tree_simplify_using_condition, simplify_using_initial_conditions,
loop_niter_by_eval, find_loop_niter_by_eval,
estimate_numbers_of_iterations_loop, compare_trees,
upper_bound_in_type, lower_bound_in_type,
can_count_iv_in_wider_type_bound): Use buildN instead of build. Use
fold_convert or build_int_cst_type instead of convert. Use (non)zero_p
instead of integer_(non)zerop.
2004-10-01 Jakub Jelinek <jakub@redhat.com> 2004-10-01 Jakub Jelinek <jakub@redhat.com>
Revert Revert

View File

@ -117,7 +117,7 @@ chrec_fold_plus_poly_poly (enum tree_code code,
(CHREC_VARIABLE (poly1), (CHREC_VARIABLE (poly1),
chrec_fold_minus (type, poly0, CHREC_LEFT (poly1)), chrec_fold_minus (type, poly0, CHREC_LEFT (poly1)),
chrec_fold_multiply (type, CHREC_RIGHT (poly1), chrec_fold_multiply (type, CHREC_RIGHT (poly1),
convert (type, integer_minus_one_node))); build_int_cst_type (type, -1)));
} }
if (CHREC_VARIABLE (poly0) > CHREC_VARIABLE (poly1)) if (CHREC_VARIABLE (poly0) > CHREC_VARIABLE (poly1))
@ -282,9 +282,8 @@ chrec_fold_plus_1 (enum tree_code code,
return build_polynomial_chrec return build_polynomial_chrec
(CHREC_VARIABLE (op1), (CHREC_VARIABLE (op1),
chrec_fold_minus (type, op0, CHREC_LEFT (op1)), chrec_fold_minus (type, op0, CHREC_LEFT (op1)),
chrec_fold_multiply (type, CHREC_RIGHT (op1), chrec_fold_multiply (type, CHREC_RIGHT (op1),
convert (type, build_int_cst_type (type, -1)));
integer_minus_one_node)));
default: default:
if (tree_contains_chrecs (op0) if (tree_contains_chrecs (op0)
@ -347,7 +346,7 @@ chrec_fold_multiply (tree type,
if (integer_onep (op1)) if (integer_onep (op1))
return op0; return op0;
if (integer_zerop (op1)) if (integer_zerop (op1))
return convert (type, integer_zero_node); return build_int_cst_type (type, 0);
return build_polynomial_chrec return build_polynomial_chrec
(CHREC_VARIABLE (op0), (CHREC_VARIABLE (op0),
@ -360,7 +359,7 @@ chrec_fold_multiply (tree type,
return op1; return op1;
if (integer_zerop (op0)) if (integer_zerop (op0))
return convert (type, integer_zero_node); return build_int_cst_type (type, 0);
switch (TREE_CODE (op1)) switch (TREE_CODE (op1))
{ {
@ -374,7 +373,7 @@ chrec_fold_multiply (tree type,
if (integer_onep (op1)) if (integer_onep (op1))
return op0; return op0;
if (integer_zerop (op1)) if (integer_zerop (op1))
return convert (type, integer_zero_node); return build_int_cst_type (type, 0);
return fold (build (MULT_EXPR, type, op0, op1)); return fold (build (MULT_EXPR, type, op0, op1));
} }
} }

View File

@ -506,9 +506,8 @@ compute_overall_effect_of_inner_loop (struct loop *loop, tree evolution_fn)
/* Number of iterations is off by one (the ssa name we /* Number of iterations is off by one (the ssa name we
analyze must be defined before the exit). */ analyze must be defined before the exit). */
nb_iter = chrec_fold_minus (chrec_type (nb_iter), nb_iter = chrec_fold_minus (chrec_type (nb_iter),
nb_iter, nb_iter,
fold_convert (chrec_type (nb_iter), build_int_cst_type (chrec_type (nb_iter), 1));
integer_one_node));
/* evolution_fn is the evolution function in LOOP. Get /* evolution_fn is the evolution function in LOOP. Get
its value in the nb_iter-th iteration. */ its value in the nb_iter-th iteration. */
@ -896,7 +895,7 @@ add_to_evolution (unsigned loop_nb,
if (code == MINUS_EXPR) if (code == MINUS_EXPR)
to_add = chrec_fold_multiply (type, to_add, to_add = chrec_fold_multiply (type, to_add,
fold_convert (type, integer_minus_one_node)); build_int_cst_type (type, -1));
res = add_to_evolution_1 (loop_nb, chrec_before, to_add); res = add_to_evolution_1 (loop_nb, chrec_before, to_add);
@ -916,7 +915,9 @@ static inline tree
set_nb_iterations_in_loop (struct loop *loop, set_nb_iterations_in_loop (struct loop *loop,
tree res) tree res)
{ {
res = chrec_fold_plus (chrec_type (res), res, integer_one_node); res = chrec_fold_plus (chrec_type (res), res,
build_int_cst_type (chrec_type (res), 1));
/* FIXME HWI: However we want to store one iteration less than the /* FIXME HWI: However we want to store one iteration less than the
count of the loop in order to be compatible with the other count of the loop in order to be compatible with the other
nb_iter computations in loop-iv. This also allows the nb_iter computations in loop-iv. This also allows the
@ -1209,8 +1210,7 @@ follow_ssa_edge_in_rhs (struct loop *loop,
(loop->num, (loop->num,
chrec_fold_multiply (type_rhs, chrec_fold_multiply (type_rhs,
*evolution_of_loop, *evolution_of_loop,
fold_convert (type_rhs, build_int_cst_type (type_rhs, -1)),
integer_minus_one_node)),
PLUS_EXPR, rhs0); PLUS_EXPR, rhs0);
} }
} }
@ -1241,7 +1241,7 @@ follow_ssa_edge_in_rhs (struct loop *loop,
(loop->num, (loop->num,
chrec_fold_multiply (type_rhs, chrec_fold_multiply (type_rhs,
*evolution_of_loop, *evolution_of_loop,
fold_convert (type_rhs, integer_minus_one_node)), build_int_cst_type (type_rhs, -1)),
PLUS_EXPR, rhs0); PLUS_EXPR, rhs0);
} }

View File

@ -104,6 +104,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
struct iv struct iv
{ {
tree base; /* Initial value of the iv. */ tree base; /* Initial value of the iv. */
tree base_object; /* A memory object to that the induction variable points. */
tree step; /* Step of the iv (constant only). */ tree step; /* Step of the iv (constant only). */
tree ssa_name; /* The ssa name with the value. */ tree ssa_name; /* The ssa name with the value. */
bool biv_p; /* Is it a biv? */ bool biv_p; /* Is it a biv? */
@ -301,9 +302,12 @@ extern void dump_iv (FILE *, struct iv *);
void void
dump_iv (FILE *file, struct iv *iv) dump_iv (FILE *file, struct iv *iv)
{ {
fprintf (file, "ssa name "); if (iv->ssa_name)
print_generic_expr (file, iv->ssa_name, TDF_SLIM); {
fprintf (file, "\n"); fprintf (file, "ssa name ");
print_generic_expr (file, iv->ssa_name, TDF_SLIM);
fprintf (file, "\n");
}
fprintf (file, " type "); fprintf (file, " type ");
print_generic_expr (file, TREE_TYPE (iv->base), TDF_SLIM); print_generic_expr (file, TREE_TYPE (iv->base), TDF_SLIM);
@ -326,6 +330,13 @@ dump_iv (FILE *file, struct iv *iv)
fprintf (file, "\n"); fprintf (file, "\n");
} }
if (iv->base_object)
{
fprintf (file, " base object ");
print_generic_expr (file, iv->base_object, TDF_SLIM);
fprintf (file, "\n");
}
if (iv->biv_p) if (iv->biv_p)
fprintf (file, " is a biv\n"); fprintf (file, " is a biv\n");
} }
@ -336,8 +347,6 @@ extern void dump_use (FILE *, struct iv_use *);
void void
dump_use (FILE *file, struct iv_use *use) dump_use (FILE *file, struct iv_use *use)
{ {
struct iv *iv = use->iv;
fprintf (file, "use %d\n", use->id); fprintf (file, "use %d\n", use->id);
switch (use->type) switch (use->type)
@ -371,26 +380,7 @@ dump_use (FILE *file, struct iv_use *use)
print_generic_expr (file, *use->op_p, TDF_SLIM); print_generic_expr (file, *use->op_p, TDF_SLIM);
fprintf (file, "\n"); fprintf (file, "\n");
fprintf (file, " type "); dump_iv (file, use->iv);
print_generic_expr (file, TREE_TYPE (iv->base), TDF_SLIM);
fprintf (file, "\n");
if (iv->step)
{
fprintf (file, " base ");
print_generic_expr (file, iv->base, TDF_SLIM);
fprintf (file, "\n");
fprintf (file, " step ");
print_generic_expr (file, iv->step, TDF_SLIM);
fprintf (file, "\n");
}
else
{
fprintf (file, " invariant ");
print_generic_expr (file, iv->base, TDF_SLIM);
fprintf (file, "\n");
}
fprintf (file, " related candidates "); fprintf (file, " related candidates ");
dump_bitmap (file, use->related_cands); dump_bitmap (file, use->related_cands);
@ -446,26 +436,7 @@ dump_cand (FILE *file, struct iv_cand *cand)
break; break;
} }
fprintf (file, " type "); dump_iv (file, iv);
print_generic_expr (file, TREE_TYPE (iv->base), TDF_SLIM);
fprintf (file, "\n");
if (iv->step)
{
fprintf (file, " base ");
print_generic_expr (file, iv->base, TDF_SLIM);
fprintf (file, "\n");
fprintf (file, " step ");
print_generic_expr (file, iv->step, TDF_SLIM);
fprintf (file, "\n");
}
else
{
fprintf (file, " invariant ");
print_generic_expr (file, iv->base, TDF_SLIM);
fprintf (file, "\n");
}
} }
/* Returns the info for ssa version VER. */ /* Returns the info for ssa version VER. */
@ -626,6 +597,52 @@ tree_ssa_iv_optimize_init (struct loops *loops, struct ivopts_data *data)
VARRAY_GENERIC_PTR_NOGC_INIT (decl_rtl_to_reset, 20, "decl_rtl_to_reset"); VARRAY_GENERIC_PTR_NOGC_INIT (decl_rtl_to_reset, 20, "decl_rtl_to_reset");
} }
/* Returns a memory object to that EXPR points. In case we are able to
determine that it does not point to any such object, NULL is returned. */
static tree
determine_base_object (tree expr)
{
enum tree_code code = TREE_CODE (expr);
tree base, obj, op0, op1;
if (!POINTER_TYPE_P (TREE_TYPE (expr)))
return NULL_TREE;
switch (code)
{
case INTEGER_CST:
return NULL_TREE;
case ADDR_EXPR:
obj = TREE_OPERAND (expr, 0);
base = get_base_address (obj);
if (!base)
return fold_convert (ptr_type_node, expr);
return fold (build1 (ADDR_EXPR, ptr_type_node, base));
case PLUS_EXPR:
case MINUS_EXPR:
op0 = determine_base_object (TREE_OPERAND (expr, 0));
op1 = determine_base_object (TREE_OPERAND (expr, 1));
if (!op1)
return op0;
if (!op0)
return (code == PLUS_EXPR
? op1
: fold (build1 (NEGATE_EXPR, ptr_type_node, op1)));
return fold (build (code, ptr_type_node, op0, op1));
default:
return fold_convert (ptr_type_node, expr);
}
}
/* Allocates an induction variable with given initial value BASE and step STEP /* Allocates an induction variable with given initial value BASE and step STEP
for loop LOOP. */ for loop LOOP. */
@ -638,6 +655,7 @@ alloc_iv (tree base, tree step)
step = NULL_TREE; step = NULL_TREE;
iv->base = base; iv->base = base;
iv->base_object = determine_base_object (base);
iv->step = step; iv->step = step;
iv->biv_p = false; iv->biv_p = false;
iv->have_use_for = false; iv->have_use_for = false;
@ -1001,6 +1019,10 @@ record_use (struct ivopts_data *data, tree *use_p, struct iv *iv,
use->op_p = use_p; use->op_p = use_p;
use->related_cands = BITMAP_XMALLOC (); use->related_cands = BITMAP_XMALLOC ();
/* To avoid showing ssa name in the dumps, if it was not reset by the
caller. */
iv->ssa_name = NULL_TREE;
if (dump_file && (dump_flags & TDF_DETAILS)) if (dump_file && (dump_flags & TDF_DETAILS))
dump_use (dump_file, use); dump_use (dump_file, use);
@ -2794,6 +2816,19 @@ get_computation_cost_at (struct ivopts_data *data,
return INFTY; return INFTY;
} }
if (address_p)
{
/* Do not try to express address of an object with computation based
on address of a different object. This may cause problems in rtl
level alias analysis (that does not expect this to be happening,
as this is illegal in C), and would be unlikely to be useful
anyway. */
if (use->iv->base_object
&& cand->iv->base_object
&& !operand_equal_p (use->iv->base_object, cand->iv->base_object, 0))
return INFTY;
}
if (!cst_and_fits_in_hwi (ustep) if (!cst_and_fits_in_hwi (ustep)
|| !cst_and_fits_in_hwi (cstep)) || !cst_and_fits_in_hwi (cstep))
return INFTY; return INFTY;
@ -2974,23 +3009,31 @@ may_eliminate_iv (struct loop *loop,
struct iv_use *use, struct iv_cand *cand, struct iv_use *use, struct iv_cand *cand,
enum tree_code *compare, tree *bound) enum tree_code *compare, tree *bound)
{ {
basic_block ex_bb;
edge exit; edge exit;
struct tree_niter_desc *niter, new_niter; struct tree_niter_desc niter, new_niter;
tree wider_type, type, base; tree wider_type, type, base;
/* For now just very primitive -- we work just for the single exit condition, /* For now works only for exits that dominate the loop latch. TODO -- extend
and are quite conservative about the possible overflows. TODO -- both of for other conditions inside loop body. */
these can be improved. */ ex_bb = bb_for_stmt (use->stmt);
exit = single_dom_exit (loop); if (use->stmt != last_stmt (ex_bb)
if (!exit) || TREE_CODE (use->stmt) != COND_EXPR)
return false; return false;
if (use->stmt != last_stmt (exit->src)) if (!dominated_by_p (CDI_DOMINATORS, loop->latch, ex_bb))
return false; return false;
niter = &loop_data (loop)->niter; exit = EDGE_SUCC (ex_bb, 0);
if (!niter->niter if (flow_bb_inside_loop_p (loop, exit->dest))
|| !integer_nonzerop (niter->assumptions) exit = EDGE_SUCC (ex_bb, 1);
|| !integer_zerop (niter->may_be_zero)) if (flow_bb_inside_loop_p (loop, exit->dest))
return false;
niter.niter = NULL_TREE;
number_of_iterations_exit (loop, exit, &niter);
if (!niter.niter
|| !integer_nonzerop (niter.assumptions)
|| !integer_zerop (niter.may_be_zero))
return false; return false;
if (exit->flags & EDGE_TRUE_VALUE) if (exit->flags & EDGE_TRUE_VALUE)
@ -2998,7 +3041,7 @@ may_eliminate_iv (struct loop *loop,
else else
*compare = NE_EXPR; *compare = NE_EXPR;
*bound = cand_value_at (loop, cand, use->stmt, niter->niter); *bound = cand_value_at (loop, cand, use->stmt, niter.niter);
/* Let us check there is not some problem with overflows, by checking that /* Let us check there is not some problem with overflows, by checking that
the number of iterations is unchanged. */ the number of iterations is unchanged. */
@ -3017,9 +3060,9 @@ may_eliminate_iv (struct loop *loop,
return false; return false;
wider_type = TREE_TYPE (new_niter.niter); wider_type = TREE_TYPE (new_niter.niter);
if (TYPE_PRECISION (wider_type) < TYPE_PRECISION (TREE_TYPE (niter->niter))) if (TYPE_PRECISION (wider_type) < TYPE_PRECISION (TREE_TYPE (niter.niter)))
wider_type = TREE_TYPE (niter->niter); wider_type = TREE_TYPE (niter.niter);
if (!operand_equal_p (fold_convert (wider_type, niter->niter), if (!operand_equal_p (fold_convert (wider_type, niter.niter),
fold_convert (wider_type, new_niter.niter), 0)) fold_convert (wider_type, new_niter.niter), 0))
return false; return false;

View File

@ -52,7 +52,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
*/ */
/* Returns true if ARG is either NULL_TREE or constant zero. */ /* Returns true if ARG is either NULL_TREE or constant zero. Unlike
integer_zerop, it does not care about overflow flags. */
bool bool
zero_p (tree arg) zero_p (tree arg)
@ -60,7 +61,25 @@ zero_p (tree arg)
if (!arg) if (!arg)
return true; return true;
return integer_zerop (arg); if (TREE_CODE (arg) != INTEGER_CST)
return false;
return (TREE_INT_CST_LOW (arg) == 0 && TREE_INT_CST_HIGH (arg) == 0);
}
/* Returns true if ARG a nonzero constant. Unlike integer_nonzerop, it does
not care about overflow flags. */
static bool
nonzero_p (tree arg)
{
if (!arg)
return false;
if (TREE_CODE (arg) != INTEGER_CST)
return false;
return (TREE_INT_CST_LOW (arg) != 0 || TREE_INT_CST_HIGH (arg) != 0);
} }
/* Returns inverse of X modulo 2^s, where MASK = 2^s-1. */ /* Returns inverse of X modulo 2^s, where MASK = 2^s-1. */
@ -70,9 +89,9 @@ inverse (tree x, tree mask)
{ {
tree type = TREE_TYPE (x); tree type = TREE_TYPE (x);
tree ctr = EXEC_BINARY (RSHIFT_EXPR, type, mask, integer_one_node); tree ctr = EXEC_BINARY (RSHIFT_EXPR, type, mask, integer_one_node);
tree rslt = convert (type, integer_one_node); tree rslt = build_int_cst_type (type, 1);
while (integer_nonzerop (ctr)) while (nonzero_p (ctr))
{ {
rslt = EXEC_BINARY (MULT_EXPR, type, rslt, x); rslt = EXEC_BINARY (MULT_EXPR, type, rslt, x);
rslt = EXEC_BINARY (BIT_AND_EXPR, type, rslt, mask); rslt = EXEC_BINARY (BIT_AND_EXPR, type, rslt, mask);
@ -180,24 +199,24 @@ number_of_iterations_cond (tree type, tree base0, tree step0,
if (zero_p (step0)) if (zero_p (step0))
{ {
if (mmax) if (mmax)
assumption = fold (build (EQ_EXPR, boolean_type_node, base0, mmax)); assumption = fold (build2 (EQ_EXPR, boolean_type_node, base0, mmax));
else else
assumption = boolean_false_node; assumption = boolean_false_node;
if (integer_nonzerop (assumption)) if (nonzero_p (assumption))
goto zero_iter; goto zero_iter;
base0 = fold (build (PLUS_EXPR, type, base0, base0 = fold (build2 (PLUS_EXPR, type, base0,
convert (type, integer_one_node))); build_int_cst_type (type, 1)));
} }
else else
{ {
if (mmin) if (mmin)
assumption = fold (build (EQ_EXPR, boolean_type_node, base1, mmin)); assumption = fold (build2 (EQ_EXPR, boolean_type_node, base1, mmin));
else else
assumption = boolean_false_node; assumption = boolean_false_node;
if (integer_nonzerop (assumption)) if (nonzero_p (assumption))
goto zero_iter; goto zero_iter;
base1 = fold (build (MINUS_EXPR, type, base1, base1 = fold (build2 (MINUS_EXPR, type, base1,
convert (type, integer_one_node))); build_int_cst_type (type, 1)));
} }
noloop_assumptions = assumption; noloop_assumptions = assumption;
code = LE_EXPR; code = LE_EXPR;
@ -232,14 +251,14 @@ number_of_iterations_cond (tree type, tree base0, tree step0,
step = EXEC_UNARY (NEGATE_EXPR, type, step1); step = EXEC_UNARY (NEGATE_EXPR, type, step1);
else else
step = step0; step = step0;
delta = build (MINUS_EXPR, type, base1, base0); delta = build2 (MINUS_EXPR, type, base1, base0);
delta = fold (build (FLOOR_MOD_EXPR, type, delta, step)); delta = fold (build2 (FLOOR_MOD_EXPR, type, delta, step));
may_xform = boolean_false_node; may_xform = boolean_false_node;
if (TREE_CODE (delta) == INTEGER_CST) if (TREE_CODE (delta) == INTEGER_CST)
{ {
tmp = EXEC_BINARY (MINUS_EXPR, type, step, tmp = EXEC_BINARY (MINUS_EXPR, type, step,
convert (type, integer_one_node)); build_int_cst_type (type, 1));
if (was_sharp if (was_sharp
&& operand_equal_p (delta, tmp, 0)) && operand_equal_p (delta, tmp, 0))
{ {
@ -262,7 +281,7 @@ number_of_iterations_cond (tree type, tree base0, tree step0,
{ {
bound = EXEC_BINARY (PLUS_EXPR, type, mmin, step); bound = EXEC_BINARY (PLUS_EXPR, type, mmin, step);
bound = EXEC_BINARY (MINUS_EXPR, type, bound, delta); bound = EXEC_BINARY (MINUS_EXPR, type, bound, delta);
may_xform = fold (build (LE_EXPR, boolean_type_node, may_xform = fold (build2 (LE_EXPR, boolean_type_node,
bound, base0)); bound, base0));
} }
} }
@ -274,33 +293,33 @@ number_of_iterations_cond (tree type, tree base0, tree step0,
{ {
bound = EXEC_BINARY (MINUS_EXPR, type, mmax, step); bound = EXEC_BINARY (MINUS_EXPR, type, mmax, step);
bound = EXEC_BINARY (PLUS_EXPR, type, bound, delta); bound = EXEC_BINARY (PLUS_EXPR, type, bound, delta);
may_xform = fold (build (LE_EXPR, boolean_type_node, may_xform = fold (build2 (LE_EXPR, boolean_type_node,
base1, bound)); base1, bound));
} }
} }
} }
if (!integer_zerop (may_xform)) if (!zero_p (may_xform))
{ {
/* We perform the transformation always provided that it is not /* We perform the transformation always provided that it is not
completely senseless. This is OK, as we would need this assumption completely senseless. This is OK, as we would need this assumption
to determine the number of iterations anyway. */ to determine the number of iterations anyway. */
if (!integer_nonzerop (may_xform)) if (!nonzero_p (may_xform))
assumptions = may_xform; assumptions = may_xform;
if (zero_p (step0)) if (zero_p (step0))
{ {
base0 = build (PLUS_EXPR, type, base0, delta); base0 = build2 (PLUS_EXPR, type, base0, delta);
base0 = fold (build (MINUS_EXPR, type, base0, step)); base0 = fold (build2 (MINUS_EXPR, type, base0, step));
} }
else else
{ {
base1 = build (MINUS_EXPR, type, base1, delta); base1 = build2 (MINUS_EXPR, type, base1, delta);
base1 = fold (build (PLUS_EXPR, type, base1, step)); base1 = fold (build2 (PLUS_EXPR, type, base1, step));
} }
assumption = fold (build (GT_EXPR, boolean_type_node, base0, base1)); assumption = fold (build2 (GT_EXPR, boolean_type_node, base0, base1));
noloop_assumptions = fold (build (TRUTH_OR_EXPR, boolean_type_node, noloop_assumptions = fold (build2 (TRUTH_OR_EXPR, boolean_type_node,
noloop_assumptions, assumption)); noloop_assumptions, assumption));
code = NE_EXPR; code = NE_EXPR;
} }
@ -316,39 +335,39 @@ number_of_iterations_cond (tree type, tree base0, tree step0,
makes us able to do more involved computations of number of iterations makes us able to do more involved computations of number of iterations
than in other cases. First transform the condition into shape than in other cases. First transform the condition into shape
s * i <> c, with s positive. */ s * i <> c, with s positive. */
base1 = fold (build (MINUS_EXPR, type, base1, base0)); base1 = fold (build2 (MINUS_EXPR, type, base1, base0));
base0 = NULL_TREE; base0 = NULL_TREE;
if (!zero_p (step1)) if (!zero_p (step1))
step0 = EXEC_UNARY (NEGATE_EXPR, type, step1); step0 = EXEC_UNARY (NEGATE_EXPR, type, step1);
step1 = NULL_TREE; step1 = NULL_TREE;
if (!tree_expr_nonnegative_p (convert (signed_niter_type, step0))) if (!tree_expr_nonnegative_p (fold_convert (signed_niter_type, step0)))
{ {
step0 = EXEC_UNARY (NEGATE_EXPR, type, step0); step0 = EXEC_UNARY (NEGATE_EXPR, type, step0);
base1 = fold (build1 (NEGATE_EXPR, type, base1)); base1 = fold (build1 (NEGATE_EXPR, type, base1));
} }
base1 = convert (niter_type, base1); base1 = fold_convert (niter_type, base1);
step0 = convert (niter_type, step0); step0 = fold_convert (niter_type, step0);
/* Let nsd (s, size of mode) = d. If d does not divide c, the loop /* Let nsd (s, size of mode) = d. If d does not divide c, the loop
is infinite. Otherwise, the number of iterations is is infinite. Otherwise, the number of iterations is
(inverse(s/d) * (c/d)) mod (size of mode/d). */ (inverse(s/d) * (c/d)) mod (size of mode/d). */
s = step0; s = step0;
d = integer_one_node; d = integer_one_node;
bound = convert (niter_type, build_int_cst (NULL_TREE, -1)); bound = build_int_cst (niter_type, -1);
while (1) while (1)
{ {
tmp = EXEC_BINARY (BIT_AND_EXPR, niter_type, s, tmp = EXEC_BINARY (BIT_AND_EXPR, niter_type, s,
convert (niter_type, integer_one_node)); build_int_cst (niter_type, 1));
if (integer_nonzerop (tmp)) if (nonzero_p (tmp))
break; break;
s = EXEC_BINARY (RSHIFT_EXPR, niter_type, s, s = EXEC_BINARY (RSHIFT_EXPR, niter_type, s,
convert (niter_type, integer_one_node)); build_int_cst (niter_type, 1));
d = EXEC_BINARY (LSHIFT_EXPR, niter_type, d, d = EXEC_BINARY (LSHIFT_EXPR, niter_type, d,
convert (niter_type, integer_one_node)); build_int_cst (niter_type, 1));
bound = EXEC_BINARY (RSHIFT_EXPR, niter_type, bound, bound = EXEC_BINARY (RSHIFT_EXPR, niter_type, bound,
convert (niter_type, integer_one_node)); build_int_cst (niter_type, 1));
} }
assumption = fold (build2 (FLOOR_MOD_EXPR, niter_type, base1, d)); assumption = fold (build2 (FLOOR_MOD_EXPR, niter_type, base1, d));
@ -358,9 +377,9 @@ number_of_iterations_cond (tree type, tree base0, tree step0,
assumptions = fold (build2 (TRUTH_AND_EXPR, boolean_type_node, assumptions = fold (build2 (TRUTH_AND_EXPR, boolean_type_node,
assumptions, assumption)); assumptions, assumption));
tmp = fold (build (EXACT_DIV_EXPR, niter_type, base1, d)); tmp = fold (build2 (EXACT_DIV_EXPR, niter_type, base1, d));
tmp = fold (build (MULT_EXPR, niter_type, tmp, inverse (s, bound))); tmp = fold (build2 (MULT_EXPR, niter_type, tmp, inverse (s, bound)));
niter->niter = fold (build (BIT_AND_EXPR, niter_type, tmp, bound)); niter->niter = fold (build2 (BIT_AND_EXPR, niter_type, tmp, bound));
} }
else else
{ {
@ -375,18 +394,18 @@ number_of_iterations_cond (tree type, tree base0, tree step0,
if (mmax) if (mmax)
{ {
bound = EXEC_BINARY (MINUS_EXPR, type, mmax, step0); bound = EXEC_BINARY (MINUS_EXPR, type, mmax, step0);
assumption = fold (build (LE_EXPR, boolean_type_node, assumption = fold (build2 (LE_EXPR, boolean_type_node,
base1, bound)); base1, bound));
assumptions = fold (build (TRUTH_AND_EXPR, boolean_type_node, assumptions = fold (build2 (TRUTH_AND_EXPR, boolean_type_node,
assumptions, assumption)); assumptions, assumption));
} }
step = step0; step = step0;
tmp = fold (build (PLUS_EXPR, type, base1, step0)); tmp = fold (build2 (PLUS_EXPR, type, base1, step0));
assumption = fold (build (GT_EXPR, boolean_type_node, base0, tmp)); assumption = fold (build2 (GT_EXPR, boolean_type_node, base0, tmp));
delta = fold (build (PLUS_EXPR, type, base1, step)); delta = fold (build2 (PLUS_EXPR, type, base1, step));
delta = fold (build (MINUS_EXPR, type, delta, base0)); delta = fold (build2 (MINUS_EXPR, type, delta, base0));
delta = convert (niter_type, delta); delta = fold_convert (niter_type, delta);
} }
else else
{ {
@ -396,22 +415,22 @@ number_of_iterations_cond (tree type, tree base0, tree step0,
if (mmin) if (mmin)
{ {
bound = EXEC_BINARY (MINUS_EXPR, type, mmin, step1); bound = EXEC_BINARY (MINUS_EXPR, type, mmin, step1);
assumption = fold (build (LE_EXPR, boolean_type_node, assumption = fold (build2 (LE_EXPR, boolean_type_node,
bound, base0)); bound, base0));
assumptions = fold (build (TRUTH_AND_EXPR, boolean_type_node, assumptions = fold (build2 (TRUTH_AND_EXPR, boolean_type_node,
assumptions, assumption)); assumptions, assumption));
} }
step = fold (build1 (NEGATE_EXPR, type, step1)); step = fold (build1 (NEGATE_EXPR, type, step1));
tmp = fold (build (PLUS_EXPR, type, base0, step1)); tmp = fold (build2 (PLUS_EXPR, type, base0, step1));
assumption = fold (build (GT_EXPR, boolean_type_node, tmp, base1)); assumption = fold (build2 (GT_EXPR, boolean_type_node, tmp, base1));
delta = fold (build (MINUS_EXPR, type, base0, step)); delta = fold (build2 (MINUS_EXPR, type, base0, step));
delta = fold (build (MINUS_EXPR, type, base1, delta)); delta = fold (build2 (MINUS_EXPR, type, base1, delta));
delta = convert (niter_type, delta); delta = fold_convert (niter_type, delta);
} }
noloop_assumptions = fold (build (TRUTH_OR_EXPR, boolean_type_node, noloop_assumptions = fold (build2 (TRUTH_OR_EXPR, boolean_type_node,
noloop_assumptions, assumption)); noloop_assumptions, assumption));
delta = fold (build (FLOOR_DIV_EXPR, niter_type, delta, delta = fold (build2 (FLOOR_DIV_EXPR, niter_type, delta,
convert (niter_type, step))); fold_convert (niter_type, step)));
niter->niter = delta; niter->niter = delta;
} }
@ -422,7 +441,7 @@ number_of_iterations_cond (tree type, tree base0, tree step0,
zero_iter: zero_iter:
niter->assumptions = boolean_true_node; niter->assumptions = boolean_true_node;
niter->may_be_zero = boolean_true_node; niter->may_be_zero = boolean_true_node;
niter->niter = convert (type, integer_zero_node); niter->niter = build_int_cst_type (type, 0);
return; return;
} }
@ -466,9 +485,9 @@ simplify_using_outer_evolutions (struct loop *loop, tree expr)
if (changed) if (changed)
{ {
if (code == COND_EXPR) if (code == COND_EXPR)
expr = build (code, boolean_type_node, e0, e1, e2); expr = build3 (code, boolean_type_node, e0, e1, e2);
else else
expr = build (code, boolean_type_node, e0, e1); expr = build2 (code, boolean_type_node, e0, e1);
expr = fold (expr); expr = fold (expr);
} }
@ -521,9 +540,9 @@ tree_simplify_using_condition (tree cond, tree expr)
if (changed) if (changed)
{ {
if (code == COND_EXPR) if (code == COND_EXPR)
expr = build (code, boolean_type_node, e0, e1, e2); expr = build3 (code, boolean_type_node, e0, e1, e2);
else else
expr = build (code, boolean_type_node, e0, e1); expr = build2 (code, boolean_type_node, e0, e1);
expr = fold (expr); expr = fold (expr);
} }
@ -532,15 +551,15 @@ tree_simplify_using_condition (tree cond, tree expr)
/* Check whether COND ==> EXPR. */ /* Check whether COND ==> EXPR. */
notcond = invert_truthvalue (cond); notcond = invert_truthvalue (cond);
e = fold (build (TRUTH_OR_EXPR, boolean_type_node, e = fold (build2 (TRUTH_OR_EXPR, boolean_type_node,
notcond, expr)); notcond, expr));
if (integer_nonzerop (e)) if (nonzero_p (e))
return e; return e;
/* Check whether COND ==> not EXPR. */ /* Check whether COND ==> not EXPR. */
e = fold (build (TRUTH_AND_EXPR, boolean_type_node, e = fold (build2 (TRUTH_AND_EXPR, boolean_type_node,
cond, expr)); cond, expr));
if (integer_zerop (e)) if (zero_p (e))
return e; return e;
return expr; return expr;
@ -579,7 +598,7 @@ simplify_using_initial_conditions (struct loop *loop, tree expr,
exp = tree_simplify_using_condition (cond, expr); exp = tree_simplify_using_condition (cond, expr);
if (exp != expr) if (exp != expr)
*conds_used = fold (build (TRUTH_AND_EXPR, *conds_used = fold (build2 (TRUTH_AND_EXPR,
boolean_type_node, boolean_type_node,
*conds_used, *conds_used,
cond)); cond));
@ -861,8 +880,8 @@ loop_niter_by_eval (struct loop *loop, edge exit)
for (j = 0; j < 2; j++) for (j = 0; j < 2; j++)
aval[j] = get_val_for (op[j], val[j]); aval[j] = get_val_for (op[j], val[j]);
acnd = fold (build (cmp, boolean_type_node, aval[0], aval[1])); acnd = fold (build2 (cmp, boolean_type_node, aval[0], aval[1]));
if (integer_zerop (acnd)) if (zero_p (acnd))
{ {
if (dump_file && (dump_flags & TDF_DETAILS)) if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, fprintf (dump_file,
@ -906,7 +925,7 @@ find_loop_niter_by_eval (struct loop *loop, edge *exit)
continue; continue;
if (niter if (niter
&& !integer_nonzerop (fold (build (LT_EXPR, boolean_type_node, && !nonzero_p (fold (build2 (LT_EXPR, boolean_type_node,
aniter, niter)))) aniter, niter))))
continue; continue;
@ -980,11 +999,11 @@ estimate_numbers_of_iterations_loop (struct loop *loop)
niter = niter_desc.niter; niter = niter_desc.niter;
type = TREE_TYPE (niter); type = TREE_TYPE (niter);
if (!integer_zerop (niter_desc.may_be_zero) if (!zero_p (niter_desc.may_be_zero)
&& !integer_nonzerop (niter_desc.may_be_zero)) && !nonzero_p (niter_desc.may_be_zero))
niter = build (COND_EXPR, type, niter_desc.may_be_zero, niter = build3 (COND_EXPR, type, niter_desc.may_be_zero,
convert (type, integer_zero_node), build_int_cst_type (type, 0),
niter); niter);
record_estimate (loop, niter, record_estimate (loop, niter,
niter_desc.additional_info, niter_desc.additional_info,
last_stmt (exits[i]->src)); last_stmt (exits[i]->src));
@ -1025,14 +1044,14 @@ compare_trees (tree a, tree b)
else else
type = typeb; type = typeb;
a = convert (type, a); a = fold_convert (type, a);
b = convert (type, b); b = fold_convert (type, b);
if (integer_nonzerop (fold (build (EQ_EXPR, boolean_type_node, a, b)))) if (nonzero_p (fold (build2 (EQ_EXPR, boolean_type_node, a, b))))
return 0; return 0;
if (integer_nonzerop (fold (build (LT_EXPR, boolean_type_node, a, b)))) if (nonzero_p (fold (build2 (LT_EXPR, boolean_type_node, a, b))))
return 1; return 1;
if (integer_nonzerop (fold (build (GT_EXPR, boolean_type_node, a, b)))) if (nonzero_p (fold (build2 (GT_EXPR, boolean_type_node, a, b))))
return -1; return -1;
return 2; return 2;
@ -1080,9 +1099,8 @@ upper_bound_in_type (tree outer, tree inner)
} }
} }
return convert (outer, return fold_convert (outer,
convert (inner, build_int_cst_wide (inner, lo, hi));
build_int_cst_wide (NULL_TREE, lo, hi)));
} }
/* Returns the smallest value obtainable by casting something in INNER type to /* Returns the smallest value obtainable by casting something in INNER type to
@ -1107,9 +1125,8 @@ lower_bound_in_type (tree outer, tree inner)
lo = 0; lo = 0;
} }
return convert (outer, return fold_convert (outer,
convert (inner, build_int_cst_wide (inner, lo, hi));
build_int_cst_wide (NULL_TREE, lo, hi)));
} }
/* Returns true if statement S1 dominates statement S2. */ /* Returns true if statement S1 dominates statement S2. */
@ -1168,10 +1185,10 @@ can_count_iv_in_wider_type_bound (tree type, tree base, tree step,
tree valid_niter, extreme, unsigned_type, delta, bound_type; tree valid_niter, extreme, unsigned_type, delta, bound_type;
tree cond; tree cond;
b = convert (type, base); b = fold_convert (type, base);
bplusstep = convert (type, bplusstep = fold_convert (type,
fold (build (PLUS_EXPR, inner_type, base, step))); fold (build2 (PLUS_EXPR, inner_type, base, step)));
new_step = fold (build (MINUS_EXPR, type, bplusstep, b)); new_step = fold (build2 (MINUS_EXPR, type, bplusstep, b));
if (TREE_CODE (new_step) != INTEGER_CST) if (TREE_CODE (new_step) != INTEGER_CST)
return NULL_TREE; return NULL_TREE;
@ -1179,14 +1196,14 @@ can_count_iv_in_wider_type_bound (tree type, tree base, tree step,
{ {
case -1: case -1:
extreme = upper_bound_in_type (type, inner_type); extreme = upper_bound_in_type (type, inner_type);
delta = fold (build (MINUS_EXPR, type, extreme, b)); delta = fold (build2 (MINUS_EXPR, type, extreme, b));
new_step_abs = new_step; new_step_abs = new_step;
break; break;
case 1: case 1:
extreme = lower_bound_in_type (type, inner_type); extreme = lower_bound_in_type (type, inner_type);
new_step_abs = fold (build (NEGATE_EXPR, type, new_step)); new_step_abs = fold (build1 (NEGATE_EXPR, type, new_step));
delta = fold (build (MINUS_EXPR, type, b, extreme)); delta = fold (build2 (MINUS_EXPR, type, b, extreme));
break; break;
case 0: case 0:
@ -1197,40 +1214,40 @@ can_count_iv_in_wider_type_bound (tree type, tree base, tree step,
} }
unsigned_type = unsigned_type_for (type); unsigned_type = unsigned_type_for (type);
delta = convert (unsigned_type, delta); delta = fold_convert (unsigned_type, delta);
new_step_abs = convert (unsigned_type, new_step_abs); new_step_abs = fold_convert (unsigned_type, new_step_abs);
valid_niter = fold (build (FLOOR_DIV_EXPR, unsigned_type, valid_niter = fold (build2 (FLOOR_DIV_EXPR, unsigned_type,
delta, new_step_abs)); delta, new_step_abs));
bound_type = TREE_TYPE (bound); bound_type = TREE_TYPE (bound);
if (TYPE_PRECISION (type) > TYPE_PRECISION (bound_type)) if (TYPE_PRECISION (type) > TYPE_PRECISION (bound_type))
bound = convert (unsigned_type, bound); bound = fold_convert (unsigned_type, bound);
else else
valid_niter = convert (bound_type, valid_niter); valid_niter = fold_convert (bound_type, valid_niter);
if (at_stmt && stmt_dominates_stmt_p (of, at_stmt)) if (at_stmt && stmt_dominates_stmt_p (of, at_stmt))
{ {
/* After the statement OF we know that anything is executed at most /* After the statement OF we know that anything is executed at most
BOUND times. */ BOUND times. */
cond = build (GE_EXPR, boolean_type_node, valid_niter, bound); cond = build2 (GE_EXPR, boolean_type_node, valid_niter, bound);
} }
else else
{ {
/* Before the statement OF we know that anything is executed at most /* Before the statement OF we know that anything is executed at most
BOUND + 1 times. */ BOUND + 1 times. */
cond = build (GT_EXPR, boolean_type_node, valid_niter, bound); cond = build2 (GT_EXPR, boolean_type_node, valid_niter, bound);
} }
cond = fold (cond); cond = fold (cond);
if (integer_nonzerop (cond)) if (nonzero_p (cond))
return new_step; return new_step;
/* Try taking additional conditions into account. */ /* Try taking additional conditions into account. */
cond = build (TRUTH_OR_EXPR, boolean_type_node, cond = build2 (TRUTH_OR_EXPR, boolean_type_node,
invert_truthvalue (additional), invert_truthvalue (additional),
cond); cond);
cond = fold (cond); cond = fold (cond);
if (integer_nonzerop (cond)) if (nonzero_p (cond))
return new_step; return new_step;
return NULL_TREE; return NULL_TREE;