Patchwork Allow not simple ivs in SLP

login
register
mail settings
Submitter Ira Rosen
Date Sept. 14, 2011, 12:01 p.m.
Message ID <CAKSNEw4PQKiX_MCtw5Go+K7i=ROjrtOar3dWKvKGYCNLqN75Kg@mail.gmail.com>
Download mbox | patch
Permalink /patch/114667/
State New
Headers show

Comments

Ira Rosen - Sept. 14, 2011, 12:01 p.m.
Hi,

This patch makes data-refs analysis to not fail if simple_iv returns
false in basic block SLP.

Bootstrapped and tested on powerpc64-suse-linux.
OK for mainline?

Thanks,
Ira

ChangeLog:

     * tree-data-ref.c (dr_analyze_innermost): Rename to...
     (dr_analyze_innermost_1): ... this.  Add new argument.
     Allow not simple iv if analyzing basic block.
     (dr_analyze_innermost): Call dr_analyze_innermost_1.
     (create_data_ref): Call dr_analyze_innermost_1.

testsuite/ChangeLog:

     * gcc.dg/vect/bb-slp-24.c: New test.

+
Richard Guenther - Sept. 23, 2011, 8:09 p.m.
On Wed, Sep 14, 2011 at 2:01 PM, Ira Rosen <ira.rosen@linaro.org> wrote:
> Hi,
>
> This patch makes data-refs analysis to not fail if simple_iv returns
> false in basic block SLP.
>
> Bootstrapped and tested on powerpc64-suse-linux.
> OK for mainline?

Ok if you instead of wrapping dr_analyze_innermost change the remaining
callers to pass the loop nest parameter instead.

Thanks,
Richard.

