[PATCH v2 1/5] niter: Add helper to compute type bound.

Robin Dapp <[email protected]>
Newsgroups gmane.comp.gcc.patches
Message-ID <[email protected]>
From: Robin Dapp <[email protected]>

This adds the get_niter_type_bound helper and uses it in
loop_exits_before_overflow as well as derive_simple_iv_with_niters.
We can re-use it in subsequent patches for computing nowrap bounds.

gcc/ChangeLog:

	* tree-scalar-evolution.cc (derive_simple_iv_with_niters): Use
	new function.
	* tree-ssa-loop-niter.cc (loop_exits_before_overflow): Use new
	function.
	(get_niter_type_bound): New function.
	* tree-ssa-loop-niter.h (get_niter_type_bound): Declare.
---
 gcc/tree-scalar-evolution.cc | 20 ++++------------
 gcc/tree-ssa-loop-niter.cc   | 44 ++++++++++++++++++++++--------------
 gcc/tree-ssa-loop-niter.h    |  1 +
 3 files changed, 32 insertions(+), 33 deletions(-)

diff --git a/gcc/tree-scalar-evolution.cc b/gcc/tree-scalar-evolution.cc
index cd99cbe86ce..80f24ec86a5 100644
--- a/gcc/tree-scalar-evolution.cc
+++ b/gcc/tree-scalar-evolution.cc
@@ -3247,22 +3247,10 @@ derive_simple_iv_with_niters (tree ev, tree *niters)
      folded only if inner iv won't overflow.  We compute the maximum
      number the inner iv can iterate before overflowing and return the
      simplified affine iv.  */
-  tree delta;
-  init = fold_convert (type, init);
-  step = fold_convert (type, step);
-  ev = build_polynomial_chrec (CHREC_VARIABLE (inner_ev), init, step);
-  if (tree_int_cst_sign_bit (step))
-    {
-      tree bound = lower_bound_in_type (inner_type, inner_type);
-      delta = fold_build2 (MINUS_EXPR, type, init, fold_convert (type, bound));
-      step = fold_build1 (NEGATE_EXPR, type, step);
-    }
-  else
-    {
-      tree bound = upper_bound_in_type (inner_type, inner_type);
-      delta = fold_build2 (MINUS_EXPR, type, fold_convert (type, bound), init);
-    }
-  *niters = fold_build2 (FLOOR_DIV_EXPR, type, delta, step);
+  ev = build_polynomial_chrec (CHREC_VARIABLE (inner_ev),
+			       fold_convert (type, init),
+			       fold_convert (type, step));
+  *niters = get_niter_type_bound (inner_type, init, step);
   return ev;
 }
 
diff --git a/gcc/tree-ssa-loop-niter.cc b/gcc/tree-ssa-loop-niter.cc
index 0c1ebd1c7d5..fe179b69b05 100644
--- a/gcc/tree-ssa-loop-niter.cc
+++ b/gcc/tree-ssa-loop-niter.cc
@@ -5357,24 +5357,15 @@ nowrap_type_p (tree type)
   return false;
 }
 
-/* Return true if we can prove LOOP is exited before evolution of induction
-   variable {BASE, STEP} overflows with respect to its type bound.  */
+/* Return an upper bound on the number of times the affine IV {BASE, +, STEP}
+   of type TYPE can step while staying within TYPE's range.  */
 
-static bool
-loop_exits_before_overflow (tree base, tree step,
-			    gimple *at_stmt, class loop *loop)
+tree
+get_niter_type_bound (tree type, tree base, tree step)
 {
-  widest_int niter;
-  struct control_iv *civ;
-  class nb_iter_bound *bound;
-  tree e, delta, step_abs, unsigned_base;
-  tree type = TREE_TYPE (step);
-  tree unsigned_type, valid_niter;
-
-  /* Compute the number of iterations before we reach the bound of the
-     type, and verify that the loop is exited before this occurs.  */
-  unsigned_type = unsigned_type_for (type);
-  unsigned_base = fold_convert (unsigned_type, base);
+  tree unsigned_type = unsigned_type_for (type);
+  tree unsigned_base = fold_convert (unsigned_type, base);
+  tree delta, step_abs;
 
   if (tree_int_cst_sign_bit (step))
     {
@@ -5392,7 +5383,26 @@ loop_exits_before_overflow (tree base, tree step,
       step_abs = fold_convert (unsigned_type, step);
     }
 
-  valid_niter = fold_build2 (FLOOR_DIV_EXPR, unsigned_type, delta, step_abs);
+  return fold_build2 (FLOOR_DIV_EXPR, unsigned_type, delta, step_abs);
+}
+
+/* Return true if we can prove LOOP is exited before evolution of induction
+   variable {BASE, STEP} overflows with respect to its type bound.  */
+
+static bool
+loop_exits_before_overflow (tree base, tree step,
+			    gimple *at_stmt, class loop *loop)
+{
+  widest_int niter;
+  struct control_iv *civ;
+  class nb_iter_bound *bound;
+  tree e;
+  tree type = TREE_TYPE (step);
+  tree valid_niter;
+
+  /* Compute the number of iterations before we reach the bound of the
+     type, and verify that the loop is exited before this occurs.  */
+  valid_niter = get_niter_type_bound (type, base, step);
 
   estimate_numbers_of_iterations (loop);
 
diff --git a/gcc/tree-ssa-loop-niter.h b/gcc/tree-ssa-loop-niter.h
index 643ac1d7f7f..24e458f08db 100644
--- a/gcc/tree-ssa-loop-niter.h
+++ b/gcc/tree-ssa-loop-niter.h
@@ -52,6 +52,7 @@ extern void estimate_numbers_of_iterations (function *);
 extern void estimate_numbers_of_iterations (class loop *);
 extern bool stmt_dominates_stmt_p (gimple *, gimple *);
 extern bool nowrap_type_p (tree);
+extern tree get_niter_type_bound (tree, tree, tree);
 extern bool scev_probably_wraps_p (tree, tree, tree, gimple *,
 				   class loop *, bool);
 extern void free_numbers_of_iterations_estimates (class loop *);
-- 
2.54.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.