OSDN Git Service

2011-05-23 Tom de Vries <tom@codesourcery.com>
authorvries <vries@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 23 May 2011 07:27:59 +0000 (07:27 +0000)
committervries <vries@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 23 May 2011 07:27:59 +0000 (07:27 +0000)
PR target/45098
* tree-ssa-loop-niter.c (infer_loop_bounds_from_pointer_arith): New
function.
(infer_loop_bounds_from_undefined): Use new function.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@174056 138bc75d-0d04-0410-961f-82ee72b054a4

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

index a724332..7070973 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 2ec2e0c..230593a 100644 (file)
@@ -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);
+            }
        }
 
     }