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> 2004-10-01 Jakub Jelinek <jakub@redhat.com>
Revert Revert
......
...@@ -117,7 +117,7 @@ chrec_fold_plus_poly_poly (enum tree_code code, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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, ...@@ -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 ...@@ -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, ...@@ -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, ...@@ -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 ...@@ -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 *); ...@@ -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) ...@@ -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 *); ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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;
......
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