> Thanks,
> Ira
>
> ChangeLog:
>
>     * tree-data-ref.c (dr_analyze_innermost): Rename to...
>     (dr_analyze_innermost_1): ... this.  Add new argument.
>     Allow not simple iv if analyzing basic block.
>     (dr_analyze_innermost): Call dr_analyze_innermost_1.
>     (create_data_ref): Call dr_analyze_innermost_1.
>
> testsuite/ChangeLog:
>
>     * gcc.dg/vect/bb-slp-24.c: New test.
>
> Index: tree-data-ref.c
> ===================================================================
> --- tree-data-ref.c     (revision 178755)
> +++ tree-data-ref.c     (working copy)
> @@ -722,11 +722,11 @@ canonicalize_base_object_address (tree addr)
>  }
>
>  /* Analyzes the behavior of the memory reference DR in the innermost loop or
> -   basic block that contains it. Returns true if analysis succeed or false
> +   basic block that contains it.  Returns true if analysis succeed or false
>    otherwise.  */
>
> -bool
> -dr_analyze_innermost (struct data_reference *dr)
> +static bool
> +dr_analyze_innermost_1 (struct data_reference *dr, struct loop *nest)
>  {
>   gimple stmt = DR_STMT (dr);
>   struct loop *loop = loop_containing_stmt (stmt);
> @@ -769,14 +769,25 @@ canonicalize_base_object_address (tree addr)
>     }
>   else
>     base = build_fold_addr_expr (base);
> +
>   if (in_loop)
>     {
>       if (!simple_iv (loop, loop_containing_stmt (stmt), base, &base_iv,
>                       false))
>         {
> -          if (dump_file && (dump_flags & TDF_DETAILS))
> -           fprintf (dump_file, "failed: evolution of base is not affine.\n");
> -          return false;
> +          if (nest)
> +            {
> +              if (dump_file && (dump_flags & TDF_DETAILS))
> +               fprintf (dump_file, "failed: evolution of base is not"
> +                                    " affine.\n");
> +                return false;
> +            }
> +          else
> +            {
> +              base_iv.base = base;
> +              base_iv.step = ssize_int (0);
> +              base_iv.no_overflow = true;
> +            }
>         }
>     }
>   else
> @@ -801,10 +812,18 @@ canonicalize_base_object_address (tree addr)
>       else if (!simple_iv (loop, loop_containing_stmt (stmt),
>                            poffset, &offset_iv, false))
>         {
> -          if (dump_file && (dump_flags & TDF_DETAILS))
> -            fprintf (dump_file, "failed: evolution of offset is not"
> -                                " affine.\n");
> -          return false;
> +          if (nest)
> +            {
> +              if (dump_file && (dump_flags & TDF_DETAILS))
> +                fprintf (dump_file, "failed: evolution of offset is not"
> +                                    " affine.\n");
> +              return false;
> +            }
> +          else
> +            {
> +              offset_iv.base = poffset;
> +              offset_iv.step = ssize_int (0);
> +            }
>         }
>     }
>
> @@ -832,6 +851,19 @@ canonicalize_base_object_address (tree addr)
>   return true;
>  }
>
> +/* Analyzes the behavior of the memory reference DR in the innermost loop or
> +   basic block that contains it.  Returns true if analysis succeed or false
> +   otherwise.  */
> +
> +bool
> +dr_analyze_innermost (struct data_reference *dr)
> +{
> +  gimple stmt = DR_STMT (dr);
> +  struct loop *loop = loop_containing_stmt (stmt);
> +
> +  return dr_analyze_innermost_1 (dr, loop);
> +}
> +
>  /* Determines the base object and the list of indices of memory reference
>    DR, analyzed in LOOP and instantiated in loop nest NEST.  */
>
> @@ -972,7 +1004,7 @@ create_data_ref (loop_p nest, loop_p loop, tree me
>   DR_REF (dr) = memref;
>   DR_IS_READ (dr) = is_read;
>
> -  dr_analyze_innermost (dr);
> +  dr_analyze_innermost_1 (dr, nest);
>   dr_analyze_indices (dr, nest, loop);
>   dr_analyze_alias (dr);
>
> Index: testsuite/gcc.dg/vect/bb-slp-24.c
> ===================================================================
> --- testsuite/gcc.dg/vect/bb-slp-24.c   (revision 0)
> +++ testsuite/gcc.dg/vect/bb-slp-24.c   (revision 0)
> @@ -0,0 +1,55 @@
> +/* { dg-require-effective-target vect_int } */
> +
> +#include <stdarg.h>
> +#include "tree-vect.h"
> +
> +#define A 3
> +#define N 256
> +
> +short src[N], dst[N];
> +
> +void foo (short * __restrict dst, short * __restrict src, int h, int stride)
> +{
> +    int i;
> +    h /= 8;
> +    for (i = 0; i < h; i++) {
> +        dst[0] += A*src[0];
> +        dst[1] += A*src[1];
> +        dst[2] += A*src[2];
> +        dst[3] += A*src[3];
> +        dst[4] += A*src[4];
> +        dst[5] += A*src[5];
> +        dst[6] += A*src[6];
> +        dst[7] += A*src[7];
> +        dst += stride;
> +        src += stride;
> +    }
> +}
> +
> +
> +int main (void)
> +{
> +  int i;
> +
> +  check_vect ();
> +
> +  for (i = 0; i < N; i++)
> +    {
> +      dst[i] = 0;
> +      src[i] = i;
> +    }
> +
> +  foo (dst, src, N, 8);
> +
> +  for (i = 0; i < N; i++)
> +    {
> +      if (dst[i] != A * i)
> +        abort ();
> +    }
> +
> +  return 0;
> +}
> +
> +/* { dg-final { scan-tree-dump-times "basic block vectorized using
> SLP" 1 "slp" { target vect_element_align } } } */
> +/* { dg-final { cleanup-tree-dump "slp" } } */
> +
>

Patch

Index: tree-data-ref.c
===================================================================
--- tree-data-ref.c     (revision 178755)
+++ tree-data-ref.c     (working copy)
@@ -722,11 +722,11 @@  canonicalize_base_object_address (tree addr)
 }

 /* Analyzes the behavior of the memory reference DR in the innermost loop or
-   basic block that contains it. Returns true if analysis succeed or false
+   basic block that contains it.  Returns true if analysis succeed or false
    otherwise.  */

-bool
-dr_analyze_innermost (struct data_reference *dr)
+static bool
+dr_analyze_innermost_1 (struct data_reference *dr, struct loop *nest)
 {
   gimple stmt = DR_STMT (dr);
   struct loop *loop = loop_containing_stmt (stmt);
@@ -769,14 +769,25 @@  canonicalize_base_object_address (tree addr)
     }
   else
     base = build_fold_addr_expr (base);
