re PR middle-end/45098 (Missed induction variable optimization)
authorTom de Vries <tom@codesourcery.com>
Mon, 23 May 2011 07:27:59 +0000 (07:27 +0000)
committerTom de Vries <vries@gcc.gnu.org>
Mon, 23 May 2011 07:27:59 +0000 (07:27 +0000)
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

gcc/ChangeLog
gcc/tree-ssa-loop-niter.c

index a7243328a0ce478bce74f17be9c083868cf80738..70709733413e4ef9aa92184aa13135b0cf657084 100644 (file)
@@ -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.
index 2ec2e0ce5104c049c2fb25317600ccd9b92baaf6..230593ad264b99d67680a044b93e861faf183523 100644 (file)
@@ -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);
+            }
        }
 
     }