diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a7243328a0c..70709733413 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2011-05-23 Tom de Vries + + 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 * 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 2ec2e0ce510..230593ad264 100644 --- a/gcc/tree-ssa-loop-niter.c +++ b/gcc/tree-ssa-loop-niter.c @@ -2831,6 +2831,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. */ @@ -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); + } } }