diff mbox series

[GRAPHITE] Fix PR82449

Message ID alpine.LSU.2.20.1710061354130.6597@zhemvz.fhfr.qr
State New
Headers show
Series [GRAPHITE] Fix PR82449 | expand

Commit Message

Richard Biener Oct. 6, 2017, 11:56 a.m. UTC
The following fences off a few more SCEVs through scev_analyzable_p given
at the end we need those pass chrec_apply when getting a rename through
SCEV.

The SCEV in question is

  {(integer(kind=4)) {0, +, {1, +, 1}_1}_1, + 1}_2

which fails to chrec_apply in the CHREC_LEFT part because that part
is not affine (and we're usually not replacing a IV with a constant
where chrec_apply might handle one or the other case).

Bootstrapped and tested on x86_64-unknown-linux-gnu.

This fixes three out of the remaining 8 codegen errors in SPEC CPU 2006.

Ok?

Thanks,
Richard.

2017-10-06  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/82449
	* sese.c (can_chrec_apply): New function.
	(scev_analyzable_p): Check we can call chrec_apply on the SCEV.

	* gfortran.dg/graphite/pr82449.f: New testcase.

Comments

Sebastian Pop Oct. 6, 2017, 12:59 p.m. UTC | #1
On Fri, Oct 6, 2017 at 6:56 AM, Richard Biener <rguenther@suse.de> wrote:

>
> The following fences off a few more SCEVs through scev_analyzable_p given
> at the end we need those pass chrec_apply when getting a rename through
> SCEV.
>
> The SCEV in question is
>
>   {(integer(kind=4)) {0, +, {1, +, 1}_1}_1, + 1}_2
>
> which fails to chrec_apply in the CHREC_LEFT part because that part
> is not affine (and we're usually not replacing a IV with a constant
> where chrec_apply might handle one or the other case).
>
> Bootstrapped and tested on x86_64-unknown-linux-gnu.
>
> This fixes three out of the remaining 8 codegen errors in SPEC CPU 2006.
>
> Ok?
>
> Thanks,
> Richard.
>
> 2017-10-06  Richard Biener  <rguenther@suse.de>
>
>         PR tree-optimization/82449
>         * sese.c (can_chrec_apply): New function.
>         (scev_analyzable_p): Check we can call chrec_apply on the SCEV.
>
>         * gfortran.dg/graphite/pr82449.f: New testcase.
>
> Index: gcc/sese.c
> ===================================================================
> --- gcc/sese.c  (revision 253477)
> +++ gcc/sese.c  (working copy)
> @@ -421,6 +421,27 @@ invariant_in_sese_p_rec (tree t, const s
>    return true;
>  }
>
> +/* Check whether we can call chrec_apply on CHREC with arbitrary X and
> VAR.  */
> +
> +static bool
> +can_chrec_apply (tree chrec)
> +{
> +  if (automatically_generated_chrec_p (chrec))
> +    return false;
> +  switch (TREE_CODE (chrec))
> +    {
> +    case POLYNOMIAL_CHREC:
> +      if (evolution_function_is_affine_p (chrec))
> +       return (can_chrec_apply (CHREC_LEFT (chrec))
> +               && can_chrec_apply (CHREC_RIGHT (chrec)));
> +      return false;
> +    CASE_CONVERT:
> +      return can_chrec_apply (TREE_OPERAND (chrec, 0));
> +    default:;
> +      return tree_does_not_contain_chrecs (chrec);
> +    }
> +}
> +
>  /* Return true when DEF can be analyzed in REGION by the scalar
>     evolution analyzer.  */
>
> @@ -449,6 +470,7 @@ scev_analyzable_p (tree def, sese_l &reg
>         || !defined_in_sese_p (scev, region))
>      && (tree_does_not_contain_chrecs (scev)
>         || evolution_function_is_affine_p (scev))
>

Why isn't evolution_function_is_affine_p returning false on {0, +, {1, +,
1}_1}_1?
This is quadratic.



> +    && can_chrec_apply (scev)
>      && (! loop
>         || ! loop_in_sese_p (loop, region)
>         || ! chrec_contains_symbols_defined_in_loop (scev, loop->num));
> Index: gcc/testsuite/gfortran.dg/graphite/pr82449.f
> ===================================================================
> --- gcc/testsuite/gfortran.dg/graphite/pr82449.f        (nonexistent)
> +++ gcc/testsuite/gfortran.dg/graphite/pr82449.f        (working copy)
> @@ -0,0 +1,11 @@
> +! { dg-do compile }
> +! { dg-options "-O2 -floop-nest-optimize" }
> +
> +      SUBROUTINE JDFIDX(MKL,KGSH)
> +      DIMENSION MKL(6,6)
> +      NKL=0
> +  400 DO 40 KG = 1,KGSH
> +      DO 40 LG = 1,KG
> +      NKL = NKL + 1
> +   40 MKL(LG,KG) = NKL
> +      END
>
Richard Biener Oct. 6, 2017, 1:33 p.m. UTC | #2
On Fri, 6 Oct 2017, Sebastian Pop wrote:

