Commit e6845c23 by Zdenek Dvorak Committed by Zdenek Dvorak

tree-chrec.c (chrec_fold_plus_poly_poly, [...]): Use fold_convert or…

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
parent 5496b36f
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>
Revert
......
......@@ -117,7 +117,7 @@ chrec_fold_plus_poly_poly (enum tree_code code,
(CHREC_VARIABLE (poly1),
chrec_fold_minus (type, poly0, CHREC_LEFT (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))
......@@ -283,8 +283,7 @@ chrec_fold_plus_1 (enum tree_code code,
(CHREC_VARIABLE (op1),
chrec_fold_minus (type, op0, CHREC_LEFT (op1)),
chrec_fold_multiply (type, CHREC_RIGHT (op1),
convert (type,
integer_minus_one_node)));
build_int_cst_type (type, -1)));
default:
if (tree_contains_chrecs (op0)
......@@ -347,7 +346,7 @@ chrec_fold_multiply (tree type,
if (integer_onep (op1))
return op0;
if (integer_zerop (op1))
return convert (type, integer_zero_node);
return build_int_cst_type (type, 0);
return build_polynomial_chrec
(CHREC_VARIABLE (op0),
......@@ -360,7 +359,7 @@ chrec_fold_multiply (tree type,
return op1;
if (integer_zerop (op0))
return convert (type, integer_zero_node);
return build_int_cst_type (type, 0);
switch (TREE_CODE (op1))
{
......@@ -374,7 +373,7 @@ chrec_fold_multiply (tree type,
if (integer_onep (op1))
return op0;
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));
}
}
......
......@@ -507,8 +507,7 @@ compute_overall_effect_of_inner_loop (struct loop *loop, tree evolution_fn)
analyze must be defined before the exit). */
nb_iter = chrec_fold_minus (chrec_type (nb_iter),
nb_iter,
fold_convert (chrec_type (nb_iter),
integer_one_node));
build_int_cst_type (chrec_type (nb_iter), 1));
/* evolution_fn is the evolution function in LOOP. Get
its value in the nb_iter-th iteration. */
......@@ -896,7 +895,7 @@ add_to_evolution (unsigned loop_nb,
if (code == MINUS_EXPR)
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);
......@@ -916,7 +915,9 @@ static inline tree
set_nb_iterations_in_loop (struct loop *loop,
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
count of the loop in order to be compatible with the other
nb_iter computations in loop-iv. This also allows the
......@@ -1209,8 +1210,7 @@ follow_ssa_edge_in_rhs (struct loop *loop,
(loop->num,
chrec_fold_multiply (type_rhs,
*evolution_of_loop,
fold_convert (type_rhs,
integer_minus_one_node)),
build_int_cst_type (type_rhs, -1)),
PLUS_EXPR, rhs0);
}
}
......@@ -1241,7 +1241,7 @@ follow_ssa_edge_in_rhs (struct loop *loop,
(loop->num,
chrec_fold_multiply (type_rhs,
*evolution_of_loop,
fold_convert (type_rhs, integer_minus_one_node)),
build_int_cst_type (type_rhs, -1)),
PLUS_EXPR, rhs0);
}
......
......@@ -104,6 +104,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
struct 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 ssa_name; /* The ssa name with the value. */
bool biv_p; /* Is it a biv? */
......@@ -301,9 +302,12 @@ extern void dump_iv (FILE *, struct iv *);
void
dump_iv (FILE *file, struct iv *iv)
{
if (iv->ssa_name)
{
fprintf (file, "ssa name ");
print_generic_expr (file, iv->ssa_name, TDF_SLIM);
fprintf (file, "\n");
}
fprintf (file, " type ");
print_generic_expr (file, TREE_TYPE (iv->base), TDF_SLIM);
......@@ -326,6 +330,13 @@ dump_iv (FILE *file, struct iv *iv)
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)
fprintf (file, " is a biv\n");
}
......@@ -336,8 +347,6 @@ extern void dump_use (FILE *, struct iv_use *);
void
dump_use (FILE *file, struct iv_use *use)
{
struct iv *iv = use->iv;
fprintf (file, "use %d\n", use->id);
switch (use->type)
......@@ -371,26 +380,7 @@ dump_use (FILE *file, struct iv_use *use)
print_generic_expr (file, *use->op_p, TDF_SLIM);
fprintf (file, "\n");
fprintf (file, " type ");
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");
}
dump_iv (file, use->iv);
fprintf (file, " related candidates ");
dump_bitmap (file, use->related_cands);
......@@ -446,26 +436,7 @@ dump_cand (FILE *file, struct iv_cand *cand)
break;
}
fprintf (file, " type ");
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");
}
dump_iv (file, iv);
}
/* 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");
}
/* 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
for loop LOOP. */
......@@ -638,6 +655,7 @@ alloc_iv (tree base, tree step)
step = NULL_TREE;
iv->base = base;
iv->base_object = determine_base_object (base);
iv->step = step;
iv->biv_p = 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->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))
dump_use (dump_file, use);
......@@ -2794,6 +2816,19 @@ get_computation_cost_at (struct ivopts_data *data,
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)
|| !cst_and_fits_in_hwi (cstep))
return INFTY;
......@@ -2974,23 +3009,31 @@ may_eliminate_iv (struct loop *loop,
struct iv_use *use, struct iv_cand *cand,
enum tree_code *compare, tree *bound)
{
basic_block ex_bb;
edge exit;
struct tree_niter_desc *niter, new_niter;
struct tree_niter_desc niter, new_niter;
tree wider_type, type, base;
/* For now just very primitive -- we work just for the single exit condition,
and are quite conservative about the possible overflows. TODO -- both of
these can be improved. */
exit = single_dom_exit (loop);
if (!exit)
/* For now works only for exits that dominate the loop latch. TODO -- extend
for other conditions inside loop body. */
ex_bb = bb_for_stmt (use->stmt);
if (use->stmt != last_stmt (ex_bb)
|| TREE_CODE (use->stmt) != COND_EXPR)
return false;
if (use->stmt != last_stmt (exit->src))
if (!dominated_by_p (CDI_DOMINATORS, loop->latch, ex_bb))
return false;
niter = &loop_data (loop)->niter;
if (!niter->niter
|| !integer_nonzerop (niter->assumptions)
|| !integer_zerop (niter->may_be_zero))
exit = EDGE_SUCC (ex_bb, 0);
if (flow_bb_inside_loop_p (loop, exit->dest))
exit = EDGE_SUCC (ex_bb, 1);
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;
if (exit->flags & EDGE_TRUE_VALUE)
......@@ -2998,7 +3041,7 @@ may_eliminate_iv (struct loop *loop,
else
*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
the number of iterations is unchanged. */
......@@ -3017,9 +3060,9 @@ may_eliminate_iv (struct loop *loop,
return false;
wider_type = TREE_TYPE (new_niter.niter);
if (TYPE_PRECISION (wider_type) < TYPE_PRECISION (TREE_TYPE (niter->niter)))
wider_type = TREE_TYPE (niter->niter);
if (!operand_equal_p (fold_convert (wider_type, niter->niter),
if (TYPE_PRECISION (wider_type) < TYPE_PRECISION (TREE_TYPE (niter.niter)))
wider_type = TREE_TYPE (niter.niter);
if (!operand_equal_p (fold_convert (wider_type, niter.niter),
fold_convert (wider_type, new_niter.niter), 0))
return false;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment