GCC is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
-Free Software Foundation; either version 2, or (at your option) any
+Free Software Foundation; either version 3, or (at your option) any
later version.
GCC is distributed in the hope that it will be useful, but WITHOUT
for more details.
You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING. If not, write to the Free
-Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301, USA. */
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
#include "config.h"
#include "system.h"
#include "tree-inline.h"
#include "gmp.h"
-#define SWAP(X, Y) do { void *tmp = (X); (X) = (Y); (Y) = tmp; } while (0)
+#define SWAP(X, Y) do { affine_iv *tmp = (X); (X) = (Y); (Y) = tmp; } while (0)
/* The maximum number of dominator BBs we search for conditions
of loop header copies we use for simplifying a conditional
/* Fallthru. */
case PLUS_EXPR:
+ case POINTER_PLUS_EXPR:
op0 = TREE_OPERAND (expr, 0);
op1 = TREE_OPERAND (expr, 1);
STRIP_SIGN_NOPS (c0);
STRIP_SIGN_NOPS (c1);
ctype = TREE_TYPE (c0);
- if (!tree_ssa_useless_type_conversion_1 (ctype, type))
+ if (!useless_type_conversion_p (ctype, type))
return;
break;
mpz_t mmod;
tree assumption = boolean_true_node, bound, noloop;
bool ret = false;
+ tree type1 = type;
+ if (POINTER_TYPE_P (type))
+ type1 = sizetype;
if (TREE_CODE (mod) != INTEGER_CST)
return false;
if (integer_nonzerop (mod))
mod = fold_build2 (MINUS_EXPR, niter_type, step, mod);
- tmod = fold_convert (type, mod);
+ tmod = fold_convert (type1, mod);
mpz_init (mmod);
mpz_set_double_int (mmod, tree_to_double_int (mod), true);
if (!iv1->no_overflow && !integer_zerop (mod))
{
bound = fold_build2 (MINUS_EXPR, type,
- TYPE_MAX_VALUE (type), tmod);
+ TYPE_MAX_VALUE (type1), tmod);
assumption = fold_build2 (LE_EXPR, boolean_type_node,
iv1->base, bound);
if (integer_zerop (assumption))
else
noloop = fold_build2 (GT_EXPR, boolean_type_node,
iv0->base,
- fold_build2 (PLUS_EXPR, type,
+ fold_build2 (PLUS_EXPR, type1,
iv1->base, tmod));
}
else
iv0->base - MOD <= iv1->base. */
if (!iv0->no_overflow && !integer_zerop (mod))
{
- bound = fold_build2 (PLUS_EXPR, type,
- TYPE_MIN_VALUE (type), tmod);
+ bound = fold_build2 (PLUS_EXPR, type1,
+ TYPE_MIN_VALUE (type1), tmod);
assumption = fold_build2 (GE_EXPR, boolean_type_node,
iv0->base, bound);
if (integer_zerop (assumption))
noloop = boolean_false_node;
else
noloop = fold_build2 (GT_EXPR, boolean_type_node,
- fold_build2 (MINUS_EXPR, type,
+ fold_build2 (MINUS_EXPR, type1,
iv0->base, tmod),
iv1->base);
}
struct tree_niter_desc *niter, bounds *bnds)
{
tree assumption = boolean_true_node, bound, diff;
- tree mbz, mbzl, mbzr;
+ tree mbz, mbzl, mbzr, type1;
bool rolls_p, no_overflow_p;
double_int dstep;
mpz_t mstep, max;
if (rolls_p && no_overflow_p)
return;
+
+ type1 = type;
+ if (POINTER_TYPE_P (type))
+ type1 = sizetype;
/* Now the hard part; we must formulate the assumption(s) as expressions, and
we must be careful not to introduce overflow. */
if (integer_nonzerop (iv0->step))
{
- diff = fold_build2 (MINUS_EXPR, type,
- iv0->step, build_int_cst (type, 1));
+ diff = fold_build2 (MINUS_EXPR, type1,
+ iv0->step, build_int_cst (type1, 1));
/* We need to know that iv0->base >= MIN + iv0->step - 1. Since
0 address never belongs to any object, we can assume this for
pointers. */
if (!POINTER_TYPE_P (type))
{
- bound = fold_build2 (PLUS_EXPR, type,
+ bound = fold_build2 (PLUS_EXPR, type1,
TYPE_MIN_VALUE (type), diff);
assumption = fold_build2 (GE_EXPR, boolean_type_node,
iv0->base, bound);
/* And then we can compute iv0->base - diff, and compare it with
iv1->base. */
- mbzl = fold_build2 (MINUS_EXPR, type, iv0->base, diff);
- mbzr = iv1->base;
+ mbzl = fold_build2 (MINUS_EXPR, type1,
+ fold_convert (type1, iv0->base), diff);
+ mbzr = fold_convert (type1, iv1->base);
}
else
{
- diff = fold_build2 (PLUS_EXPR, type,
- iv1->step, build_int_cst (type, 1));
+ diff = fold_build2 (PLUS_EXPR, type1,
+ iv1->step, build_int_cst (type1, 1));
if (!POINTER_TYPE_P (type))
{
- bound = fold_build2 (PLUS_EXPR, type,
+ bound = fold_build2 (PLUS_EXPR, type1,
TYPE_MAX_VALUE (type), diff);
assumption = fold_build2 (LE_EXPR, boolean_type_node,
iv1->base, bound);
}
- mbzl = iv0->base;
- mbzr = fold_build2 (MINUS_EXPR, type, iv1->base, diff);
+ mbzl = fold_convert (type1, iv0->base);
+ mbzr = fold_build2 (MINUS_EXPR, type1,
+ fold_convert (type1, iv1->base), diff);
}
if (!integer_nonzerop (assumption))
bounds *bnds)
{
tree assumption;
+ tree type1 = type;
+ if (POINTER_TYPE_P (type))
+ type1 = sizetype;
/* Say that IV0 is the control variable. Then IV0 <= IV1 iff
IV0 < IV1 + 1, assuming that IV1 is not equal to the greatest
{
if (integer_nonzerop (iv0->step))
assumption = fold_build2 (NE_EXPR, boolean_type_node,
- iv1->base, TYPE_MAX_VALUE (type));
+ iv1->base, TYPE_MAX_VALUE (type1));
else
assumption = fold_build2 (NE_EXPR, boolean_type_node,
- iv0->base, TYPE_MIN_VALUE (type));
+ iv0->base, TYPE_MIN_VALUE (type1));
if (integer_zerop (assumption))
return false;
}
if (integer_nonzerop (iv0->step))
- iv1->base = fold_build2 (PLUS_EXPR, type,
- iv1->base, build_int_cst (type, 1));
+ iv1->base = fold_build2 (PLUS_EXPR, type1,
+ iv1->base, build_int_cst (type1, 1));
else
- iv0->base = fold_build2 (MINUS_EXPR, type,
- iv0->base, build_int_cst (type, 1));
+ iv0->base = fold_build2 (MINUS_EXPR, type1,
+ iv0->base, build_int_cst (type1, 1));
- bounds_add (bnds, double_int_one, type);
+ bounds_add (bnds, double_int_one, type1);
return number_of_iterations_lt (type, iv0, iv1, niter, never_infinite, bnds);
}
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file,
- "Analysing # of iterations of loop %d\n", loop->num);
+ "Analyzing # of iterations of loop %d\n", loop->num);
fprintf (dump_file, " exit condition ");
dump_affine_iv (dump_file, iv0);
/* Substitute NEW for OLD in EXPR and fold the result. */
static tree
-simplify_replace_tree (tree expr, tree old, tree new)
+simplify_replace_tree (tree expr, tree old, tree new_tree)
{
unsigned i, n;
tree ret = NULL_TREE, e, se;
if (expr == old
|| operand_equal_p (expr, old, 0))
- return unshare_expr (new);
+ return unshare_expr (new_tree);
if (!EXPR_P (expr) && !GIMPLE_STMT_P (expr))
return expr;
for (i = 0; i < n; i++)
{
e = TREE_OPERAND (expr, i);
- se = simplify_replace_tree (e, old, new);
+ se = simplify_replace_tree (e, old, new_tree);
if (e == se)
continue;
&& !is_gimple_min_invariant (e)
/* And increments and decrements by a constant are simple. */
&& !((TREE_CODE (e) == PLUS_EXPR
- || TREE_CODE (e) == MINUS_EXPR)
+ || TREE_CODE (e) == MINUS_EXPR
+ || TREE_CODE (e) == POINTER_PLUS_EXPR)
&& is_gimple_min_invariant (TREE_OPERAND (e, 1))))
return expr;
/* Returns true if EXIT is the only possible exit from LOOP. */
static bool
-loop_only_exit_p (struct loop *loop, edge exit)
+loop_only_exit_p (const struct loop *loop, const_edge exit)
{
basic_block *body;
block_stmt_iterator bsi;
be nonnegative. */
static double_int
-derive_constant_upper_bound (tree val)
+derive_constant_upper_bound (const_tree val)
{
tree type = TREE_TYPE (val);
tree op0, op1, subtype, maxt;
return bnd;
case PLUS_EXPR:
+ case POINTER_PLUS_EXPR:
case MINUS_EXPR:
op0 = TREE_OPERAND (val, 0);
op1 = TREE_OPERAND (val, 1);
list. */
if (upper)
{
- struct nb_iter_bound *elt = XNEW (struct nb_iter_bound);
+ struct nb_iter_bound *elt = GGC_NEW (struct nb_iter_bound);
elt->bound = i_bound;
elt->stmt = at_stmt;
static bool
idx_infer_loop_bounds (tree base, tree *idx, void *dta)
{
- struct ilb_data *data = dta;
+ struct ilb_data *data = (struct ilb_data *) dta;
tree ev, init, step;
tree low, high, type, next;
bool sign, upper = data->reliable, at_end = false;
/* Returns true if statement S1 dominates statement S2. */
-static bool
+bool
stmt_dominates_stmt_p (tree s1, tree s2)
{
basic_block bb1 = bb_for_stmt (s1), bb2 = bb_for_stmt (s2);
2032, 2040, 0, 8, ..., but the code is still legal. */
if (chrec_contains_undetermined (base)
- || chrec_contains_undetermined (step)
- || TREE_CODE (step) != INTEGER_CST)
+ || chrec_contains_undetermined (step))
return true;
if (integer_zerop (step))
if (use_overflow_semantics && nowrap_type_p (type))
return false;
+ /* To be able to use estimates on number of iterations of the loop,
+ we must have an upper bound on the absolute value of the step. */
+ if (TREE_CODE (step) != INTEGER_CST)
+ return true;
+
/* Don't issue signed overflow warnings. */
fold_defer_overflow_warnings ();
for (bound = loop->bounds; bound; bound = next)
{
next = bound->next;
- free (bound);
+ ggc_free (bound);
}
loop->bounds = NULL;