> On Fri, Oct 6, 2017 at 6:56 AM, Richard Biener <rguenther@suse.de> wrote:
> 
> >
> > The following fences off a few more SCEVs through scev_analyzable_p given
> > at the end we need those pass chrec_apply when getting a rename through
> > SCEV.
> >
> > The SCEV in question is
> >
> >   {(integer(kind=4)) {0, +, {1, +, 1}_1}_1, + 1}_2
> >
> > which fails to chrec_apply in the CHREC_LEFT part because that part
> > is not affine (and we're usually not replacing a IV with a constant
> > where chrec_apply might handle one or the other case).
> >
> > Bootstrapped and tested on x86_64-unknown-linux-gnu.
> >
> > This fixes three out of the remaining 8 codegen errors in SPEC CPU 2006.
> >
> > Ok?
> >
> > Thanks,
> > Richard.
> >
> > 2017-10-06  Richard Biener  <rguenther@suse.de>
> >
> >         PR tree-optimization/82449
> >         * sese.c (can_chrec_apply): New function.
> >         (scev_analyzable_p): Check we can call chrec_apply on the SCEV.
> >
> >         * gfortran.dg/graphite/pr82449.f: New testcase.
> >
> > Index: gcc/sese.c
> > ===================================================================
> > --- gcc/sese.c  (revision 253477)
> > +++ gcc/sese.c  (working copy)
> > @@ -421,6 +421,27 @@ invariant_in_sese_p_rec (tree t, const s
> >    return true;
> >  }
> >
> > +/* Check whether we can call chrec_apply on CHREC with arbitrary X and
> > VAR.  */
> > +
> > +static bool
> > +can_chrec_apply (tree chrec)
> > +{
> > +  if (automatically_generated_chrec_p (chrec))
> > +    return false;
> > +  switch (TREE_CODE (chrec))
> > +    {
> > +    case POLYNOMIAL_CHREC:
> > +      if (evolution_function_is_affine_p (chrec))
> > +       return (can_chrec_apply (CHREC_LEFT (chrec))
> > +               && can_chrec_apply (CHREC_RIGHT (chrec)));
> > +      return false;
> > +    CASE_CONVERT:
> > +      return can_chrec_apply (TREE_OPERAND (chrec, 0));
> > +    default:;
> > +      return tree_does_not_contain_chrecs (chrec);
> > +    }
> > +}
> > +
> >  /* Return true when DEF can be analyzed in REGION by the scalar
> >     evolution analyzer.  */
> >
> > @@ -449,6 +470,7 @@ scev_analyzable_p (tree def, sese_l &reg
> >         || !defined_in_sese_p (scev, region))
> >      && (tree_does_not_contain_chrecs (scev)
> >         || evolution_function_is_affine_p (scev))
> >
> 
> Why isn't evolution_function_is_affine_p returning false on {0, +, {1, +,
> 1}_1}_1?
> This is quadratic.

It returns false on that but the CHREC we ask it on is

{(integer(kind=4)) {0, +, {1, +, 1}_1}_1, + 1}_2

only the initial value is "quadratic".

Richard.
Sebastian Pop Oct. 6, 2017, 2:47 p.m. UTC | #3
On Fri, Oct 6, 2017 at 8:33 AM, Richard Biener <rguenther@suse.de> wrote:

> On Fri, 6 Oct 2017, Sebastian Pop wrote:
>
> > On Fri, Oct 6, 2017 at 6:56 AM, Richard Biener <rguenther@suse.de>
> wrote:
> >
> > >
> > > The following fences off a few more SCEVs through scev_analyzable_p
> given
> > > at the end we need those pass chrec_apply when getting a rename through
> > > SCEV.
> > >
> > > The SCEV in question is
> > >
> > >   {(integer(kind=4)) {0, +, {1, +, 1}_1}_1, + 1}_2
> > >
> > > which fails to chrec_apply in the CHREC_LEFT part because that part
> > > is not affine (and we're usually not replacing a IV with a constant
> > > where chrec_apply might handle one or the other case).
> > >
> > > Bootstrapped and tested on x86_64-unknown-linux-gnu.
> > >
> > > This fixes three out of the remaining 8 codegen errors in SPEC CPU
> 2006.
> > >
> > > Ok?
> > >
> > > Thanks,
> > > Richard.
> > >
> > > 2017-10-06  Richard Biener  <rguenther@suse.de>
> > >
> > >         PR tree-optimization/82449
> > >         * sese.c (can_chrec_apply): New function.
> > >         (scev_analyzable_p): Check we can call chrec_apply on the SCEV.
> > >
> > >         * gfortran.dg/graphite/pr82449.f: New testcase.
>
> >
> > > Index: gcc/sese.c
> > > ===================================================================
> > > --- gcc/sese.c  (revision 253477)
> > > +++ gcc/sese.c  (working copy)
> > > @@ -421,6 +421,27 @@ invariant_in_sese_p_rec (tree t, const s
> > >    return true;
> > >  }
> > >
> > > +/* Check whether we can call chrec_apply on CHREC with arbitrary X and
> > > VAR.  */
>
> > +
> > > +static bool
> > > +can_chrec_apply (tree chrec)
>

