aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/tree-ssa-loop-niter.c53
2 files changed, 59 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a724332..7070973 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2011-05-23 Tom de Vries <tom@codesourcery.com>
+
+ PR target/45098
+ * tree-ssa-loop-niter.c (infer_loop_bounds_from_pointer_arith): New
+ function.
+ (infer_loop_bounds_from_undefined): Use new function.
+
2011-05-22 Richard Sandiford <rdsandiford@googlemail.com>
* config/mips/mips.h (SUBTARGET_ASM_OPTIMIZING_SPEC): Delete.
diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c
index 2ec2e0c..230593a 100644
--- a/gcc/tree-ssa-loop-niter.c
+++ b/gcc/tree-ssa-loop-niter.c
@@ -2832,6 +2832,54 @@ infer_loop_bounds_from_array (struct loop *loop, gimple stmt, bool reliable)
}
/* Determine information about number of iterations of a LOOP from the fact
+ that pointer arithmetics in STMT does not overflow. */
+
+static void
+infer_loop_bounds_from_pointer_arith (struct loop *loop, gimple stmt)
+{
+ tree def, base, step, scev, type, low, high;
+ tree var, ptr;
+
+ if (!is_gimple_assign (stmt)
+ || gimple_assign_rhs_code (stmt) != POINTER_PLUS_EXPR)
+ return;
+
+ def = gimple_assign_lhs (stmt);
+ if (TREE_CODE (def) != SSA_NAME)
+ return;
+
+ type = TREE_TYPE (def);
+ if (!nowrap_type_p (type))
+ return;
+
+ ptr = gimple_assign_rhs1 (stmt);
+ if (!expr_invariant_in_loop_p (loop, ptr))
+ return;
+
+ var = gimple_assign_rhs2 (stmt);
+ if (TYPE_PRECISION (type) != TYPE_PRECISION (TREE_TYPE (var)))
+ return;
+
+ scev = instantiate_parameters (loop, analyze_scalar_evolution (loop, def));
+ if (chrec_contains_undetermined (scev))
+ return;
+
+ base = initial_condition_in_loop_num (scev, loop->num);
+ step = evolution_part_in_loop_num (scev, loop->num);
+
+ if (!base || !step
+ || TREE_CODE (step) != INTEGER_CST
+ || tree_contains_chrecs (base, NULL)
+ || chrec_contains_symbols_defined_in_loop (base, loop->num))
+ return;
+
+ low = lower_bound_in_type (type, type);
+ high = upper_bound_in_type (type, type);
+
+ record_nonwrapping_iv (loop, base, step, stmt, low, high, false, true);
+}
+
+/* Determine information about number of iterations of a LOOP from the fact
that signed arithmetics in STMT does not overflow. */
static void
@@ -2907,7 +2955,10 @@ infer_loop_bounds_from_undefined (struct loop *loop)
infer_loop_bounds_from_array (loop, stmt, reliable);
if (reliable)
- infer_loop_bounds_from_signedness (loop, stmt);
+ {
+ infer_loop_bounds_from_signedness (loop, stmt);
+ infer_loop_bounds_from_pointer_arith (loop, stmt);
+ }
}
}