aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorTom de Vries <tom@codesourcery.com>2011-05-23 07:27:59 +0000
committerTom de Vries <vries@gcc.gnu.org>2011-05-23 07:27:59 +0000
commitbc69f7ffb57a35be61feb20e4a7b4300c8d1de24 (patch)
treefb512c461f1f61fb543c5013b019ee653fc7d9b3 /gcc
parentfec5d58b1ff0548148eb41ae72757a09d67a876c (diff)
downloadgcc-bc69f7ffb57a35be61feb20e4a7b4300c8d1de24.zip
gcc-bc69f7ffb57a35be61feb20e4a7b4300c8d1de24.tar.gz
gcc-bc69f7ffb57a35be61feb20e4a7b4300c8d1de24.tar.bz2
re PR middle-end/45098 (Missed induction variable optimization)
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. From-SVN: r174056
Diffstat (limited to 'gcc')
-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);
+ }
}
}