Could we use scev_is_linear_expression ?
It seems like can_chrec_apply has the same semantics.


> > > +{
> > > +  if (automatically_generated_chrec_p (chrec))
> > > +    return false;
> > > +  switch (TREE_CODE (chrec))
> > > +    {
> > > +    case POLYNOMIAL_CHREC:
> > > +      if (evolution_function_is_affine_p (chrec))
> > > +       return (can_chrec_apply (CHREC_LEFT (chrec))
> > > +               && can_chrec_apply (CHREC_RIGHT (chrec)));
> > > +      return false;
> > > +    CASE_CONVERT:
> > > +      return can_chrec_apply (TREE_OPERAND (chrec, 0));
> > > +    default:;
> > > +      return tree_does_not_contain_chrecs (chrec);
> > > +    }
> > > +}
> > > +
> > >  /* Return true when DEF can be analyzed in REGION by the scalar
> > >     evolution analyzer.  */
> > >
> > > @@ -449,6 +470,7 @@ scev_analyzable_p (tree def, sese_l &reg
> > >         || !defined_in_sese_p (scev, region))
> > >      && (tree_does_not_contain_chrecs (scev)
> > >         || evolution_function_is_affine_p (scev))
> > >
> >
> > Why isn't evolution_function_is_affine_p returning false on {0, +, {1, +,
> > 1}_1}_1?
> > This is quadratic.
>
> It returns false on that but the CHREC we ask it on is
>
> {(integer(kind=4)) {0, +, {1, +, 1}_1}_1, + 1}_2
>
> only the initial value is "quadratic".
>

Right.
If I understand correctly, the scop is the body of loop_1,
and we do not need to represent the quadratic evolution
of the initial value.
Richard Biener Oct. 9, 2017, 8:08 a.m. UTC | #4
On Fri, 6 Oct 2017, Sebastian Pop wrote:

> On Fri, Oct 6, 2017 at 8:33 AM, Richard Biener <rguenther@suse.de> wrote:
> 
> > On Fri, 6 Oct 2017, Sebastian Pop wrote:
> >
> > > On Fri, Oct 6, 2017 at 6:56 AM, Richard Biener <rguenther@suse.de>
> > wrote:
> > >
> > > >
> > > > The following fences off a few more SCEVs through scev_analyzable_p
> > given
> > > > at the end we need those pass chrec_apply when getting a rename through
> > > > SCEV.
> > > >
> > > > The SCEV in question is
> > > >
> > > >   {(integer(kind=4)) {0, +, {1, +, 1}_1}_1, + 1}_2
> > > >
> > > > which fails to chrec_apply in the CHREC_LEFT part because that part
> > > > is not affine (and we're usually not replacing a IV with a constant
> > > > where chrec_apply might handle one or the other case).
> > > >
> > > > Bootstrapped and tested on x86_64-unknown-linux-gnu.
> > > >
> > > > This fixes three out of the remaining 8 codegen errors in SPEC CPU
> > 2006.
> > > >
> > > > Ok?
> > > >
> > > > Thanks,
> > > > Richard.
> > > >
> > > > 2017-10-06  Richard Biener  <rguenther@suse.de>
> > > >
> > > >         PR tree-optimization/82449
> > > >         * sese.c (can_chrec_apply): New function.
> > > >         (scev_analyzable_p): Check we can call chrec_apply on the SCEV.
> > > >
> > > >         * gfortran.dg/graphite/pr82449.f: New testcase.
> >
> > >
> > > > Index: gcc/sese.c
> > > > ===================================================================
> > > > --- gcc/sese.c  (revision 253477)
> > > > +++ gcc/sese.c  (working copy)
> > > > @@ -421,6 +421,27 @@ invariant_in_sese_p_rec (tree t, const s
> > > >    return true;
> > > >  }
> > > >
> > > > +/* Check whether we can call chrec_apply on CHREC with arbitrary X and
> > > > VAR.  */
> >
> > > +
> > > > +static bool
> > > > +can_chrec_apply (tree chrec)
> >
> 
> Could we use scev_is_linear_expression ?
> It seems like can_chrec_apply has the same semantics.

