Patchwork Allow not simple ivs in SLP

login
register
mail settings
Submitter Ira Rosen
Date Sept. 25, 2011, 9:24 a.m.
Message ID <CAKSNEw7thza3hwZO_7v2PhQa8XeNT8xKobu_Y7oj171AE0hn9g@mail.gmail.com>
Download mbox | patch
Permalink /patch/116269/
State New
Headers show

Comments

Ira Rosen - Sept. 25, 2011, 9:24 a.m.
On 23 September 2011 23:09, Richard Guenther <richard.guenther@gmail.com> wrote:
> 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.

I committed the attached patch.

Thanks,
Ira

>
> Thanks,
> Richard.
>

Patch

Index: tree-loop-distribution.c
===================================================================
--- tree-loop-distribution.c	(revision 179159)
+++ tree-loop-distribution.c	(working copy)
@@ -268,7 +268,7 @@  generate_memset_zero (gimple stmt, tree op0, tree
 
   DR_STMT (dr) = stmt;
   DR_REF (dr) = op0;
-  res = dr_analyze_innermost (dr);
+  res = dr_analyze_innermost (dr, loop_containing_stmt (stmt));
   gcc_assert (res && stride_of_unit_type_p (DR_STEP (dr), TREE_TYPE (op0)));
 
   nb_bytes = build_size_arg_loc (loc, nb_iter, op0, &stmt_list);
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 179159)
+++ ChangeLog	(working copy)
@@ -1,3 +1,13 @@ 
+2011-09-25  Ira Rosen  <ira.rosen@linaro.org>
+
+	* tree-data-ref.c (dr_analyze_innermost): Add new argument.
+	Allow not simple iv if analyzing basic block.
+	(create_data_ref): Update call to dr_analyze_innermost.
+	(stmt_with_adjacent_zero_store_dr_p, ref_base_address): Likewise.
+	* tree-loop-distribution.c (generate_memset_zero): Likewise.
+	* tree-predcom.c (find_looparound_phi): Likewise.
+	* tree-data-ref.h (dr_analyze_innermost): Add new argument.
+
 2011-09-24  David S. Miller  <davem@davemloft.net>
 
 	* config/sparc/sparc.h (FIRST_PSEUDO_REGISTER): Bump to 103.
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,59 @@ 
+/* { 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 dummy)
+{
+  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;
+      if (dummy == 32)
+        abort ();
+    }
+}
+
+
+int main (void)
+{
+  int i;
+
+  check_vect ();
+
+  for (i = 0; i < N; i++)
+    {
+      dst[i] = 0;
+      src[i] = i;
+    }
+
+  foo (dst, src, N, 8, 0);
+
+  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" } } */
+
Index: testsuite/ChangeLog
===================================================================
--- testsuite/ChangeLog	(revision 179159)
+++ testsuite/ChangeLog	(working copy)
@@ -1,3 +1,7 @@ 
+2011-09-25  Ira Rosen  <ira.rosen@linaro.org>
+
+	* gcc.dg/vect/bb-slp-24.c: New.
+
 2011-09-24  Jason Merrill  <jason@redhat.com>
 
 	* g++.dg/cpp0x/nsdmi-eh1.C: New.
Index: tree-data-ref.c
===================================================================
--- tree-data-ref.c	(revision 179159)
+++ 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)
+dr_analyze_innermost (struct data_reference *dr, struct loop *nest)
 {
   gimple stmt = DR_STMT (dr);
   struct loop *loop = loop_containing_stmt (stmt);
@@ -769,14 +769,25 @@  bool
     }
   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 @@  bool
       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);
+            }
         }
     }
 
@@ -972,7 +991,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 (dr, nest);
   dr_analyze_indices (dr, nest, loop);
   dr_analyze_alias (dr);
 
@@ -5150,7 +5169,7 @@  stmt_with_adjacent_zero_store_dr_p (gimple stmt)
   DR_STMT (dr) = stmt;
   DR_REF (dr) = op0;
 
-  res = dr_analyze_innermost (dr)
+  res = dr_analyze_innermost (dr, loop_containing_stmt (stmt))
     && stride_of_unit_type_p (DR_STEP (dr), TREE_TYPE (op0));
 
   free_data_ref (dr);
@@ -5190,7 +5209,7 @@  ref_base_address (gimple stmt, data_ref_loc *ref)
 
   DR_STMT (dr) = stmt;
   DR_REF (dr) = *ref->pos;
-  dr_analyze_innermost (dr);
+  dr_analyze_innermost (dr, loop_containing_stmt (stmt));
   base_address = DR_BASE_ADDRESS (dr);
 
   if (!base_address)
Index: tree-data-ref.h
===================================================================
--- tree-data-ref.h	(revision 179159)
+++ tree-data-ref.h	(working copy)
@@ -386,7 +386,7 @@  DEF_VEC_O (data_ref_loc);
 DEF_VEC_ALLOC_O (data_ref_loc, heap);
 
 bool get_references_in_stmt (gimple, VEC (data_ref_loc, heap) **);
-bool dr_analyze_innermost (struct data_reference *);
+bool dr_analyze_innermost (struct data_reference *, struct loop *);
 extern bool compute_data_dependences_for_loop (struct loop *, bool,
 					       VEC (loop_p, heap) **,
 					       VEC (data_reference_p, heap) **,
Index: tree-predcom.c
===================================================================
--- tree-predcom.c	(revision 179159)
+++ tree-predcom.c	(working copy)
@@ -1116,7 +1116,7 @@  find_looparound_phi (struct loop *loop, dref ref,
   memset (&init_dr, 0, sizeof (struct data_reference));
   DR_REF (&init_dr) = init_ref;
   DR_STMT (&init_dr) = phi;
-  if (!dr_analyze_innermost (&init_dr))
+  if (!dr_analyze_innermost (&init_dr, loop))
     return NULL;
 
   if (!valid_initializer_p (&init_dr, ref->distance + 1, root->ref))