public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH GCC]Improve loop bound info by simplifying conversions in iv base
@ 2015-07-28 10:14 Bin Cheng
  2015-08-13  8:58 ` Bin.Cheng
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Bin Cheng @ 2015-07-28 10:14 UTC (permalink / raw)
  To: gcc-patches

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

Hi,
For now, SCEV may compute iv base in the form of "(signed T)((unsigned
T)base + step))".  This complicates other optimizations/analysis depending
on SCEV because it's hard to dive into type conversions.  For many cases,
such type conversions can be simplified with additional range information
implied by loop initial conditions.  This patch does such simplification.
With simplified iv base, loop niter analysis can compute more accurate bound
information since sensible value range can be derived for "base+step".  For
example, accurate loop bound&may_be_zero information is computed for cases
added by this patch.
The code is actually borrowed from loop_exits_before_overflow.  Moreover,
with simplified iv base, the second case handled in that function now
becomes the first case.  I didn't remove that part of code because it may(?)
still be visited in scev analysis itself and simple_iv isn't an interface
for that.

Is it OK?

Thanks,
bin

2015-07-28  Bin Cheng  <bin.cheng@arm.com>

	* tree-ssa-loop-niter.c (tree_simplify_using_condition): Export
	the interface.
	* tree-ssa-loop-niter.h (tree_simplify_using_condition): Declare.
	* tree-scalar-evolution.c (simple_iv): Simplify type conversions
	in iv base using loop initial conditions.

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

	* gcc.dg/tree-ssa/loop-bound-2.c: New test.
	* gcc.dg/tree-ssa/loop-bound-4.c: New test.
	* gcc.dg/tree-ssa/loop-bound-6.c: New test.

[-- Attachment #2: simplify-iv_base-using-loop-initial-conditions-20150728.txt --]
[-- Type: text/plain, Size: 6432 bytes --]

Index: gcc/testsuite/gcc.dg/tree-ssa/loop-bound-2.c
===================================================================
--- gcc/testsuite/gcc.dg/tree-ssa/loop-bound-2.c	(revision 0)
+++ gcc/testsuite/gcc.dg/tree-ssa/loop-bound-2.c	(revision 0)
@@ -0,0 +1,23 @@
+/* { 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;
+}
+
+/* Check loop niter bound information.  */
+/* { dg-final { scan-tree-dump "bounded by 254" "ivopts" } } */
+/* { dg-final { scan-tree-dump-not "bounded by 255" "ivopts" } } */
+/* { dg-final { scan-tree-dump-not "zero if " "ivopts" } } */
Index: gcc/testsuite/gcc.dg/tree-ssa/loop-bound-4.c
===================================================================
--- gcc/testsuite/gcc.dg/tree-ssa/loop-bound-4.c	(revision 0)
+++ gcc/testsuite/gcc.dg/tree-ssa/loop-bound-4.c	(revision 0)
@@ -0,0 +1,23 @@
+/* { 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;
+}
+
+/* Check loop niter bound information.  */
+/* { dg-final { scan-tree-dump "bounded by 254" "ivopts" } } */
+/* { dg-final { scan-tree-dump-not "bounded by 255" "ivopts" } } */
+/* { dg-final { scan-tree-dump-not "zero if " "ivopts" } } */
Index: gcc/testsuite/gcc.dg/tree-ssa/loop-bound-6.c
===================================================================
--- gcc/testsuite/gcc.dg/tree-ssa/loop-bound-6.c	(revision 0)
+++ gcc/testsuite/gcc.dg/tree-ssa/loop-bound-6.c	(revision 0)
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-ivopts-details" } */
+
+int *a;
+
+int
+foo (signed char s)
+{
+  signed char i;
+  int sum = 0;
+
+  for (i = s; i > 0; i--)
+    {
+      sum += a[i];
+    }
+
+  return sum;
+}
+
+/* Check loop niter bound information.  */
+/* { dg-final { scan-tree-dump "bounded by 126" "ivopts" } } */
+/* { dg-final { scan-tree-dump-not "bounded by 127" "ivopts" } } */
+/* { dg-final { scan-tree-dump-not "zero if " "ivopts" } } */
Index: gcc/tree-ssa-loop-niter.c
===================================================================
--- gcc/tree-ssa-loop-niter.c	(revision 225859)
+++ gcc/tree-ssa-loop-niter.c	(working copy)
@@ -1779,9 +2043,9 @@ tree_simplify_using_condition (tree cond, tree exp
 
 /* Tries to simplify EXPR using the conditions on entry to LOOP.
    Returns the simplified expression (or EXPR unchanged, if no
-   simplification was possible).*/
+   simplification was possible).  */
 
-static tree
+tree
 simplify_using_initial_conditions (struct loop *loop, tree expr)
 {
   edge e;
Index: gcc/tree-ssa-loop-niter.h
===================================================================
--- gcc/tree-ssa-loop-niter.h	(revision 225859)
+++ gcc/tree-ssa-loop-niter.h	(working copy)
@@ -21,6 +21,7 @@ along with GCC; see the file COPYING3.  If not see
 #define GCC_TREE_SSA_LOOP_NITER_H
 
 extern tree expand_simple_operations (tree, tree = NULL);
+extern tree simplify_using_initial_conditions (struct loop *, tree);
 extern bool loop_only_exit_p (const struct loop *, const_edge);
 extern bool number_of_iterations_exit (struct loop *, edge,
 				       struct tree_niter_desc *niter, bool,
Index: gcc/tree-scalar-evolution.c
===================================================================
--- gcc/tree-scalar-evolution.c	(revision 225859)
+++ gcc/tree-scalar-evolution.c	(working copy)
@@ -3234,7 +3234,8 @@ bool
 simple_iv (struct loop *wrto_loop, struct loop *use_loop, tree op,
 	   affine_iv *iv, bool allow_nonconstant_step)
 {
-  tree type, ev;
+  enum tree_code code;
+  tree type, ev, base, e, extreme;
   bool folded_casts;
 
   iv->base = NULL_TREE;
@@ -3276,6 +3277,77 @@ simple_iv (struct loop *wrto_loop, struct loop *us
   iv->no_overflow = (!folded_casts && ANY_INTEGRAL_TYPE_P (type)
 		     && TYPE_OVERFLOW_UNDEFINED (type));
 
+  /* Try to simplify iv base:
+
+       (signed T) ((unsigned T)base + step) ;; TREE_TYPE (base) == signed T
+	 == (signed T)(unsigned T)base + step
+	 == base + step
+
+     If we can prove operation (base + step) doesn't overflow or underflow.
+     Specifically, we try to prove below conditions are satisfied:
+
+	     base <= UPPER_BOUND (type) - step  ;;step > 0
+	     base >= LOWER_BOUND (type) - step  ;;step < 0
+
+     This is done by proving the reverse conditions are false using loop's
+     initial conditions.
+
+     The is necessary to make loop niter, or iv overflow analysis easier
+     for below example:
+
+       int foo (int *a, signed char s, signed char l)
+	 {
+	   signed char i;
+	   for (i = s; i < l; i++)
+	     a[i] = 0;
+	   return 0;
+	  }
+
+     Note variable I is firstly converted to type unsigned char, incremented,
+     then converted back to type signed char.  */
+
+  if (wrto_loop->num != use_loop->num)
+    return true;
+
+  if (!CONVERT_EXPR_P (iv->base))
+    return true;
+  type = TREE_TYPE (iv->base);
+  e = TREE_OPERAND (iv->base, 0);
+  if (TREE_CODE (e) != PLUS_EXPR
+      || TREE_CODE (TREE_OPERAND (e, 1)) != INTEGER_CST
+      || !operand_equal_p (iv->step,
+			   fold_convert (type,
+					 TREE_OPERAND (e, 1)), 0))
+    return true;
+  e = TREE_OPERAND (e, 0);
+  if (!CONVERT_EXPR_P (e))
+    return true;
+  base = TREE_OPERAND (e, 0);
+  if (!useless_type_conversion_p (type, TREE_TYPE (base)))
+    return true;
+
+  if (tree_int_cst_sign_bit (iv->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, iv->step);
+  e = fold_build2 (code, boolean_type_node, base, extreme);
+  e = simplify_using_initial_conditions (use_loop, e);
+  if (!integer_zerop (e))
+    return true;
+
+  if (POINTER_TYPE_P (TREE_TYPE (base)))
+    code = POINTER_PLUS_EXPR;
+  else
+    code = PLUS_EXPR;
+
+  iv->base = fold_build2 (code, TREE_TYPE (base), base, iv->step);
   return true;
 }
 

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

* Re: [PATCH GCC]Improve loop bound info by simplifying conversions in iv base
  2015-07-28 10:14 [PATCH GCC]Improve loop bound info by simplifying conversions in iv base Bin Cheng
@ 2015-08-13  8:58 ` Bin.Cheng
  2015-08-13 22:16 ` Jeff Law
  2015-08-14  8:32 ` Richard Biener
  2 siblings, 0 replies; 7+ messages in thread
