This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch] Allow not simple ivs in SLP
- From: Ira Rosen <ira dot rosen at linaro dot org>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Patch Tracking <patches at linaro dot org>
- Date: Wed, 14 Sep 2011 15:01:42 +0300
- Subject: [patch] Allow not simple ivs in SLP
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.
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" } } */
+