public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH GCC]Improve overflow in scev by using information computed in loop niter, part II
@ 2015-05-26 12:19 Bin.Cheng
  2015-06-01 10:41 ` Richard Biener
  0 siblings, 1 reply; 3+ messages in thread
From: Bin.Cheng @ 2015-05-26 12:19 UTC (permalink / raw)
  To: gcc-patches List

Hi,
The first part patch improving how we handle overflow in scev is
posted at https://gcc.gnu.org/ml/gcc-patches/2015-05/msg01795.html .
Here comes the second part patch.

This patch does below improvements:
  1) Computes and records control iv for each loop's exit edge.  This
provides a way to compute overflow information in loop niter and use
it in different customers.  It think it's useful, especially with
option -funsafe-loop-optimizers.
  2) Improve chrec_convert by adding new interface
loop_exits_before_overflow.  It checks if a converted IV overflows
wrto its type and loop using overflow information of loop's control
iv.  This basically propagates no-overflow information from control iv
to ivs converted from control iv.  Moreover, we can further improve
the logic by using possible VRP information in the future.

With this patch, cases like scev-9.c and scev-10.c in patch can be
handled now.  Cases reported in PR48052 can be vectorized too.
Opinions?

Thanks,
bin


2015-05-26  Bin Cheng  <bin.cheng@arm.com>

    * cfgloop.h (struct control_iv): New.
    (struct loop): New field control_ivs.
    * tree-ssa-loop-niter.c : Include "stor-layout.h".
    (number_of_iterations_lt): Set no_overflow information.
    (number_of_iterations_exit): Init control iv in niter struct.
    (record_control_iv): New.
    (estimate_numbers_of_iterations_loop): Call record_control_iv.
    (loop_exits_before_overflow): New.  Interface factored out of
    scev_probably_wraps_p.
    (scev_probably_wraps_p): Factor loop niter related code into
    loop_exits_before_overflow.
    (free_numbers_of_iterations_estimates_loop): Free control ivs.
    * tree-ssa-loop-niter.h (free_loop_control_ivs): New.

gcc/testsuite/ChangeLog
2015-05-26  Bin Cheng  <bin.cheng@arm.com>

    PR tree-optimization/48052
    * gcc.dg/tree-ssa/scev-8.c: New.
    * gcc.dg/tree-ssa/scev-9.c: New.
    * gcc.dg/tree-ssa/scev-10.c: New.
    * gcc.dg/vect/pr48052.c: New.

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH GCC]Improve overflow in scev by using information computed in loop niter, part II
  2015-05-26 12:19 [PATCH GCC]Improve overflow in scev by using information computed in loop niter, part II Bin.Cheng
@ 2015-06-01 10:41 ` Richard Biener
  2015-06-01 10:46   ` Bin.Cheng
  0 siblings, 1 reply; 3+ messages in thread
From: Richard Biener @ 2015-06-01 10:41 UTC (permalink / raw)
  To: Bin.Cheng; +Cc: gcc-patches List

On Tue, May 26, 2015 at 1:13 PM, Bin.Cheng <amker.cheng@gmail.com> wrote:
> Hi,
> The first part patch improving how we handle overflow in scev is
> posted at https://gcc.gnu.org/ml/gcc-patches/2015-05/msg01795.html .
> Here comes the second part patch.
>
> This patch does below improvements:
>   1) Computes and records control iv for each loop's exit edge.  This
> provides a way to compute overflow information in loop niter and use
> it in different customers.  It think it's useful, especially with
> option -funsafe-loop-optimizers.
>   2) Improve chrec_convert by adding new interface
> loop_exits_before_overflow.  It checks if a converted IV overflows
> wrto its type and loop using overflow information of loop's control
> iv.  This basically propagates no-overflow information from control iv
> to ivs converted from control iv.  Moreover, we can further improve
> the logic by using possible VRP information in the future.
>
> With this patch, cases like scev-9.c and scev-10.c in patch can be
> handled now.  Cases reported in PR48052 can be vectorized too.
> Opinions?

-ENOPATCH

> Thanks,
> bin
>
>
> 2015-05-26  Bin Cheng  <bin.cheng@arm.com>
>
>     * cfgloop.h (struct control_iv): New.
>     (struct loop): New field control_ivs.
>     * tree-ssa-loop-niter.c : Include "stor-layout.h".
>     (number_of_iterations_lt): Set no_overflow information.
>     (number_of_iterations_exit): Init control iv in niter struct.
>     (record_control_iv): New.
>     (estimate_numbers_of_iterations_loop): Call record_control_iv.
>     (loop_exits_before_overflow): New.  Interface factored out of
>     scev_probably_wraps_p.
>     (scev_probably_wraps_p): Factor loop niter related code into
>     loop_exits_before_overflow.
>     (free_numbers_of_iterations_estimates_loop): Free control ivs.
>     * tree-ssa-loop-niter.h (free_loop_control_ivs): New.
>
> gcc/testsuite/ChangeLog
> 2015-05-26  Bin Cheng  <bin.cheng@arm.com>
>
>     PR tree-optimization/48052
>     * gcc.dg/tree-ssa/scev-8.c: New.
>     * gcc.dg/tree-ssa/scev-9.c: New.
>     * gcc.dg/tree-ssa/scev-10.c: New.
>     * gcc.dg/vect/pr48052.c: New.

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH GCC]Improve overflow in scev by using information computed in loop niter, part II
  2015-06-01 10:41 ` Richard Biener