Looks like that works.

> 
> > > > +{
> > > > +  if (automatically_generated_chrec_p (chrec))
> > > > +    return false;
> > > > +  switch (TREE_CODE (chrec))
> > > > +    {
> > > > +    case POLYNOMIAL_CHREC:
> > > > +      if (evolution_function_is_affine_p (chrec))
> > > > +       return (can_chrec_apply (CHREC_LEFT (chrec))
> > > > +               && can_chrec_apply (CHREC_RIGHT (chrec)));
> > > > +      return false;
> > > > +    CASE_CONVERT:
> > > > +      return can_chrec_apply (TREE_OPERAND (chrec, 0));
> > > > +    default:;
> > > > +      return tree_does_not_contain_chrecs (chrec);
> > > > +    }
> > > > +}
> > > > +
> > > >  /* Return true when DEF can be analyzed in REGION by the scalar
> > > >     evolution analyzer.  */
> > > >
> > > > @@ -449,6 +470,7 @@ scev_analyzable_p (tree def, sese_l &reg
> > > >         || !defined_in_sese_p (scev, region))
> > > >      && (tree_does_not_contain_chrecs (scev)
> > > >         || evolution_function_is_affine_p (scev))
> > > >
> > >
> > > Why isn't evolution_function_is_affine_p returning false on {0, +, {1, +,
> > > 1}_1}_1?
> > > This is quadratic.
> >
> > It returns false on that but the CHREC we ask it on is
> >
> > {(integer(kind=4)) {0, +, {1, +, 1}_1}_1, + 1}_2
> >
> > only the initial value is "quadratic".
> >
> 
> Right.
> If I understand correctly, the scop is the body of loop_1,
> and we do not need to represent the quadratic evolution
> of the initial value.

Giving the following full testing now.

Richard.

2017-10-09  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/82449
	* sese.c (scev_analyzable_p): Check whether the SCEV is linear.

	* gfortran.dg/graphite/pr82449.f: New testcase.

Index: gcc/sese.c
===================================================================
--- gcc/sese.c	(revision 253486)
+++ gcc/sese.c	(working copy)
@@ -444,14 +444,13 @@ scev_analyzable_p (tree def, sese_l &reg
   loop = loop_containing_stmt (SSA_NAME_DEF_STMT (def));
   scev = scalar_evolution_in_region (region, loop, def);
 
-  return !chrec_contains_undetermined (scev)
-    && (TREE_CODE (scev) != SSA_NAME
-	|| !defined_in_sese_p (scev, region))
-    && (tree_does_not_contain_chrecs (scev)
-	|| evolution_function_is_affine_p (scev))
-    && (! loop
-	|| ! loop_in_sese_p (loop, region)
-	|| ! chrec_contains_symbols_defined_in_loop (scev, loop->num));
+  return (!chrec_contains_undetermined (scev)
+	  && (TREE_CODE (scev) != SSA_NAME
+	      || !defined_in_sese_p (scev, region))
+	  && scev_is_linear_expression (scev)
+	  && (! loop
+	      || ! loop_in_sese_p (loop, region)
+	      || ! chrec_contains_symbols_defined_in_loop (scev, loop->num)));
 }
 
 /* Returns the scalar evolution of T in REGION.  Every variable that
Index: gcc/testsuite/gfortran.dg/graphite/pr82449.f
===================================================================
--- gcc/testsuite/gfortran.dg/graphite/pr82449.f	(nonexistent)
+++ gcc/testsuite/gfortran.dg/graphite/pr82449.f	(working copy)
@@ -0,0 +1,11 @@
+! { dg-do compile }
+! { dg-options "-O2 -floop-nest-optimize" }
+
+      SUBROUTINE JDFIDX(MKL,KGSH)
+      DIMENSION MKL(6,6)
+      NKL=0
+  400 DO 40 KG = 1,KGSH
+      DO 40 LG = 1,KG
+      NKL = NKL + 1
+   40 MKL(LG,KG) = NKL
+      END
Richard Biener Oct. 9, 2017, 1:48 p.m. UTC | #5
On Mon, 9 Oct 2017, Richard Biener wrote:

> On Fri, 6 Oct 2017, Sebastian Pop wrote:
> 
> > On Fri, Oct 6, 2017 at 8:33 AM, Richard Biener <rguenther@suse.de> wrote:
> > 
> > > On Fri, 6 Oct 2017, Sebastian Pop wrote:
> > >
> > > > On Fri, Oct 6, 2017 at 6:56 AM, Richard Biener <rguenther@suse.de>
> > > wrote:
> > > >
> > > > >
> > > > > The following fences off a few more SCEVs through scev_analyzable_p
> > > given
> > > > > at the end we need those pass chrec_apply when getting a rename through
> > > > > SCEV.
> > > > >
> > > > > The SCEV in question is
> > > > >
> > > > >   {(integer(kind=4)) {0, +, {1, +, 1}_1}_1, + 1}_2
> > > > >
> > > > > which fails to chrec_apply in the CHREC_LEFT part because that part
> > > > > is not affine (and we're usually not replacing a IV with a constant
> > > > > where chrec_apply might handle one or the other case).
> > > > >
> > > > > Bootstrapped and tested on x86_64-unknown-linux-gnu.
> > > > >
> > > > > This fixes three out of the remaining 8 codegen errors in SPEC CPU
> > > 2006.
> > > > >
> > > > > Ok?
> > > > >
> > > > > Thanks,
> > > > > Richard.
> > > > >
> > > > > 2017-10-06  Richard Biener  <rguenther@suse.de>
> > > > >
> > > > >         PR tree-optimization/82449
> > > > >         * sese.c (can_chrec_apply): New function.
> > > > >         (scev_analyzable_p): Check we can call chrec_apply on the SCEV.
> > > > >
> > > > >         * gfortran.dg/graphite/pr82449.f: New testcase.
> > >
> > > >
> > > > > Index: gcc/sese.c
> > > > > ===================================================================
> > > > > --- gcc/sese.c  (revision 253477)
> > > > > +++ gcc/sese.c  (working copy)
> > > > > @@ -421,6 +421,27 @@ invariant_in_sese_p_rec (tree t, const s
> > > > >    return true;
> > > > >  }
> > > > >
> > > > > +/* Check whether we can call chrec_apply on CHREC with arbitrary X and
> > > > > VAR.  */
> > >
> > > > +
> > > > > +static bool
> > > > > +can_chrec_apply (tree chrec)
> > >
> > 
> > Could we use scev_is_linear_expression ?
> > It seems like can_chrec_apply has the same semantics.
> 
> Looks like that works.
> 
> > 
> > > > > +{
> > > > > +  if (automatically_generated_chrec_p (chrec))
> > > > > +    return false;
> > > > > +  switch (TREE_CODE (chrec))
> > > > > +    {
> > > > > +    case POLYNOMIAL_CHREC:
> > > > > +      if (evolution_function_is_affine_p (chrec))
> > > > > +       return (can_chrec_apply (CHREC_LEFT (chrec))
> > > > > +               && can_chrec_apply (CHREC_RIGHT (chrec)));
> > > > > +      return false;
> > > > > +    CASE_CONVERT:
> > > > > +      return can_chrec_apply (TREE_OPERAND (chrec, 0));
> > > > > +    default:;
> > > > > +      return tree_does_not_contain_chrecs (chrec);
> > > > > +    }
> > > > > +}
> > > > > +
> > > > >  /* Return true when DEF can be analyzed in REGION by the scalar
> > > > >     evolution analyzer.  */
> > > > >
> > > > > @@ -449,6 +470,7 @@ scev_analyzable_p (tree def, sese_l &reg
> > > > >         || !defined_in_sese_p (scev, region))
> > > > >      && (tree_does_not_contain_chrecs (scev)
> > > > >         || evolution_function_is_affine_p (scev))
> > > > >
> > > >
> > > > Why isn't evolution_function_is_affine_p returning false on {0, +, {1, +,
> > > > 1}_1}_1?
> > > > This is quadratic.
> > >
> > > It returns false on that but the CHREC we ask it on is
> > >
> > > {(integer(kind=4)) {0, +, {1, +, 1}_1}_1, + 1}_2
> > >
> > > only the initial value is "quadratic".
> > >
> > 
> > Right.
> > If I understand correctly, the scop is the body of loop_1,
> > and we do not need to represent the quadratic evolution
> > of the initial value.
> 
> Giving the following full testing now.

And the following is what I have applied after bootstrap / testing
on x86_64-unknown-linux-gnu.

As you can see I needed some adjustments to not reject otherwise
valid SCEVs with address constants.

Richard.

2017-10-09  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/82449
	* sese.c (scev_analyzable_p): Check whether the SCEV is linear.
	* tree-chrec.h (evolution_function_is_constant_p): Adjust to
	allow constant addresses.
	* tree-chrec.c (scev_is_linear_expression): Constant evolutions
	are linear.

	* gfortran.dg/graphite/pr82449.f: New testcase.