From: Bin.Cheng @ 2015-08-13  8:58 UTC (permalink / raw)
  To: Bin Cheng; +Cc: gcc-patches List

Ping.

Thanks,
bin

On Tue, Jul 28, 2015 at 5:38 PM, Bin Cheng <bin.cheng@arm.com> wrote:
> Hi,
> For now, SCEV may compute iv base in the form of "(signed T)((unsigned
> T)base + step))".  This complicates other optimizations/analysis depending
> on SCEV because it's hard to dive into type conversions.  For many cases,
> such type conversions can be simplified with additional range information
> implied by loop initial conditions.  This patch does such simplification.
> With simplified iv base, loop niter analysis can compute more accurate bound
> information since sensible value range can be derived for "base+step".  For
> example, accurate loop bound&may_be_zero information is computed for cases
> added by this patch.
> The code is actually borrowed from loop_exits_before_overflow.  Moreover,
> with simplified iv base, the second case handled in that function now
> becomes the first case.  I didn't remove that part of code because it may(?)
> still be visited in scev analysis itself and simple_iv isn't an interface
> for that.
>
> Is it OK?
>
> Thanks,
> bin
>
> 2015-07-28  Bin Cheng  <bin.cheng@arm.com>
>
>         * tree-ssa-loop-niter.c (tree_simplify_using_condition): Export
>         the interface.
>         * tree-ssa-loop-niter.h (tree_simplify_using_condition): Declare.
>         * tree-scalar-evolution.c (simple_iv): Simplify type conversions
>         in iv base using loop initial conditions.
>
> gcc/testsuite/ChangeLog
> 2015-07-28  Bin Cheng  <bin.cheng@arm.com>
>
>         * gcc.dg/tree-ssa/loop-bound-2.c: New test.
>         * gcc.dg/tree-ssa/loop-bound-4.c: New test.
>         * gcc.dg/tree-ssa/loop-bound-6.c: New test.

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