+
   if (in_loop)
     {
       if (!simple_iv (loop, loop_containing_stmt (stmt), base, &base_iv,
                       false))
         {
-          if (dump_file && (dump_flags & TDF_DETAILS))
-           fprintf (dump_file, "failed: evolution of base is not affine.\n");
-          return false;
+          if (nest)
+            {
+              if (dump_file && (dump_flags & TDF_DETAILS))
+               fprintf (dump_file, "failed: evolution of base is not"
+                                    " affine.\n");
+                return false;
+            }
+          else
+            {
+              base_iv.base = base;
+              base_iv.step = ssize_int (0);
+              base_iv.no_overflow = true;
+            }
         }
     }
   else
@@ -801,10 +812,18 @@  canonicalize_base_object_address (tree addr)
       else if (!simple_iv (loop, loop_containing_stmt (stmt),
                            poffset, &offset_iv, false))
         {
-          if (dump_file && (dump_flags & TDF_DETAILS))
-            fprintf (dump_file, "failed: evolution of offset is not"
-                                " affine.\n");
-          return false;
+          if (nest)
+            {
+              if (dump_file && (dump_flags & TDF_DETAILS))
+                fprintf (dump_file, "failed: evolution of offset is not"
+                                    " affine.\n");
+              return false;
+            }
+          else
+            {
+              offset_iv.base = poffset;
+              offset_iv.step = ssize_int (0);
+            }
         }
     }

@@ -832,6 +851,19 @@  canonicalize_base_object_address (tree addr)
   return true;
 }

+/* Analyzes the behavior of the memory reference DR in the innermost loop or
+   basic block that contains it.  Returns true if analysis succeed or false
+   otherwise.  */
+
+bool
+dr_analyze_innermost (struct data_reference *dr)
+{
+  gimple stmt = DR_STMT (dr);
+  struct loop *loop = loop_containing_stmt (stmt);
+
+  return dr_analyze_innermost_1 (dr, loop);
+}
+
 /* Determines the base object and the list of indices of memory reference
    DR, analyzed in LOOP and instantiated in loop nest NEST.  */

@@ -972,7 +1004,7 @@  create_data_ref (loop_p nest, loop_p loop, tree me
   DR_REF (dr) = memref;
   DR_IS_READ (dr) = is_read;

-  dr_analyze_innermost (dr);
+  dr_analyze_innermost_1 (dr, nest);
   dr_analyze_indices (dr, nest, loop);
   dr_analyze_alias (dr);

Index: testsuite/gcc.dg/vect/bb-slp-24.c
===================================================================
--- testsuite/gcc.dg/vect/bb-slp-24.c   (revision 0)
+++ testsuite/gcc.dg/vect/bb-slp-24.c   (revision 0)
@@ -0,0 +1,55 @@ 
+/* { dg-require-effective-target vect_int } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define A 3
+#define N 256
+
+short src[N], dst[N];
+
+void foo (short * __restrict dst, short * __restrict src, int h, int stride)
+{
+    int i;
+    h /= 8;
+    for (i = 0; i < h; i++) {
+        dst[0] += A*src[0];
+        dst[1] += A*src[1];
+        dst[2] += A*src[2];
+        dst[3] += A*src[3];
+        dst[4] += A*src[4];
+        dst[5] += A*src[5];
+        dst[6] += A*src[6];
+        dst[7] += A*src[7];
+        dst += stride;
+        src += stride;
+    }
+}
+
+
+int main (void)
+{
+  int i;
+
+  check_vect ();
+
+  for (i = 0; i < N; i++)
+    {
+      dst[i] = 0;
+      src[i] = i;
+    }
+
+  foo (dst, src, N, 8);
+
+  for (i = 0; i < N; i++)
+    {
+      if (dst[i] != A * i)
+        abort ();
+    }
+
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "basic block vectorized using
SLP" 1 "slp" { target vect_element_align } } } */
+/* { dg-final { cleanup-tree-dump "slp" } } */