Index: gcc/sese.c
===================================================================
--- gcc/sese.c	(revision 253486)
+++ gcc/sese.c	(working copy)
@@ -444,14 +444,13 @@ scev_analyzable_p (tree def, sese_l &reg
   loop = loop_containing_stmt (SSA_NAME_DEF_STMT (def));
   scev = scalar_evolution_in_region (region, loop, def);
 
-  return !chrec_contains_undetermined (scev)
-    && (TREE_CODE (scev) != SSA_NAME
-	|| !defined_in_sese_p (scev, region))
-    && (tree_does_not_contain_chrecs (scev)
-	|| evolution_function_is_affine_p (scev))
-    && (! loop
-	|| ! loop_in_sese_p (loop, region)
-	|| ! chrec_contains_symbols_defined_in_loop (scev, loop->num));
+  return (!chrec_contains_undetermined (scev)
+	  && (TREE_CODE (scev) != SSA_NAME
+	      || !defined_in_sese_p (scev, region))
+	  && scev_is_linear_expression (scev)
+	  && (! loop
+	      || ! loop_in_sese_p (loop, region)
+	      || ! chrec_contains_symbols_defined_in_loop (scev, loop->num)));
 }
 
 /* Returns the scalar evolution of T in REGION.  Every variable that
Index: gcc/testsuite/gfortran.dg/graphite/pr82449.f
===================================================================
--- gcc/testsuite/gfortran.dg/graphite/pr82449.f	(nonexistent)
+++ gcc/testsuite/gfortran.dg/graphite/pr82449.f	(working copy)
@@ -0,0 +1,11 @@
+! { dg-do compile }
+! { dg-options "-O2 -floop-nest-optimize" }
+
+      SUBROUTINE JDFIDX(MKL,KGSH)
+      DIMENSION MKL(6,6)
+      NKL=0
+  400 DO 40 KG = 1,KGSH
+      DO 40 LG = 1,KG
+      NKL = NKL + 1
+   40 MKL(LG,KG) = NKL
+      END
Index: gcc/tree-chrec.c
===================================================================
--- gcc/tree-chrec.c	(revision 253486)
+++ gcc/tree-chrec.c	(working copy)
@@ -1610,6 +1610,9 @@ operator_is_linear (tree scev)
 bool
 scev_is_linear_expression (tree scev)
 {
+  if (evolution_function_is_constant_p (scev))
+    return true;
+
   if (scev == NULL
       || !operator_is_linear (scev))
     return false;
Index: gcc/tree-chrec.h
===================================================================
--- gcc/tree-chrec.h	(revision 253486)
+++ gcc/tree-chrec.h	(working copy)
@@ -169,15 +169,9 @@ evolution_function_is_constant_p (const_
   if (chrec == NULL_TREE)
     return false;
 
-  switch (TREE_CODE (chrec))
-    {
-    case INTEGER_CST:
-    case REAL_CST:
-      return true;
-
-    default:
-      return false;
-    }
+  if (CONSTANT_CLASS_P (chrec))
+    return true;
+  return is_gimple_min_invariant (chrec);
 }
 
 /* Determine whether CHREC is an affine evolution function in LOOPNUM.  */
Sebastian Pop Oct. 11, 2017, 1:50 p.m. UTC | #6
On Oct 9, 2017 8:48 AM, "Richard Biener" <rguenther@suse.de> wrote:

On Mon, 9 Oct 2017, Richard Biener wrote:

> On Fri, 6 Oct 2017, Sebastian Pop wrote:
>
> > On Fri, Oct 6, 2017 at 8:33 AM, Richard Biener <rguenther@suse.de>
wrote:
> >
> > > On Fri, 6 Oct 2017, Sebastian Pop wrote:
> > >
> > > > On Fri, Oct 6, 2017 at 6:56 AM, Richard Biener <rguenther@suse.de>
> > > wrote:
> > > >
> > > > >
> > > > > The following fences off a few more SCEVs through
scev_analyzable_p
> > > given
> > > > > at the end we need those pass chrec_apply when getting a rename
through
> > > > > SCEV.
> > > > >
> > > > > The SCEV in question is
> > > > >
> > > > >   {(integer(kind=4)) {0, +, {1, +, 1}_1}_1, + 1}_2
> > > > >
> > > > > which fails to chrec_apply in the CHREC_LEFT part because that
part
> > > > > is not affine (and we're usually not replacing a IV with a
constant
> > > > > where chrec_apply might handle one or the other case).
> > > > >
> > > > > Bootstrapped and tested on x86_64-unknown-linux-gnu.
> > > > >
> > > > > This fixes three out of the remaining 8 codegen errors in SPEC CPU
> > > 2006.
> > > > >
> > > > > Ok?
> > > > >
> > > > > Thanks,
> > > > > Richard.
> > > > >
> > > > > 2017-10-06  Richard Biener  <rguenther@suse.de>
> > > > >
> > > > >         PR tree-optimization/82449
> > > > >         * sese.c (can_chrec_apply): New function.
> > > > >         (scev_analyzable_p): Check we can call chrec_apply on the
SCEV.
> > > > >
> > > > >         * gfortran.dg/graphite/pr82449.f: New testcase.
> > >
> > > >
> > > > > Index: gcc/sese.c
> > > > > ============================================================
=======
> > > > > --- gcc/sese.c  (revision 253477)
> > > > > +++ gcc/sese.c  (working copy)
> > > > > @@ -421,6 +421,27 @@ invariant_in_sese_p_rec (tree t, const s
> > > > >    return true;
> > > > >  }
> > > > >
> > > > > +/* Check whether we can call chrec_apply on CHREC with arbitrary
X and
> > > > > VAR.  */
> > >
> > > > +
> > > > > +static bool
> > > > > +can_chrec_apply (tree chrec)
> > >
> >
> > Could we use scev_is_linear_expression ?
> > It seems like can_chrec_apply has the same semantics.
>
> Looks like that works.
>
> >
> > > > > +{
> > > > > +  if (automatically_generated_chrec_p (chrec))
> > > > > +    return false;
> > > > > +  switch (TREE_CODE (chrec))
> > > > > +    {
> > > > > +    case POLYNOMIAL_CHREC:
> > > > > +      if (evolution_function_is_affine_p (chrec))
> > > > > +       return (can_chrec_apply (CHREC_LEFT (chrec))
> > > > > +               && can_chrec_apply (CHREC_RIGHT (chrec)));
> > > > > +      return false;
> > > > > +    CASE_CONVERT:
> > > > > +      return can_chrec_apply (TREE_OPERAND (chrec, 0));
> > > > > +    default:;
> > > > > +      return tree_does_not_contain_chrecs (chrec);
> > > > > +    }
> > > > > +}
> > > > > +
> > > > >  /* Return true when DEF can be analyzed in REGION by the scalar
> > > > >     evolution analyzer.  */
> > > > >
> > > > > @@ -449,6 +470,7 @@ scev_analyzable_p (tree def, sese_l &reg
> > > > >         || !defined_in_sese_p (scev, region))
> > > > >      && (tree_does_not_contain_chrecs (scev)
> > > > >         || evolution_function_is_affine_p (scev))
> > > > >
> > > >
> > > > Why isn't evolution_function_is_affine_p returning false on {0, +,
{1, +,
> > > > 1}_1}_1?
> > > > This is quadratic.
> > >
> > > It returns false on that but the CHREC we ask it on is
> > >
> > > {(integer(kind=4)) {0, +, {1, +, 1}_1}_1, + 1}_2
> > >
> > > only the initial value is "quadratic".
> > >
> >
> > Right.
> > If I understand correctly, the scop is the body of loop_1,
> > and we do not need to represent the quadratic evolution
> > of the initial value.
>
> Giving the following full testing now.

And the following is what I have applied after bootstrap / testing
on x86_64-unknown-linux-gnu.

As you can see I needed some adjustments to not reject otherwise
valid SCEVs with address constants.

Richard.

2017-10-09  Richard Biener  <rguenther@suse.de>

        PR tree-optimization/82449
        * sese.c (scev_analyzable_p): Check whether the SCEV is linear.
        * tree-chrec.h (evolution_function_is_constant_p): Adjust to
        allow constant addresses.
        * tree-chrec.c (scev_is_linear_expression): Constant evolutions
        are linear.

        * gfortran.dg/graphite/pr82449.f: New testcase.


Looks good to me.

Thanks.


Index: gcc/sese.c
===================================================================
--- gcc/sese.c  (revision 253486)
+++ gcc/sese.c  (working copy)
@@ -444,14 +444,13 @@ scev_analyzable_p (tree def, sese_l &reg
   loop = loop_containing_stmt (SSA_NAME_DEF_STMT (def));
   scev = scalar_evolution_in_region (region, loop, def);

-  return !chrec_contains_undetermined (scev)
-    && (TREE_CODE (scev) != SSA_NAME
-       || !defined_in_sese_p (scev, region))
-    && (tree_does_not_contain_chrecs (scev)
-       || evolution_function_is_affine_p (scev))
-    && (! loop
-       || ! loop_in_sese_p (loop, region)
-       || ! chrec_contains_symbols_defined_in_loop (scev, loop->num));
+  return (!chrec_contains_undetermined (scev)
+         && (TREE_CODE (scev) != SSA_NAME
+             || !defined_in_sese_p (scev, region))
+         && scev_is_linear_expression (scev)
+         && (! loop
+             || ! loop_in_sese_p (loop, region)
+             || ! chrec_contains_symbols_defined_in_loop (scev,
loop->num)));
 }

 /* Returns the scalar evolution of T in REGION.  Every variable that
Index: gcc/testsuite/gfortran.dg/graphite/pr82449.f
===================================================================
--- gcc/testsuite/gfortran.dg/graphite/pr82449.f        (nonexistent)
+++ gcc/testsuite/gfortran.dg/graphite/pr82449.f        (working copy)
@@ -0,0 +1,11 @@
+! { dg-do compile }
+! { dg-options "-O2 -floop-nest-optimize" }
+
+      SUBROUTINE JDFIDX(MKL,KGSH)
+      DIMENSION MKL(6,6)
+      NKL=0
+  400 DO 40 KG = 1,KGSH
+      DO 40 LG = 1,KG
+      NKL = NKL + 1
+   40 MKL(LG,KG) = NKL
+      END
Index: gcc/tree-chrec.c
===================================================================
--- gcc/tree-chrec.c    (revision 253486)
+++ gcc/tree-chrec.c    (working copy)
@@ -1610,6 +1610,9 @@ operator_is_linear (tree scev)
 bool
 scev_is_linear_expression (tree scev)
 {
+  if (evolution_function_is_constant_p (scev))
+    return true;
+
   if (scev == NULL
       || !operator_is_linear (scev))
     return false;
Index: gcc/tree-chrec.h
===================================================================
--- gcc/tree-chrec.h    (revision 253486)
+++ gcc/tree-chrec.h    (working copy)
@@ -169,15 +169,9 @@ evolution_function_is_constant_p (const_
   if (chrec == NULL_TREE)
     return false;

-  switch (TREE_CODE (chrec))
-    {
-    case INTEGER_CST:
-    case REAL_CST:
-      return true;
-
-    default:
-      return false;
-    }
+  if (CONSTANT_CLASS_P (chrec))
+    return true;
+  return is_gimple_min_invariant (chrec);
 }

 /* Determine whether CHREC is an affine evolution function in LOOPNUM.  */
diff mbox series

Patch

Index: gcc/sese.c
===================================================================
--- gcc/sese.c	(revision 253477)
+++ gcc/sese.c	(working copy)
@@ -421,6 +421,27 @@  invariant_in_sese_p_rec (tree t, const s
   return true;
 }
 
+/* Check whether we can call chrec_apply on CHREC with arbitrary X and VAR.  */
+
+static bool
+can_chrec_apply (tree chrec)
+{
+  if (automatically_generated_chrec_p (chrec))
+    return false;
+  switch (TREE_CODE (chrec))
+    {
+    case POLYNOMIAL_CHREC:
+      if (evolution_function_is_affine_p (chrec))
+	return (can_chrec_apply (CHREC_LEFT (chrec))
+		&& can_chrec_apply (CHREC_RIGHT (chrec)));
+      return false;
+    CASE_CONVERT:
+      return can_chrec_apply (TREE_OPERAND (chrec, 0));
+    default:;
+      return tree_does_not_contain_chrecs (chrec);
+    }
+}
+
 /* Return true when DEF can be analyzed in REGION by the scalar
    evolution analyzer.  */
 
@@ -449,6 +470,7 @@  scev_analyzable_p (tree def, sese_l &reg
 	|| !defined_in_sese_p (scev, region))
     && (tree_does_not_contain_chrecs (scev)
 	|| evolution_function_is_affine_p (scev))
+    && can_chrec_apply (scev)
     && (! loop
 	|| ! loop_in_sese_p (loop, region)
 	|| ! chrec_contains_symbols_defined_in_loop (scev, loop->num));
Index: gcc/testsuite/gfortran.dg/graphite/pr82449.f
===================================================================
--- gcc/testsuite/gfortran.dg/graphite/pr82449.f	(nonexistent)
+++ gcc/testsuite/gfortran.dg/graphite/pr82449.f	(working copy)
@@ -0,0 +1,11 @@ 
+! { dg-do compile }
+! { dg-options "-O2 -floop-nest-optimize" }
+
+      SUBROUTINE JDFIDX(MKL,KGSH)
+      DIMENSION MKL(6,6)
+      NKL=0
+  400 DO 40 KG = 1,KGSH
+      DO 40 LG = 1,KG
+      NKL = NKL + 1
+   40 MKL(LG,KG) = NKL
+      END