* Re: [PATCH GCC]Improve loop bound info by simplifying conversions in iv base
  2015-07-28 10:14 [PATCH GCC]Improve loop bound info by simplifying conversions in iv base Bin Cheng
  2015-08-13  8:58 ` Bin.Cheng
@ 2015-08-13 22:16 ` Jeff Law
  2015-08-14  7:29   ` Bin.Cheng
  2015-08-14  8:32 ` Richard Biener
  2 siblings, 1 reply; 7+ messages in thread
From: Jeff Law @ 2015-08-13 22:16 UTC (permalink / raw)
  To: Bin Cheng, gcc-patches

On 07/28/2015 03:38 AM, Bin Cheng wrote:
> Hi,
> For now, SCEV may compute iv base in the form of "(signed T)((unsigned
> T)base + step))".  This complicates other optimizations/analysis depending
> on SCEV because it's hard to dive into type conversions.  For many cases,
> such type conversions can be simplified with additional range information
> implied by loop initial conditions.  This patch does such simplification.
> With simplified iv base, loop niter analysis can compute more accurate bound
> information since sensible value range can be derived for "base+step".  For
> example, accurate loop bound&may_be_zero information is computed for cases
> added by this patch.
> The code is actually borrowed from loop_exits_before_overflow.  Moreover,
> with simplified iv base, the second case handled in that function now
> becomes the first case.  I didn't remove that part of code because it may(?)
> still be visited in scev analysis itself and simple_iv isn't an interface
> for that.
>
> Is it OK?
>
> Thanks,
> bin
>
> 2015-07-28  Bin Cheng  <bin.cheng@arm.com>
>
> 	* tree-ssa-loop-niter.c (tree_simplify_using_condition): Export
> 	the interface.
> 	* tree-ssa-loop-niter.h (tree_simplify_using_condition): Declare.
> 	* tree-scalar-evolution.c (simple_iv): Simplify type conversions
> 	in iv base using loop initial conditions.
>
> gcc/testsuite/ChangeLog
> 2015-07-28  Bin Cheng  <bin.cheng@arm.com>
>
> 	* gcc.dg/tree-ssa/loop-bound-2.c: New test.
> 	* gcc.dg/tree-ssa/loop-bound-4.c: New test.
> 	* gcc.dg/tree-ssa/loop-bound-6.c: New test.
I have the same concerns about these tests...  Which makes me really 
think I must be mis-understanding something in the debugging output.

jeff

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

* Re: [PATCH GCC]Improve loop bound info by simplifying conversions in iv base
  2015-08-13 22:16 ` Jeff Law
@ 2015-08-14  7:29   ` Bin.Cheng
  0 siblings, 0 replies; 7+ messages in thread
From: Bin.Cheng @ 2015-08-14  7:29 UTC (permalink / raw)
  To: Jeff Law; +Cc: Bin Cheng, gcc-patches List

On Fri, Aug 14, 2015 at 6:10 AM, Jeff Law <law@redhat.com> wrote:
> On 07/28/2015 03:38 AM, Bin Cheng wrote:
>>
>> Hi,
>> For now, SCEV may compute iv base in the form of "(signed T)((unsigned
>> T)base + step))".  This complicates other optimizations/analysis depending
>> on SCEV because it's hard to dive into type conversions.  For many cases,
>> such type conversions can be simplified with additional range information
>> implied by loop initial conditions.  This patch does such simplification.
>> With simplified iv base, loop niter analysis can compute more accurate
>> bound
>> information since sensible value range can be derived for "base+step".
>> For
>> example, accurate loop bound&may_be_zero information is computed for cases
>> added by this patch.
>> The code is actually borrowed from loop_exits_before_overflow.  Moreover,
>> with simplified iv base, the second case handled in that function now
>> becomes the first case.  I didn't remove that part of code because it
>> may(?)
>> still be visited in scev analysis itself and simple_iv isn't an interface
>> for that.
>>
>> Is it OK?
>>
>> Thanks,
>> bin
>>
>> 2015-07-28  Bin Cheng  <bin.cheng@arm.com>
>>
>>         * tree-ssa-loop-niter.c (tree_simplify_using_condition): Export
>>         the interface.
>>         * tree-ssa-loop-niter.h (tree_simplify_using_condition): Declare.
>>         * tree-scalar-evolution.c (simple_iv): Simplify type conversions
>>         in iv base using loop initial conditions.
>>
>> gcc/testsuite/ChangeLog
>> 2015-07-28  Bin Cheng  <bin.cheng@arm.com>
>>
>>         * gcc.dg/tree-ssa/loop-bound-2.c: New test.
>>         * gcc.dg/tree-ssa/loop-bound-4.c: New test.
>>         * gcc.dg/tree-ssa/loop-bound-6.c: New test.
>
> I have the same concerns about these tests...  Which makes me really think I
> must be mis-understanding something in the debugging output.

This patch tries to simplify SCEV base with the help of loop's initial
conditions.  The previous patch can only handle simplified SCEV base
when analyzing loop's bound information.  It's independent to the
previous one.  Actually it can be viewed as an irrelevant patch even
the previous one is proven wrong.  Of course, I need to change test
case in that way.

Thanks,
bin
>
> jeff
>

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

* Re: [PATCH GCC]Improve loop bound info by simplifying conversions in iv base
  2015-07-28 10:14 [PATCH GCC]Improve loop bound info by simplifying conversions in iv base Bin Cheng
  2015-08-13  8:58 ` Bin.Cheng
  2015-08-13 22:16 ` Jeff Law
@ 2015-08-14  8:32 ` Richard Biener
  2015-08-20  8:24   ` Bin.Cheng
  2 siblings, 1 reply; 7+ messages in thread
From: Richard Biener @ 2015-08-14  8:32 UTC (permalink / raw)
  To: Bin Cheng; +Cc: GCC Patches

On Tue, Jul 28, 2015 at 11:38 AM, Bin Cheng <bin.cheng@arm.com> wrote:
> Hi,
> For now, SCEV may compute iv base in the form of "(signed T)((unsigned
> T)base + step))".  This complicates other optimizations/analysis depending
> on SCEV because it's hard to dive into type conversions.  For many cases,
> such type conversions can be simplified with additional range information
> implied by loop initial conditions.  This patch does such simplification.
> With simplified iv base, loop niter analysis can compute more accurate bound
> information since sensible value range can be derived for "base+step".  For
> example, accurate loop bound&may_be_zero information is computed for cases
> added by this patch.
> The code is actually borrowed from loop_exits_before_overflow.  Moreover,
> with simplified iv base, the second case handled in that function now
> becomes the first case.  I didn't remove that part of code because it may(?)
> still be visited in scev analysis itself and simple_iv isn't an interface
> for that.
>
> Is it OK?

It looks quite special given it only handles a very specific pattern.  Did you
do any larger collecting of statistics on how many times this triggers,
esp. how many times simplify_using_initial_conditions succeeds and
how many times not?  This function is somewhat expensive.

+      || !operand_equal_p (iv->step,
+                          fold_convert (type,
+                                        TREE_OPERAND (e, 1)), 0))

operand_equal_p can handle sign-differences in integer constants,
no need to fold_convert here.  Also if you know that you are comparing
integer constants please use tree_int_cst_equal_p.

+      extreme = lower_bound_in_type (type, type);

that's a strange function to call here (with two same types).  Looks like
just wide_int_to_tree (type, wi::max/min_value (type)).

+  extreme = fold_build2 (MINUS_EXPR, type, extreme, iv->step);

so as iv->step is an INTEGER_CST please do this whole thing using
wide_ints and only build trees here:

+  e = fold_build2 (code, boolean_type_node, base, extreme);

Thanks,
Richard.

> Thanks,
> bin
>
> 2015-07-28  Bin Cheng  <bin.cheng@arm.com>
>
>         * tree-ssa-loop-niter.c (tree_simplify_using_condition): Export
>         the interface.
>         * tree-ssa-loop-niter.h (tree_simplify_using_condition): Declare.
>         * tree-scalar-evolution.c (simple_iv): Simplify type conversions
>         in iv base using loop initial conditions.
>
> gcc/testsuite/ChangeLog
> 2015-07-28  Bin Cheng  <bin.cheng@arm.com>
>
>         * gcc.dg/tree-ssa/loop-bound-2.c: New test.
>         * gcc.dg/tree-ssa/loop-bound-4.c: New test.
>         * gcc.dg/tree-ssa/loop-bound-6.c: New test.

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

* Re: [PATCH GCC]Improve loop bound info by simplifying conversions in iv base
  2015-08-14  8:32 ` Richard Biener
@ 2015-08-20  8:24   ` Bin.Cheng
  2015-08-20 11:24     ` Richard Biener
  0 siblings, 1 reply; 7+ messages in thread
From: Bin.Cheng @ 2015-08-20  8:24 UTC (permalink / raw)
  To: Richard Biener; +Cc: Bin Cheng, GCC Patches

On Fri, Aug 14, 2015 at 4:28 PM, Richard Biener
<richard.guenther@gmail.com> wrote:
> On Tue, Jul 28, 2015 at 11:38 AM, Bin Cheng <bin.cheng@arm.com> wrote:
>> Hi,
>> For now, SCEV may compute iv base in the form of "(signed T)((unsigned
>> T)base + step))".  This complicates other optimizations/analysis depending
>> on SCEV because it's hard to dive into type conversions.  For many cases,
>> such type conversions can be simplified with additional range information
>> implied by loop initial conditions.  This patch does such simplification.
>> With simplified iv base, loop niter analysis can compute more accurate bound
>> information since sensible value range can be derived for "base+step".  For
>> example, accurate loop bound&may_be_zero information is computed for cases
>> added by this patch.
>> The code is actually borrowed from loop_exits_before_overflow.  Moreover,
>> with simplified iv base, the second case handled in that function now
>> becomes the first case.  I didn't remove that part of code because it may(?)
>> still be visited in scev analysis itself and simple_iv isn't an interface
>> for that.
>>
>> Is it OK?
>
> It looks quite special given it only handles a very specific pattern.  Did you
> do any larger collecting of statistics on how many times this triggers,
> esp. how many times simplify_using_initial_conditions succeeds and
> how many times not?  This function is somewhat expensive.
Yes, this is corner case targeting induction variables of small signed
types, just like added test cases.  We need to convert it to unsigned,
do the stepping, and convert back.  I collected statistics for gcc
bootstrap and spec2k6.  The function is called about 400-500 times in
both case.  About 45% of calls succeeded in bootstrap, while only ~3%
succeeded in spec2k6.

I will prepare a new version patch if you think it's worthwhile in
terms of compilation cost and benefit.

Thanks,
bin
>
> +      || !operand_equal_p (iv->step,
> +                          fold_convert (type,
> +                                        TREE_OPERAND (e, 1)), 0))
>
> operand_equal_p can handle sign-differences in integer constants,
> no need to fold_convert here.  Also if you know that you are comparing
> integer constants please use tree_int_cst_equal_p.
>
> +      extreme = lower_bound_in_type (type, type);
>
> that's a strange function to call here (with two same types).  Looks like
> just wide_int_to_tree (type, wi::max/min_value (type)).
>
> +  extreme = fold_build2 (MINUS_EXPR, type, extreme, iv->step);
>
> so as iv->step is an INTEGER_CST please do this whole thing using
> wide_ints and only build trees here:
>
> +  e = fold_build2 (code, boolean_type_node, base, extreme);
>
> Thanks,
> Richard.
>
>> Thanks,
>> bin
>>
>> 2015-07-28  Bin Cheng  <bin.cheng@arm.com>
>>
>>         * tree-ssa-loop-niter.c (tree_simplify_using_condition): Export
>>         the interface.
>>         * tree-ssa-loop-niter.h (tree_simplify_using_condition): Declare.
>>         * tree-scalar-evolution.c (simple_iv): Simplify type conversions
>>         in iv base using loop initial conditions.
>>
>> gcc/testsuite/ChangeLog
>> 2015-07-28  Bin Cheng  <bin.cheng@arm.com>
>>
>>         * gcc.dg/tree-ssa/loop-bound-2.c: New test.
>>         * gcc.dg/tree-ssa/loop-bound-4.c: New test.
>>         * gcc.dg/tree-ssa/loop-bound-6.c: New test.

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

* Re: [PATCH GCC]Improve loop bound info by simplifying conversions in iv base
  2015-08-20  8:24   ` Bin.Cheng
@ 2015-08-20 11:24     ` Richard Biener
  0 siblings, 0 replies; 7+ messages in thread
From: Richard Biener @ 2015-08-20 11:24 UTC (permalink / raw)
  To: Bin.Cheng; +Cc: Bin Cheng, GCC Patches

On Thu, Aug 20, 2015 at 10:22 AM, Bin.Cheng <amker.cheng@gmail.com> wrote:
> On Fri, Aug 14, 2015 at 4:28 PM, Richard Biener
> <richard.guenther@gmail.com> wrote:
>> On Tue, Jul 28, 2015 at 11:38 AM, Bin Cheng <bin.cheng@arm.com> wrote:
>>> Hi,
>>> For now, SCEV may compute iv base in the form of "(signed T)((unsigned
>>> T)base + step))".  This complicates other optimizations/analysis depending
>>> on SCEV because it's hard to dive into type conversions.  For many cases,
>>> such type conversions can be simplified with additional range information
>>> implied by loop initial conditions.  This patch does such simplification.
>>> With simplified iv base, loop niter analysis can compute more accurate bound
>>> information since sensible value range can be derived for "base+step".  For
>>> example, accurate loop bound&may_be_zero information is computed for cases
>>> added by this patch.
>>> The code is actually borrowed from loop_exits_before_overflow.  Moreover,
>>> with simplified iv base, the second case handled in that function now
>>> becomes the first case.  I didn't remove that part of code because it may(?)
>>> still be visited in scev analysis itself and simple_iv isn't an interface
>>> for that.
>>>
>>> Is it OK?
>>
>> It looks quite special given it only handles a very specific pattern.  Did you
>> do any larger collecting of statistics on how many times this triggers,
>> esp. how many times simplify_using_initial_conditions succeeds and
>> how many times not?  This function is somewhat expensive.
> Yes, this is corner case targeting induction variables of small signed
> types, just like added test cases.  We need to convert it to unsigned,
> do the stepping, and convert back.  I collected statistics for gcc
> bootstrap and spec2k6.  The function is called about 400-500 times in
> both case.  About 45% of calls succeeded in bootstrap, while only ~3%
> succeeded in spec2k6.
>
> I will prepare a new version patch if you think it's worthwhile in
> terms of compilation cost and benefit.

Yes.

Richard.

> Thanks,
> bin
>>
>> +      || !operand_equal_p (iv->step,
>> +                          fold_convert (type,
>> +                                        TREE_OPERAND (e, 1)), 0))
>>
>> operand_equal_p can handle sign-differences in integer constants,
>> no need to fold_convert here.  Also if you know that you are comparing
>> integer constants please use tree_int_cst_equal_p.
>>
>> +      extreme = lower_bound_in_type (type, type);
>>
>> that's a strange function to call here (with two same types).  Looks like
>> just wide_int_to_tree (type, wi::max/min_value (type)).
>>
>> +  extreme = fold_build2 (MINUS_EXPR, type, extreme, iv->step);
>>
>> so as iv->step is an INTEGER_CST please do this whole thing using
>> wide_ints and only build trees here:
>>
>> +  e = fold_build2 (code, boolean_type_node, base, extreme);
>>
>> Thanks,
>> Richard.
>>
>>> Thanks,
>>> bin
>>>
>>> 2015-07-28  Bin Cheng  <bin.cheng@arm.com>
>>>
>>>         * tree-ssa-loop-niter.c (tree_simplify_using_condition): Export
>>>         the interface.
>>>         * tree-ssa-loop-niter.h (tree_simplify_using_condition): Declare.
>>>         * tree-scalar-evolution.c (simple_iv): Simplify type conversions
>>>         in iv base using loop initial conditions.
>>>
>>> gcc/testsuite/ChangeLog
>>> 2015-07-28  Bin Cheng  <bin.cheng@arm.com>
>>>
>>>         * gcc.dg/tree-ssa/loop-bound-2.c: New test.
>>>         * gcc.dg/tree-ssa/loop-bound-4.c: New test.
>>>         * gcc.dg/tree-ssa/loop-bound-6.c: New test.

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

end of thread, other threads:[~2015-08-20 11:22 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-07-28 10:14 [PATCH GCC]Improve loop bound info by simplifying conversions in iv base Bin Cheng
2015-08-13  8:58 ` Bin.Cheng
2015-08-13 22:16 ` Jeff Law
2015-08-14  7:29   ` Bin.Cheng
2015-08-14  8:32 ` Richard Biener
2015-08-20  8:24   ` Bin.Cheng
2015-08-20 11:24     ` Richard Biener

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).