@ 2015-06-01 10:46   ` Bin.Cheng
  0 siblings, 0 replies; 3+ messages in thread
From: Bin.Cheng @ 2015-06-01 10:46 UTC (permalink / raw)
  To: Richard Biener; +Cc: gcc-patches List

[-- Attachment #1: Type: text/plain, Size: 2330 bytes --]

On Mon, Jun 1, 2015 at 6:41 PM, Richard Biener
<richard.guenther@gmail.com> wrote:
> On Tue, May 26, 2015 at 1:13 PM, Bin.Cheng <amker.cheng@gmail.com> wrote:
>> Hi,
>> The first part patch improving how we handle overflow in scev is
>> posted at https://gcc.gnu.org/ml/gcc-patches/2015-05/msg01795.html .
>> Here comes the second part patch.
>>
>> This patch does below improvements:
>>   1) Computes and records control iv for each loop's exit edge.  This
>> provides a way to compute overflow information in loop niter and use
>> it in different customers.  It think it's useful, especially with
>> option -funsafe-loop-optimizers.
>>   2) Improve chrec_convert by adding new interface
>> loop_exits_before_overflow.  It checks if a converted IV overflows
>> wrto its type and loop using overflow information of loop's control
>> iv.  This basically propagates no-overflow information from control iv
>> to ivs converted from control iv.  Moreover, we can further improve
>> the logic by using possible VRP information in the future.
>>
>> With this patch, cases like scev-9.c and scev-10.c in patch can be
>> handled now.  Cases reported in PR48052 can be vectorized too.
>> Opinions?
>
> -ENOPATCH
Here comes the patch.  Sorry for the inconvenience.

Thanks,
bin
>
>> Thanks,
>> bin
>>
>>
>> 2015-05-26  Bin Cheng  <bin.cheng@arm.com>
>>
>>     * cfgloop.h (struct control_iv): New.
>>     (struct loop): New field control_ivs.
>>     * tree-ssa-loop-niter.c : Include "stor-layout.h".
>>     (number_of_iterations_lt): Set no_overflow information.
>>     (number_of_iterations_exit): Init control iv in niter struct.
>>     (record_control_iv): New.
>>     (estimate_numbers_of_iterations_loop): Call record_control_iv.
>>     (loop_exits_before_overflow): New.  Interface factored out of
>>     scev_probably_wraps_p.
>>     (scev_probably_wraps_p): Factor loop niter related code into
>>     loop_exits_before_overflow.
>>     (free_numbers_of_iterations_estimates_loop): Free control ivs.
>>     * tree-ssa-loop-niter.h (free_loop_control_ivs): New.
>>
>> gcc/testsuite/ChangeLog
>> 2015-05-26  Bin Cheng  <bin.cheng@arm.com>
>>
>>     PR tree-optimization/48052
>>     * gcc.dg/tree-ssa/scev-8.c: New.
>>     * gcc.dg/tree-ssa/scev-9.c: New.
>>     * gcc.dg/tree-ssa/scev-10.c: New.
>>     * gcc.dg/vect/pr48052.c: New.

[-- Attachment #2: improve-overlow-in-loop_niter-scev-20150526.txt --]
[-- Type: text/plain, Size: 16706 bytes --]

Index: gcc/tree-ssa-loop-niter.c
===================================================================
--- gcc/tree-ssa-loop-niter.c	(revision 222758)
+++ gcc/tree-ssa-loop-niter.c	(working copy)
@@ -31,6 +31,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "wide-int.h"
 #include "inchash.h"
 #include "tree.h"
+#include "stor-layout.h"
 #include "fold-const.h"
 #include "calls.h"
 #include "hashtab.h"
@@ -1184,6 +1185,7 @@ number_of_iterations_lt (tree type, affine_iv *iv0
       niter->niter = delta;
       niter->max = widest_int::from (wi::from_mpz (niter_type, bnds->up, false),
 				     TYPE_SIGN (niter_type));
+      niter->control.no_overflow = true;
       return true;
     }
 
@@ -1965,6 +1967,9 @@ number_of_iterations_exit (struct loop *loop, edge
     return false;
 
   niter->assumptions = boolean_false_node;
+  niter->control.base = NULL_TREE;
+  niter->control.step = NULL_TREE;
+  niter->control.no_overflow = false;
   last = last_stmt (exit->src);
   if (!last)
     return false;
@@ -2744,6 +2749,29 @@ record_estimate (struct loop *loop, tree bound, co
   record_niter_bound (loop, new_i_bound, realistic, upper);
 }
 
+/* Records the control iv analyzed in NITER for LOOP if the iv is valid
+   and doesn't overflow.  */
+
+static void
+record_control_iv (struct loop *loop, struct tree_niter_desc *niter)
+{
+  struct control_iv *iv;
+
+  if (!niter->control.base || !niter->control.step)
+    return;
+
+  if (!integer_onep (niter->assumptions) || !niter->control.no_overflow)
+    return;
+
+  iv = ggc_alloc<control_iv> ();
+  iv->base = niter->control.base;
+  iv->step = niter->control.step;
+  iv->next = loop->control_ivs;
+  loop->control_ivs = iv;
+
+  return;
+}
+
 /* Record the estimate on number of iterations of LOOP based on the fact that
    the induction variable BASE + STEP * i evaluated in STMT does not wrap and
    its values belong to the range <LOW, HIGH>.  REALISTIC is true if the
@@ -3467,6 +3495,7 @@ estimate_numbers_of_iterations_loop (struct loop *
       record_estimate (loop, niter, niter_desc.max,
 		       last_stmt (ex->src),
 		       true, ex == likely_exit, true);
+      record_control_iv (loop, &niter_desc);
     }
   exits.release ();
 
@@ -3773,6 +3802,188 @@ nowrap_type_p (tree type)
   return false;
 }
 
+/* Return true if we can prove LOOP is exited before evolution of induction
+   variabled {BASE, STEP} overflows with respect to its type bound.  */
+
+static bool
+loop_exits_before_overflow (tree base, tree step,
+			    gimple at_stmt, struct loop *loop)
+{
+  widest_int niter;
+  struct control_iv *civ;
+  struct nb_iter_bound *bound;
+  tree e, delta, step_abs, unsigned_base;
+  tree type = TREE_TYPE (step);
+  tree unsigned_type, valid_niter;
+
+  /* Don't issue signed overflow warnings.  */
+  fold_defer_overflow_warnings ();
+
+  /* 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);
+
+  if (tree_int_cst_sign_bit (step))
+    {
+      tree extreme = fold_convert (unsigned_type,
+				   lower_bound_in_type (type, type));
+      delta = fold_build2 (MINUS_EXPR, unsigned_type, unsigned_base, extreme);
+      step_abs = fold_build1 (NEGATE_EXPR, unsigned_type,
+			      fold_convert (unsigned_type, step));
+    }
+  else
+    {
+      tree extreme = fold_convert (unsigned_type,
+				   upper_bound_in_type (type, type));
+      delta = fold_build2 (MINUS_EXPR, unsigned_type, extreme, unsigned_base);
+      step_abs = fold_convert (unsigned_type, step);
+    }
+
+  valid_niter = fold_build2 (FLOOR_DIV_EXPR, unsigned_type, delta, step_abs);
+
+  estimate_numbers_of_iterations_loop (loop);
+
+  if (max_loop_iterations (loop, &niter)
+      && wi::fits_to_tree_p (niter, TREE_TYPE (valid_niter))
+      && (e = fold_binary (GT_EXPR, boolean_type_node, valid_niter,
+			   wide_int_to_tree (TREE_TYPE (valid_niter),
+					     niter))) != NULL
+      && integer_nonzerop (e))
+    {
+      fold_undefer_and_ignore_overflow_warnings ();
+      return true;
+    }
+  if (at_stmt)
+    for (bound = loop->bounds; bound; bound = bound->next)
+      {
+	if (n_of_executions_at_most (at_stmt, bound, valid_niter))
+	  {
+	    fold_undefer_and_ignore_overflow_warnings ();
+	    return true;
+	  }
+      }
+  fold_undefer_and_ignore_overflow_warnings ();
+
+  /* Try to prove loop is exited before {base, step} overflows with the
+     help of analyzed loop control IV.  This is done only for IVs with
+     constant step because otherwise we don't have the information.  */
+  if (TREE_CODE (step) == INTEGER_CST)
+    for (civ = loop->control_ivs; civ; civ = civ->next)
+      {
+	enum tree_code code;
+	tree stepped, extreme, civ_type = TREE_TYPE (civ->step);
+
+	/* Have to consider type difference because operand_equal_p ignores
+	   that for constants.  */
+	if (TYPE_UNSIGNED (type) != TYPE_UNSIGNED (civ_type)
+	    || element_precision (type) != element_precision (civ_type))
+	  continue;
+
+	/* Only consider control IV with same step.  */
+	if (!operand_equal_p (step, civ->step, 0))
+	  continue;
+
+	/* Done proving if this is a no-overflow control IV.  */
+	if (operand_equal_p (base, civ->base, 0))
+	  return true;
+
+	/* If this is a before stepping control IV, in other words, we have
+
+	     {civ_base, step} = {base + step, step}
+
+	   Because civ {base + step, step} doesn't overflow during loop
+	   iterations, {base, step} will not overflow if we can prove the
+	   operation "base + step" does not overflow.  This is done by proving
+	   below conditions:
+
+	     base <= UPPER_BOUND (type) - step  ;;step > 0
+	     base >= LOWER_BOUND (type) - step  ;;step < 0
+
+	   by using loop's initial condition.  */
+	stepped = fold_build2 (PLUS_EXPR, TREE_TYPE (base), base, step);
+	if (operand_equal_p (stepped, civ->base, 0))
+	  {
+	    if (tree_int_cst_sign_bit (step))
+	      {
+		code = LT_EXPR;
+		extreme = lower_bound_in_type (type, type);
+	      }
+	    else
+	      {
+		code = GT_EXPR;
+		extreme = upper_bound_in_type (type, type);
+	      }
+	    extreme = fold_build2 (MINUS_EXPR, type, extreme, step);
+	    e = fold_build2 (code, boolean_type_node, base, extreme);
+	    e = simplify_using_initial_conditions (loop, e);
+	    if (integer_zerop (e))
+	      return true;
+
+	    continue;
+	  }
+
+	/* Similar to above, only in this case we have:
+
+	     {civ_base, step} = {(signed T)((unsigned T)base + step), step}
+	     && TREE_TYPE (civ_base) = signed T.
+
+	   We prove that below condition is satisfied:
+
+	     (signed T)((unsigned T)base + step)
+	       == (signed T)(unsigned T)base + step
+	       == base + step
+
+	   because of exact the same reason as above.  This also proves
+	   there is no overflow in the operation "base + step", thus the
+	   induction variable {base, step} during loop iterations.
+
+	   This is necessary to handle cases as below:
+
+	     int foo (int *a, signed char s, signed char l)
+	       {
+		 signed char i;
+		 for (i = s; i < l; i++)
+		   a[i] = 0;
+		 return 0;
+	       }
+
+	   The variable I is firstly converted to type unsigned char,
+	   incremented, then converted back to type signed char.  */
+	if (!CONVERT_EXPR_P (civ->base) || TREE_TYPE (civ->base) != type)
+	  continue;
+	e = TREE_OPERAND (civ->base, 0);
+	if (TREE_CODE (e) != PLUS_EXPR
+	    || TREE_CODE (TREE_OPERAND (e, 1)) != INTEGER_CST
+	    || !operand_equal_p (step,
+				 fold_convert (type,
+					       TREE_OPERAND (e, 1)), 0))
+	  continue;
+	e = TREE_OPERAND (e, 0);
+	if (!CONVERT_EXPR_P (e) || !operand_equal_p (e, unsigned_base, 0))
+	  continue;
+	e = TREE_OPERAND (e, 0);
+	gcc_assert (operand_equal_p (e, base, 0));
+	if (tree_int_cst_sign_bit (step))
+	  {
+	    code = LT_EXPR;
+	    extreme = lower_bound_in_type (type, type);
+	  }
+	else
+	  {
+	    code = GT_EXPR;
+	    extreme = upper_bound_in_type (type, type);
+	  }
+	extreme = fold_build2 (MINUS_EXPR, type, extreme, step);
+	e = fold_build2 (code, boolean_type_node, base, extreme);
+	e = simplify_using_initial_conditions (loop, e);
+	if (integer_zerop (e))
+	  return true;
+      }
+
+  return false;
+}
+
 /* Return false only when the induction variable BASE + STEP * I is
    known to not overflow: i.e. when the number of iterations is small
    enough with respect to the step and initial condition in order to
@@ -3788,13 +3999,6 @@ scev_probably_wraps_p (tree base, tree step,
 		       gimple at_stmt, struct loop *loop,
 		       bool use_overflow_semantics)
 {
-  tree delta, step_abs;
-  tree unsigned_type, valid_niter;
-  tree type = TREE_TYPE (step);
-  tree e;
-  widest_int niter;
-  struct nb_iter_bound *bound;
-
   /* FIXME: We really need something like
      http://gcc.gnu.org/ml/gcc-patches/2005-06/msg02025.html.
 
@@ -3828,57 +4032,9 @@ scev_probably_wraps_p (tree base, tree step,
   if (TREE_CODE (step) != INTEGER_CST)
     return true;
 
-  /* Don't issue signed overflow warnings.  */
-  fold_defer_overflow_warnings ();
+  if (loop_exits_before_overflow (base, step, at_stmt, loop))
+    return false;
 
-  /* Otherwise, 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);
-  base = fold_convert (unsigned_type, base);
-
-  if (tree_int_cst_sign_bit (step))
-    {
-      tree extreme = fold_convert (unsigned_type,
-				   lower_bound_in_type (type, type));
-      delta = fold_build2 (MINUS_EXPR, unsigned_type, base, extreme);
-      step_abs = fold_build1 (NEGATE_EXPR, unsigned_type,
-			      fold_convert (unsigned_type, step));
-    }
-  else
-    {
-      tree extreme = fold_convert (unsigned_type,
-				   upper_bound_in_type (type, type));
-      delta = fold_build2 (MINUS_EXPR, unsigned_type, extreme, base);
-      step_abs = fold_convert (unsigned_type, step);
-    }
-
-  valid_niter = fold_build2 (FLOOR_DIV_EXPR, unsigned_type, delta, step_abs);
-
-  estimate_numbers_of_iterations_loop (loop);
-
-  if (max_loop_iterations (loop, &niter)
-      && wi::fits_to_tree_p (niter, TREE_TYPE (valid_niter))
-      && (e = fold_binary (GT_EXPR, boolean_type_node, valid_niter,
-			   wide_int_to_tree (TREE_TYPE (valid_niter),
-					     niter))) != NULL
-      && integer_nonzerop (e))
-    {
-      fold_undefer_and_ignore_overflow_warnings ();
-      return false;
-    }
-  if (at_stmt)
-    for (bound = loop->bounds; bound; bound = bound->next)
-      {
-	if (n_of_executions_at_most (at_stmt, bound, valid_niter))
-	  {
-	    fold_undefer_and_ignore_overflow_warnings ();
-	    return false;
-	  }
-      }
-
-  fold_undefer_and_ignore_overflow_warnings ();
-
   /* At this point we still don't have a proof that the iv does not
      overflow: give up.  */
   return true;
@@ -3889,17 +4045,26 @@ scev_probably_wraps_p (tree base, tree step,
 void
 free_numbers_of_iterations_estimates_loop (struct loop *loop)
 {
-  struct nb_iter_bound *bound, *next;
+  struct control_iv *civ;
+  struct nb_iter_bound *bound;
 
   loop->nb_iterations = NULL;
   loop->estimate_state = EST_NOT_COMPUTED;
-  for (bound = loop->bounds; bound; bound = next)
+  for (bound = loop->bounds; bound;)
     {
-      next = bound->next;
+      struct nb_iter_bound *next = bound->next;
       ggc_free (bound);
+      bound = next;
     }
+  loop->bounds = NULL;
 
-  loop->bounds = NULL;
+  for (civ = loop->control_ivs; civ;)
+    {
+      struct control_iv *next = civ->next;
+      ggc_free (civ);
+      civ = next;
+    }
+  loop->control_ivs = NULL;
 }
 
 /* Frees the information on upper bounds on numbers of iterations of loops.  */
Index: gcc/tree-ssa-loop-niter.h
===================================================================
--- gcc/tree-ssa-loop-niter.h	(revision 222758)
+++ gcc/tree-ssa-loop-niter.h	(working copy)
@@ -41,6 +41,7 @@ extern void estimate_numbers_of_iterations (void);
 extern bool stmt_dominates_stmt_p (gimple, gimple);
 extern bool nowrap_type_p (tree);
 extern bool scev_probably_wraps_p (tree, tree, gimple, struct loop *, bool);
+extern void free_loop_control_ivs (struct loop *);
 extern void free_numbers_of_iterations_estimates_loop (struct loop *);
 extern void free_numbers_of_iterations_estimates (void);
 extern void substitute_in_loop_info (struct loop *, tree, tree);
Index: gcc/testsuite/gcc.dg/vect/pr48052.c
===================================================================
--- gcc/testsuite/gcc.dg/vect/pr48052.c	(revision 0)
+++ gcc/testsuite/gcc.dg/vect/pr48052.c	(revision 0)
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-O3" } */
+
+int foo(int* A, int* B,  unsigned start, unsigned BS)
+{
+  int s;
+  for (unsigned k = start;  k < start + BS; k++)
+    {
+      s += A[k] * B[k];
+    }
+
+  return s;
+}
+
+int bar(int* A, int* B, unsigned BS)
+{
+  int s;
+  for (unsigned k = 0;  k < BS; k++)
+    {
+      s += A[k] * B[k];
+    }
+
+  return s;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" } } */
+/* { dg-final { cleanup-tree-dump "vect" } } */
Index: gcc/testsuite/gcc.dg/tree-ssa/scev-8.c
===================================================================
--- gcc/testsuite/gcc.dg/tree-ssa/scev-8.c	(revision 0)
+++ gcc/testsuite/gcc.dg/tree-ssa/scev-8.c	(revision 0)
@@ -0,0 +1,63 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-ivopts-details" } */
+
+int *a;
+
+int
+foo1 (long long s, long long l)
+{
+  long long i;
+
+  for (i = s; i < l; i++)
+    {
+      a[(short)i] = 0;
+    }
+  return 0;
+}
+
+int
+foo2 (unsigned char s, unsigned char l, unsigned char c)
+{
+  unsigned char i, step = 1;
+  int sum = 0;
+
+  for (i = s; i < l; i++)
+    {
+      sum += a[c];
+      c += step;
+    }
+
+  return sum;
+}
+
+int
+foo3 (unsigned char s, unsigned char l, unsigned char c)
+{
+  unsigned char i;
+  int sum = 0;
+
+  for (i = s; i != l; i += c)
+    {
+      sum += a[i];
+    }
+
+  return sum;
+}
+
+int
+foo4 (unsigned char s, unsigned char l)
+{
+  unsigned char i;
+  int sum = 0;
+
+  for (i = s; i != l; i++)
+    {
+      sum += a[i];
+    }
+
+  return sum;
+}
+
+/* Address of array references are not scevs.  */
+/* { dg-final { scan-tree-dump-not "use \[0-9\]\n  address" "ivopts" } } */
+/* { dg-final { cleanup-tree-dump "ivopts" } } */
Index: gcc/testsuite/gcc.dg/tree-ssa/scev-10.c
===================================================================
--- gcc/testsuite/gcc.dg/tree-ssa/scev-10.c	(revision 0)
+++ gcc/testsuite/gcc.dg/tree-ssa/scev-10.c	(revision 0)
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-ivopts-details" } */
+
+int *a;
+
+int
+foo (signed char s, signed char l)
+{
+  signed char i;
+  int sum = 0;
+
+  for (i = s; i < l; i++)
+    {
+      sum += a[i];
+    }
+
+  return sum;
+}
+
+/* Address of array references are not scevs.  */
+/* { dg-final { scan-tree-dump-times "use \[0-9\]\n  address" 1 "ivopts" } } */
+/* { dg-final { cleanup-tree-dump "ivopts" } } */
+
+
Index: gcc/testsuite/gcc.dg/tree-ssa/scev-9.c
===================================================================
--- gcc/testsuite/gcc.dg/tree-ssa/scev-9.c	(revision 0)
+++ gcc/testsuite/gcc.dg/tree-ssa/scev-9.c	(revision 0)
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-ivopts-details" } */
+
+int *a;
+
+int
+foo (unsigned char s, unsigned char l)
+{
+  unsigned char i;
+  int sum = 0;
+
+  for (i = s; i < l; i += 1)
+    {
+      sum += a[i];
+    }
+
+  return sum;
+}
+
+/* Address of array references are not scevs.  */
+/* { dg-final { scan-tree-dump-times "use \[0-9\]\n  address" 1 "ivopts" } } */
+/* { dg-final { cleanup-tree-dump "ivopts" } } */
+
Index: gcc/cfgloop.h
===================================================================
--- gcc/cfgloop.h	(revision 222758)
+++ gcc/cfgloop.h	(working copy)
@@ -116,6 +116,14 @@ enum loop_estimation
   EST_LAST
 };
 
+/* The structure describing a non-overflow control induction variable
+   of loop's exit edge.  */
+struct GTY ((chain_next ("%h.next"))) control_iv {
+  tree base;
+  tree step;
+  struct control_iv *next;
+};
+
 /* Structure to hold information for each natural loop.  */
 struct GTY ((chain_next ("%h.next"))) loop {
   /* Index into loops array.  */
@@ -203,6 +211,9 @@ struct GTY ((chain_next ("%h.next"))) loop {
   /* Upper bound on number of iterations of a loop.  */
   struct nb_iter_bound *bounds;
 
+  /* Non-overflow control ivs of a loop.  */
+  struct control_iv *control_ivs;
+
   /* Head of the cyclic list of the exits of the loop.  */
   struct loop_exit *exits;
 

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2015-06-01 10:46 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-05-26 12:19 [PATCH GCC]Improve overflow in scev by using information computed in loop niter, part II Bin.Cheng
2015-06-01 10:41 ` Richard Biener
2015-06-01 10:46   ` Bin.Cheng

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).