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:
parent
5496b36fc2
commit
e6845c2382
|
@ -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
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue