aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVictor Kaplansky <victork@il.ibm.com>2007-08-16 14:20:39 +0000
committerVictor Kaplansky <victork@gcc.gnu.org>2007-08-16 14:20:39 +0000
commitbc1edb77ba75d9a7b2c780a0fe8f04af0b3b6479 (patch)
tree03bccd8be0266f061712ef717618bb096e583eab
parent57c2d13fa01341b6b3a843d321b0d8bd2518a4dd (diff)
downloadgcc-bc1edb77ba75d9a7b2c780a0fe8f04af0b3b6479.zip
gcc-bc1edb77ba75d9a7b2c780a0fe8f04af0b3b6479.tar.gz
gcc-bc1edb77ba75d9a7b2c780a0fe8f04af0b3b6479.tar.bz2
tree-vectorizer.c (new_loop_vec_info): Initialize new field.
gcc/ChangeLog * tree-vectorizer.c (new_loop_vec_info): Initialize new field. (destroy_loop_vec_info): Add call to VEC_free. * tree-vectorizer.h (may_alias_ddrs): Define. (LOOP_VINFO_MAY_ALIAS_DDRS): Define. * tree-vect-analyze.c (vect_analyze_data_ref_dependence): Change reporting to dump. (vect_is_duplicate_ddr): New. (vect_mark_for_runtime_alias_test): New. (vect_analyze_data_ref_dependences) Add call to vect_mark_for_runtime_alias_test. (vect_enhance_data_refs_alignment): Define local variable vect_versioning_for_alias_required, don't perform peeling for alignment if versioning for alias is required. (vect_enhance_data_refs_alignment): Use PARAM_VECT_MAX_VERSION_FOR_ALIGNMENT_CHECKS instead of PARAM_VECT_MAX_VERSION_CHECKS. * tree-vect-transform.c (vect_create_cond_for_alias_checks): New. (vect_transform_loop): Add call to vect_create_cond_for_alias_checks. (vect_vfa_segment_size): New. * params.def (PARAM_VECT_MAX_VERSION_FOR_ALIGNMENT_CHECKS): Rename. (PARAM_VECT_MAX_VERSION_FOR_ALIAS_CHECKS): Define. * gcc/doc/invoke.texi (vect-max-version-for-alignment-checks): Document. (vect-max-version-for-alias-checks): Document. (vect-max-version-checks): Remove. gcc/testsuite/ChangeLog * gcc.dg/vect/vect-vfa-01.c: New. * gcc.dg/vect/vect-vfa-02.c: New. * gcc.dg/vect/vect-vfa-03.c: New. * gcc.dg/vect/vect-vfa-04.c: New. * gcc.dg/vect/vect-102a.c, gcc.dg/vect/vect-51.c, gcc.dg/vect/pr29145.c, gcc.dg/vect/vect-43.c, gcc.dg/vect/vect-61.c, gcc.dg/vect/vect-53.c, gcc.dg/vect/vect-45.c, gcc.dg/vect/vect-101.c, gcc.dg/vect/vect-37.c, gcc.dg/vect/vect-79.c, gcc.dg/vect/vect-102.c, gcc.dg/vect/vect-dv-2.c, gcc.dg/vect/vect-57.c, gcc.dg/vect/vect-49.c, gfortran.dg/vect/pr19049.f90: Rename to start with prefix no-vfa-. * gcc.dg/vect/vect.exp: Disable versioning for alias when test starts with no-vfa-. * gfortran.dg/vect/vect.exp: Likewise. From-SVN: r127559
-rw-r--r--gcc/ChangeLog33
-rw-r--r--gcc/doc/invoke.texi13
-rw-r--r--gcc/params.def11
-rw-r--r--gcc/testsuite/ChangeLog19
-rw-r--r--gcc/testsuite/gcc.dg/vect/no-vfa-pr29145.c (renamed from gcc/testsuite/gcc.dg/vect/pr29145.c)0
-rw-r--r--gcc/testsuite/gcc.dg/vect/no-vfa-vect-101.c (renamed from gcc/testsuite/gcc.dg/vect/vect-101.c)0
-rw-r--r--gcc/testsuite/gcc.dg/vect/no-vfa-vect-102.c (renamed from gcc/testsuite/gcc.dg/vect/vect-102.c)0
-rw-r--r--gcc/testsuite/gcc.dg/vect/no-vfa-vect-102a.c (renamed from gcc/testsuite/gcc.dg/vect/vect-102a.c)0
-rw-r--r--gcc/testsuite/gcc.dg/vect/no-vfa-vect-37.c (renamed from gcc/testsuite/gcc.dg/vect/vect-37.c)0
-rw-r--r--gcc/testsuite/gcc.dg/vect/no-vfa-vect-43.c (renamed from gcc/testsuite/gcc.dg/vect/vect-43.c)0
-rw-r--r--gcc/testsuite/gcc.dg/vect/no-vfa-vect-45.c (renamed from gcc/testsuite/gcc.dg/vect/vect-45.c)0
-rw-r--r--gcc/testsuite/gcc.dg/vect/no-vfa-vect-49.c (renamed from gcc/testsuite/gcc.dg/vect/vect-49.c)0
-rw-r--r--gcc/testsuite/gcc.dg/vect/no-vfa-vect-51.c (renamed from gcc/testsuite/gcc.dg/vect/vect-51.c)0
-rw-r--r--gcc/testsuite/gcc.dg/vect/no-vfa-vect-53.c (renamed from gcc/testsuite/gcc.dg/vect/vect-53.c)0
-rw-r--r--gcc/testsuite/gcc.dg/vect/no-vfa-vect-57.c (renamed from gcc/testsuite/gcc.dg/vect/vect-57.c)0
-rw-r--r--gcc/testsuite/gcc.dg/vect/no-vfa-vect-61.c (renamed from gcc/testsuite/gcc.dg/vect/vect-61.c)0
-rw-r--r--gcc/testsuite/gcc.dg/vect/no-vfa-vect-79.c (renamed from gcc/testsuite/gcc.dg/vect/vect-79.c)0
-rw-r--r--gcc/testsuite/gcc.dg/vect/no-vfa-vect-dv-2.c (renamed from gcc/testsuite/gcc.dg/vect/vect-dv-2.c)0
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-vfa-01.c39
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-vfa-02.c47
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-vfa-03.c58
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-vfa-04.c38
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect.exp6
-rw-r--r--gcc/testsuite/gfortran.dg/vect/no-vfa-pr32457.f90 (renamed from gcc/testsuite/gfortran.dg/vect/pr32457.f90)0
-rw-r--r--gcc/testsuite/gfortran.dg/vect/vect.exp13
-rw-r--r--gcc/tree-vect-analyze.c105
-rw-r--r--gcc/tree-vect-transform.c169
-rw-r--r--gcc/tree-vectorizer.c8
-rw-r--r--gcc/tree-vectorizer.h5
29 files changed, 538 insertions, 26 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 6829864..db120c0 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,36 @@
+2007-08-16 Victor Kaplansky <victork@il.ibm.com>
+
+ * tree-vectorizer.c (new_loop_vec_info): Initialize new
+ field.
+ (destroy_loop_vec_info): Add call to VEC_free.
+ * tree-vectorizer.h (may_alias_ddrs): Define.
+ (LOOP_VINFO_MAY_ALIAS_DDRS): Define.
+ * tree-vect-analyze.c (vect_analyze_data_ref_dependence):
+ Change reporting to dump.
+ (vect_is_duplicate_ddr): New.
+ (vect_mark_for_runtime_alias_test): New.
+ (vect_analyze_data_ref_dependences) Add call to
+ vect_mark_for_runtime_alias_test.
+ (vect_enhance_data_refs_alignment): Define local variable
+ vect_versioning_for_alias_required, don't perform
+ peeling for alignment if versioning for alias is
+ required.
+ (vect_enhance_data_refs_alignment): Use
+ PARAM_VECT_MAX_VERSION_FOR_ALIGNMENT_CHECKS instead of
+ PARAM_VECT_MAX_VERSION_CHECKS.
+ * tree-vect-transform.c
+ (vect_create_cond_for_alias_checks): New.
+ (vect_transform_loop): Add call to
+ vect_create_cond_for_alias_checks.
+ (vect_vfa_segment_size): New.
+ * params.def (PARAM_VECT_MAX_VERSION_FOR_ALIGNMENT_CHECKS):
+ Rename.
+ (PARAM_VECT_MAX_VERSION_FOR_ALIAS_CHECKS): Define.
+ * gcc/doc/invoke.texi
+ (vect-max-version-for-alignment-checks): Document.
+ (vect-max-version-for-alias-checks): Document.
+ (vect-max-version-checks): Remove.
+
2007-08-16 Uros Bizjak <ubizjak@gmail.com>
* config/i386/i386.md (*rep_movdi_rex64): Emit "rep" prefix on
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 944cb46..eed4f10 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -6741,10 +6741,15 @@ value is 500.
When set to 1, use expensive methods to eliminate all redundant
constraints. The default value is 0.
-@item vect-max-version-checks
-The maximum number of runtime checks that can be performed when doing
-loop versioning in the vectorizer. See option ftree-vect-loop-version
-for more information.
+@item vect-max-version-for-alignment-checks
+The maximum number of runtime checks that can be performed when
+doing loop versioning for alignment in the vectorizer. See option
+ftree-vect-loop-version for more information.
+
+@item vect-max-version-for-alias-checks
+The maximum number of runtime checks that can be performed when
+doing loop versioning for alias in the vectorizer. See option
+ftree-vect-loop-version for more information.
@item max-iterations-to-track
diff --git a/gcc/params.def b/gcc/params.def
index 3221676..bcdb4bb 100644
--- a/gcc/params.def
+++ b/gcc/params.def
@@ -485,11 +485,16 @@ DEFPARAM(PARAM_OMEGA_ELIMINATE_REDUNDANT_CONSTRAINTS,
"When set to 1, use expensive methods to eliminate all redundant constraints",
0, 0, 1)
-DEFPARAM(PARAM_VECT_MAX_VERSION_CHECKS,
- "vect-max-version-checks",
- "Bound on number of runtime checks inserted by the vectorizer's loop versioning",
+DEFPARAM(PARAM_VECT_MAX_VERSION_FOR_ALIGNMENT_CHECKS,
+ "vect-max-version-for-alignment-checks",
+ "Bound on number of runtime checks inserted by the vectorizer's loop versioning for alignment check",
6, 0, 0)
+DEFPARAM(PARAM_VECT_MAX_VERSION_FOR_ALIAS_CHECKS,
+ "vect-max-version-for-alias-checks",
+ "Bound on number of runtime checks inserted by the vectorizer's loop versioning for alias check",
+ 10, 0, 0)
+
DEFPARAM(PARAM_MAX_CSELIB_MEMORY_LOCATIONS,
"max-cselib-memory-locations",
"The maximum memory locations recorded by cselib",
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 0b79ae9..387b579 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,22 @@
+2007-08-16 Victor Kaplansky <victork@il.ibm.com>
+
+ * gcc.dg/vect/vect-vfa-01.c: New.
+ * gcc.dg/vect/vect-vfa-02.c: New.
+ * gcc.dg/vect/vect-vfa-03.c: New.
+ * gcc.dg/vect/vect-vfa-04.c: New.
+ * gcc.dg/vect/vect-102a.c, gcc.dg/vect/vect-51.c,
+ gcc.dg/vect/pr29145.c, gcc.dg/vect/vect-43.c,
+ gcc.dg/vect/vect-61.c, gcc.dg/vect/vect-53.c,
+ gcc.dg/vect/vect-45.c, gcc.dg/vect/vect-101.c,
+ gcc.dg/vect/vect-37.c, gcc.dg/vect/vect-79.c,
+ gcc.dg/vect/vect-102.c, gcc.dg/vect/vect-dv-2.c,
+ gcc.dg/vect/vect-57.c, gcc.dg/vect/vect-49.c,
+ gfortran.dg/vect/pr19049.f90: Rename to start with
+ prefix no-vfa-.
+ * gcc.dg/vect/vect.exp: Disable versioning for alias
+ when test starts with no-vfa-.
+ * gfortran.dg/vect/vect.exp: Likewise.
+
2007-08-16 Richard Sandiford <richard@codesourcery.com>
* gcc.dg/torture/pr32897.c: New test.
diff --git a/gcc/testsuite/gcc.dg/vect/pr29145.c b/gcc/testsuite/gcc.dg/vect/no-vfa-pr29145.c
index 97d190c..97d190c 100644
--- a/gcc/testsuite/gcc.dg/vect/pr29145.c
+++ b/gcc/testsuite/gcc.dg/vect/no-vfa-pr29145.c
diff --git a/gcc/testsuite/gcc.dg/vect/vect-101.c b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-101.c
index e195a58..e195a58 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-101.c
+++ b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-101.c
diff --git a/gcc/testsuite/gcc.dg/vect/vect-102.c b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-102.c
index 49df4f9..49df4f9 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-102.c
+++ b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-102.c
diff --git a/gcc/testsuite/gcc.dg/vect/vect-102a.c b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-102a.c
index 35023fc..35023fc 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-102a.c
+++ b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-102a.c
diff --git a/gcc/testsuite/gcc.dg/vect/vect-37.c b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-37.c
index e54e0c5..e54e0c5 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-37.c
+++ b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-37.c
diff --git a/gcc/testsuite/gcc.dg/vect/vect-43.c b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-43.c
index 258da28..258da28 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-43.c
+++ b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-43.c
diff --git a/gcc/testsuite/gcc.dg/vect/vect-45.c b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-45.c
index 8a99856..8a99856 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-45.c
+++ b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-45.c
diff --git a/gcc/testsuite/gcc.dg/vect/vect-49.c b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-49.c
index 8dfd0e7..8dfd0e7 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-49.c
+++ b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-49.c
diff --git a/gcc/testsuite/gcc.dg/vect/vect-51.c b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-51.c
index 541a5ff..541a5ff 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-51.c
+++ b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-51.c
diff --git a/gcc/testsuite/gcc.dg/vect/vect-53.c b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-53.c
index 91eaabe..91eaabe 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-53.c
+++ b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-53.c
diff --git a/gcc/testsuite/gcc.dg/vect/vect-57.c b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-57.c
index bcac95a..bcac95a 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-57.c
+++ b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-57.c
diff --git a/gcc/testsuite/gcc.dg/vect/vect-61.c b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-61.c
index 9f4e8e9..9f4e8e9 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-61.c
+++ b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-61.c
diff --git a/gcc/testsuite/gcc.dg/vect/vect-79.c b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-79.c
index 8e98e4d..8e98e4d 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-79.c
+++ b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-79.c
diff --git a/gcc/testsuite/gcc.dg/vect/vect-dv-2.c b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-dv-2.c
index 30d229c..30d229c 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-dv-2.c
+++ b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-dv-2.c
diff --git a/gcc/testsuite/gcc.dg/vect/vect-vfa-01.c b/gcc/testsuite/gcc.dg/vect/vect-vfa-01.c
new file mode 100644
index 0000000..ea5523e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-vfa-01.c
@@ -0,0 +1,39 @@
+/* { dg-require-effective-target vect_int } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 16
+int result[N] = {12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27};
+int X[N] = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25};
+int Y[N] = {};
+
+void
+foo (int *in, int *out)
+{
+ int i;
+
+ for (i = 0; i < N; i++)
+ out[i] = in[i] + 2;
+}
+
+int
+main (void)
+{
+ int i;
+
+ check_vect ();
+
+ foo (X, Y);
+
+ /* check results: */
+ for (i = 0; i < N; i++)
+ {
+ if (Y[i] != result[i])
+ abort ();
+ }
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
+/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-vfa-02.c b/gcc/testsuite/gcc.dg/vect/vect-vfa-02.c
new file mode 100644
index 0000000..80d85a7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-vfa-02.c
@@ -0,0 +1,47 @@
+/* { dg-require-effective-target vect_int } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 16
+int resultY[N] = {12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27};
+int resultZ[N] = {13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28};
+int X[N] = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25};
+int Y[N] = {};
+int Z[N] = {};
+
+void
+foo (int *in, int *out1, int *out2)
+{
+ int i;
+
+ for (i = 0; i < N; i++)
+ {
+ out1[i] = in[i] + 2;
+ out2[i] = in[i] + 3;
+ }
+}
+
+int
+main (void)
+{
+ int i;
+
+ check_vect ();
+
+ foo (X, Y, Z);
+
+ /* check results: */
+ for (i = 0; i < N; i++)
+ {
+ if (Y[i] != resultY[i])
+ abort ();
+
+ if (Z[i] != resultZ[i])
+ abort ();
+ }
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
+/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-vfa-03.c b/gcc/testsuite/gcc.dg/vect/vect-vfa-03.c
new file mode 100644
index 0000000..aa001bf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-vfa-03.c
@@ -0,0 +1,58 @@
+/* { dg-require-effective-target vect_int } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 16
+struct S
+{
+ unsigned short a;
+ unsigned short b;
+};
+
+struct S result[N] = {12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18,
+ 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24,
+ 24, 25, 25, 26, 26, 27, 27, 28};
+struct S X[N] = {10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16,
+ 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
+ 23, 23, 24, 24, 25, 25};
+struct S Y[N] = {};
+
+void
+foo (struct S * in, struct S * out)
+{
+ int i;
+
+ for (i = 0; i < N; i++)
+ {
+ out[i].a = in[i].a + 2;
+ out[i].b = in[i].b + 3;
+ }
+}
+
+int
+main (void)
+{
+ int i;
+
+ check_vect ();
+
+ foo (X, Y);
+
+ /* check results: */
+ for (i = 0; i < N; i++)
+ {
+ if (Y[i].a != result[i].a)
+ abort ();
+
+ if (Y[i].b != result[i].b)
+ abort ();
+
+ }
+ return 0;
+}
+
+/* Needs interleaving support. */
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_interleave && vect_extract_even_odd } } } } */
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 0 "vect" { xfail { vect_interleave && vect_extract_even_odd } } } } */
+/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-vfa-04.c b/gcc/testsuite/gcc.dg/vect/vect-vfa-04.c
new file mode 100644
index 0000000..e43df00
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-vfa-04.c
@@ -0,0 +1,38 @@
+/* { dg-require-effective-target vect_int } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 16
+int result[] = {10, 11, 15, 16, 20, 21, 25, 26, 30, 31, 35, 36, 40, 41, 45, 46, 50, 51};
+int X[] = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0};
+
+void
+foo (int *in, int *out)
+{
+ int i;
+
+ for (i = 0; i < N; i++)
+ out[i] = in[i] + 5;
+}
+
+int
+main (void)
+{
+ int i;
+
+ check_vect ();
+
+ foo (X, &X[2]);
+
+ /* check results: */
+ for (i = 0; i < N+2; i++)
+ {
+ if (X[i] != result[i])
+ abort ();
+ }
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
+/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect.exp b/gcc/testsuite/gcc.dg/vect/vect.exp
index 88ce4d9..2208f72 100644
--- a/gcc/testsuite/gcc.dg/vect/vect.exp
+++ b/gcc/testsuite/gcc.dg/vect/vect.exp
@@ -113,6 +113,12 @@ dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/vect-*.\[cS\]]] \
global SAVED_DEFAULT_VECTCFLAGS
set SAVED_DEFAULT_VECTCFLAGS $DEFAULT_VECTCFLAGS
+# --param vect-max-version-for-alias-checks=0 tests
+set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS
+lappend DEFAULT_VECTCFLAGS "--param" "vect-max-version-for-alias-checks=0"
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/no-vfa-*.\[cS\]]] \
+ "" $DEFAULT_VECTCFLAGS
+
# -ffast-math tests
set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS
lappend DEFAULT_VECTCFLAGS "-ffast-math"
diff --git a/gcc/testsuite/gfortran.dg/vect/pr32457.f90 b/gcc/testsuite/gfortran.dg/vect/no-vfa-pr32457.f90
index 07a2b60..07a2b60 100644
--- a/gcc/testsuite/gfortran.dg/vect/pr32457.f90
+++ b/gcc/testsuite/gfortran.dg/vect/no-vfa-pr32457.f90
diff --git a/gcc/testsuite/gfortran.dg/vect/vect.exp b/gcc/testsuite/gfortran.dg/vect/vect.exp
index 6a72e57..3cc41c7 100644
--- a/gcc/testsuite/gfortran.dg/vect/vect.exp
+++ b/gcc/testsuite/gfortran.dg/vect/vect.exp
@@ -90,7 +90,18 @@ proc check_effective_target_lp64_or_vect_no_align { } {
dg-init
# Main loop.
-gfortran-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[fF\]{,90,95,03} ]] $DEFAULT_VECTCFLAGS
+gfortran-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/vect-*.\[fF\]{,90,95,03} ]] $DEFAULT_VECTCFLAGS
+gfortran-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/pr-*.\[fF\]{,90,95,03} ]] $DEFAULT_VECTCFLAGS
+
+#### Tests with special options
+global SAVED_DEFAULT_VECTCFLAGS
+set SAVED_DEFAULT_VECTCFLAGS $DEFAULT_VECTCFLAGS
+
+# --param vect-max-version-for-alias-checks=0 tests
+set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS
+lappend DEFAULT_VECTCFLAGS "--param" "vect-max-version-for-alias-checks=0"
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/no-vfa-*.\[fF\]{,90,95,03} ]] \
+ "" $DEFAULT_VECTCFLAGS
# Clean up.
set dg-do-what-default ${save-dg-do-what-default}
diff --git a/gcc/tree-vect-analyze.c b/gcc/tree-vect-analyze.c
index 3e2b4c7..cc43ad6 100644
--- a/gcc/tree-vect-analyze.c
+++ b/gcc/tree-vect-analyze.c
@@ -1039,10 +1039,10 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr,
if (DDR_ARE_DEPENDENT (ddr) == chrec_dont_know)
{
- if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
+ if (vect_print_dump_info (REPORT_DR_DETAILS))
{
fprintf (vect_dump,
- "not vectorized: can't determine dependence between ");
+ "versioning for alias required: can't determine dependence between ");
print_generic_expr (vect_dump, DR_REF (dra), TDF_SLIM);
fprintf (vect_dump, " and ");
print_generic_expr (vect_dump, DR_REF (drb), TDF_SLIM);
@@ -1052,9 +1052,9 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr,
if (DDR_NUM_DIST_VECTS (ddr) == 0)
{
- if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
+ if (vect_print_dump_info (REPORT_DR_DETAILS))
{
- fprintf (vect_dump, "not vectorized: bad dist vector for ");
+ fprintf (vect_dump, "versioning for alias required: bad dist vector for ");
print_generic_expr (vect_dump, DR_REF (dra), TDF_SLIM);
fprintf (vect_dump, " and ");
print_generic_expr (vect_dump, DR_REF (drb), TDF_SLIM);
@@ -1108,10 +1108,11 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr,
continue;
}
- if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
+ if (vect_print_dump_info (REPORT_DR_DETAILS))
{
fprintf (vect_dump,
- "not vectorized: possible dependence between data-refs ");
+ "versioning for alias required: possible dependence "
+ "between data-refs ");
print_generic_expr (vect_dump, DR_REF (dra), TDF_SLIM);
fprintf (vect_dump, " and ");
print_generic_expr (vect_dump, DR_REF (drb), TDF_SLIM);
@@ -1123,6 +1124,77 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr,
return false;
}
+/* Return TRUE if DDR_NEW is already found in MAY_ALIAS_DDRS list. */
+
+static bool
+vect_is_duplicate_ddr (VEC (ddr_p, heap) * may_alias_ddrs, ddr_p ddr_new)
+{
+ unsigned i;
+ ddr_p ddr;
+
+ for (i = 0; VEC_iterate (ddr_p, may_alias_ddrs, i, ddr); i++)
+ {
+ tree dref_A_i, dref_B_i, dref_A_j, dref_B_j;
+
+ dref_A_i = DR_REF (DDR_A (ddr));
+ dref_B_i = DR_REF (DDR_B (ddr));
+ dref_A_j = DR_REF (DDR_A (ddr_new));
+ dref_B_j = DR_REF (DDR_B (ddr_new));
+
+ if ((operand_equal_p (dref_A_i, dref_A_j, 0)
+ && operand_equal_p (dref_B_i, dref_B_j, 0))
+ || (operand_equal_p (dref_A_i, dref_B_j, 0)
+ && operand_equal_p (dref_B_i, dref_A_j, 0)))
+ {
+ if (vect_print_dump_info (REPORT_DR_DETAILS))
+ {
+ fprintf (vect_dump, "found same pair of data references ");
+ print_generic_expr (vect_dump, dref_A_i, TDF_SLIM);
+ fprintf (vect_dump, " and ");
+ print_generic_expr (vect_dump, dref_B_i, TDF_SLIM);
+ }
+ return true;
+ }
+ }
+ return false;
+}
+
+/* Save DDR in LOOP_VINFO list of ddrs that may alias and need to be
+ tested at run-time. Returns false if number of run-time checks
+ inserted by vectorizer is greater than maximum defined by
+ PARAM_VECT_MAX_VERSION_FOR_ALIAS_CHECKS. */
+static bool
+vect_mark_for_runtime_alias_test (ddr_p ddr, loop_vec_info loop_vinfo)
+{
+ if (vect_print_dump_info (REPORT_DR_DETAILS))
+ {
+ fprintf (vect_dump, "mark for run-time aliasing test between ");
+ print_generic_expr (vect_dump, DR_REF (DDR_A (ddr)), TDF_SLIM);
+ fprintf (vect_dump, " and ");
+ print_generic_expr (vect_dump, DR_REF (DDR_B (ddr)), TDF_SLIM);
+ }
+
+ /* Do not add to the list duplicate ddrs. */
+ if (vect_is_duplicate_ddr (LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo), ddr))
+ return true;
+
+ if (VEC_length (ddr_p, LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo))
+ >= (unsigned) PARAM_VALUE (PARAM_VECT_MAX_VERSION_FOR_ALIAS_CHECKS))
+ {
+ if (vect_print_dump_info (REPORT_DR_DETAILS))
+ {
+ fprintf (vect_dump,
+ "disable versioning for alias - max number of generated "
+ "checks exceeded.");
+ }
+
+ VEC_truncate (ddr_p, LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo), 0);
+
+ return false;
+ }
+ VEC_safe_push (ddr_p, heap, LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo), ddr);
+ return true;
+}
/* Function vect_analyze_data_ref_dependences.
@@ -1133,7 +1205,7 @@ static bool
vect_analyze_data_ref_dependences (loop_vec_info loop_vinfo)
{
unsigned int i;
- VEC (ddr_p, heap) *ddrs = LOOP_VINFO_DDRS (loop_vinfo);
+ VEC (ddr_p, heap) * ddrs = LOOP_VINFO_DDRS (loop_vinfo);
struct data_dependence_relation *ddr;
if (vect_print_dump_info (REPORT_DETAILS))
@@ -1141,7 +1213,11 @@ vect_analyze_data_ref_dependences (loop_vec_info loop_vinfo)
for (i = 0; VEC_iterate (ddr_p, ddrs, i, ddr); i++)
if (vect_analyze_data_ref_dependence (ddr, loop_vinfo))
+ {
+ /* Add to list of ddrs that need to be tested at run-time. */
+ if (!vect_mark_for_runtime_alias_test (ddr, loop_vinfo))
return false;
+ }
return true;
}
@@ -1554,6 +1630,7 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
bool stat;
tree stmt;
stmt_vec_info stmt_info;
+ int vect_versioning_for_alias_required;
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "=== vect_enhance_data_refs_alignment ===");
@@ -1619,9 +1696,15 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
}
}
- /* Often peeling for alignment will require peeling for loop-bound, which in
- turn requires that we know how to adjust the loop ivs after the loop. */
- if (!vect_can_advance_ivs_p (loop_vinfo)
+ vect_versioning_for_alias_required =
+ (VEC_length (ddr_p, LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo)) > 0);
+
+ /* Temporarily, if versioning for alias is required, we disable peeling
+ until we support peeling and versioning. Often peeling for alignment
+ will require peeling for loop-bound, which in turn requires that we
+ know how to adjust the loop ivs after the loop. */
+ if (vect_versioning_for_alias_required
+ || !vect_can_advance_ivs_p (loop_vinfo)
|| !slpeel_can_duplicate_loop_p (loop, single_exit (loop)))
do_peeling = false;
@@ -1749,7 +1832,7 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
if (known_alignment_for_access_p (dr)
|| VEC_length (tree,
LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo))
- >= (unsigned) PARAM_VALUE (PARAM_VECT_MAX_VERSION_CHECKS))
+ >= (unsigned) PARAM_VALUE (PARAM_VECT_MAX_VERSION_FOR_ALIGNMENT_CHECKS))
{
do_versioning = false;
break;
diff --git a/gcc/tree-vect-transform.c b/gcc/tree-vect-transform.c
index 8316aab..16beffc 100644
--- a/gcc/tree-vect-transform.c
+++ b/gcc/tree-vect-transform.c
@@ -5805,6 +5805,146 @@ vect_create_cond_for_align_checks (loop_vec_info loop_vinfo,
and_tmp_name, ptrsize_zero);
}
+/* Function vect_vfa_segment_size.
+
+ Create an expression that computes the size of segment
+ that will be accessed for a data reference. The functions takes into
+ account that realignment loads may access one more vector.
+
+ Input:
+ DR: The data reference.
+ VECT_FACTOR: vectorization factor.
+
+ Return an exrpession whose value is the size of segment which will be
+ accessed by DR. */
+
+static tree
+vect_vfa_segment_size (struct data_reference *dr, tree vect_factor)
+{
+ tree segment_length;
+
+ if (vect_supportable_dr_alignment (dr) == dr_unaligned_software_pipeline)
+ {
+ tree vector_size =
+ build_int_cst (integer_type_node,
+ GET_MODE_SIZE (TYPE_MODE (STMT_VINFO_VECTYPE
+ (vinfo_for_stmt (DR_STMT (dr))))));
+
+ segment_length =
+ fold_convert (sizetype,
+ fold_build2 (PLUS_EXPR, integer_type_node,
+ fold_build2 (MULT_EXPR, integer_type_node, DR_STEP (dr),
+ vect_factor),
+ vector_size));
+
+
+ }
+ else
+ {
+ segment_length =
+ fold_convert (sizetype,
+ fold_build2 (MULT_EXPR, integer_type_node, DR_STEP (dr),
+ vect_factor));
+ }
+
+ return segment_length;
+}
+
+/* Function vect_create_cond_for_alias_checks.
+
+ Create a conditional expression that represents the run-time checks for
+ overlapping of address ranges represented by a list of data references
+ relations passed as input.
+
+ Input:
+ COND_EXPR - input conditional expression. New conditions will be chained
+ with logical and operation.
+ LOOP_VINFO - field LOOP_VINFO_MAY_ALIAS_STMTS contains the list of ddrs
+ to be checked.
+
+ Output:
+ COND_EXPR - conditional expression.
+ COND_EXPR_STMT_LIST - statements needed to construct the conditional
+ expression.
+ The returned value is the conditional expression to be used in the if
+ statement that controls which version of the loop gets executed at runtime.
+*/
+
+static void
+vect_create_cond_for_alias_checks (loop_vec_info loop_vinfo,
+ tree * cond_expr,
+ tree * cond_expr_stmt_list)
+{
+ VEC (ddr_p, heap) * may_alias_ddrs =
+ LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo);
+ tree vect_factor =
+ build_int_cst (integer_type_node, LOOP_VINFO_VECT_FACTOR (loop_vinfo));
+
+ ddr_p ddr;
+ unsigned int i;
+ tree part_cond_expr;
+
+ /* Create expression
+ ((store_ptr_0 + store_segment_length_0) < load_ptr_0)
+ || (load_ptr_0 + load_segment_length_0) < store_ptr_0))
+ &&
+ ...
+ &&
+ ((store_ptr_n + store_segment_length_n) < load_ptr_n)
+ || (load_ptr_n + load_segment_length_n) < store_ptr_n)) */
+
+ if (VEC_empty (ddr_p, may_alias_ddrs))
+ return;
+
+ for (i = 0; VEC_iterate (ddr_p, may_alias_ddrs, i, ddr); i++)
+ {
+ tree stmt_a = DR_STMT (DDR_A (ddr));
+ tree stmt_b = DR_STMT (DDR_B (ddr));
+
+ tree addr_base_a =
+ vect_create_addr_base_for_vector_ref (stmt_a, cond_expr_stmt_list,
+ NULL_TREE);
+ tree addr_base_b =
+ vect_create_addr_base_for_vector_ref (stmt_b, cond_expr_stmt_list,
+ NULL_TREE);
+
+ tree segment_length_a = vect_vfa_segment_size (DDR_A (ddr), vect_factor);
+ tree segment_length_b = vect_vfa_segment_size (DDR_B (ddr), vect_factor);
+
+ if (vect_print_dump_info (REPORT_DR_DETAILS))
+ {
+ fprintf (vect_dump,
+ "create runtime check for data references ");
+ print_generic_expr (vect_dump, DR_REF (DDR_A (ddr)), TDF_SLIM);
+ fprintf (vect_dump, " and ");
+ print_generic_expr (vect_dump, DR_REF (DDR_B (ddr)), TDF_SLIM);
+ }
+
+
+ part_cond_expr =
+ fold_build2 (TRUTH_OR_EXPR, boolean_type_node,
+ fold_build2 (LT_EXPR, boolean_type_node,
+ fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (addr_base_a),
+ addr_base_a,
+ segment_length_a),
+ addr_base_b),
+ fold_build2 (LT_EXPR, boolean_type_node,
+ fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (addr_base_b),
+ addr_base_b,
+ segment_length_b),
+ addr_base_a));
+
+ if (*cond_expr)
+ *cond_expr = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
+ *cond_expr, part_cond_expr);
+ else
+ *cond_expr = part_cond_expr;
+ }
+ if (vect_print_dump_info (REPORT_VECTORIZED_LOOPS))
+ fprintf (vect_dump, "created %u versioning for alias checks.\n",
+ VEC_length (ddr_p, may_alias_ddrs));
+
+}
/* Function vect_transform_loop.
@@ -5827,16 +5967,21 @@ vect_transform_loop (loop_vec_info loop_vinfo)
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "=== vec_transform_loop ===");
- /* If the loop has data references that may or may not be aligned then
+ /* If the loop has data references that may or may not be aligned or/and
+ has data reference relations whose independence was not proven then
two versions of the loop need to be generated, one which is vectorized
and one which isn't. A test is then generated to control which of the
loops is executed. The test checks for the alignment of all of the
- data references that may or may not be aligned. */
+ data references that may or may not be aligned. An additional
+ sequence of runtime tests is generated for each pairs of DDRs whose
+ independence was not proven. The vectorized version of loop is
+ executed only if both alias and alignment tests are passed. */
- if (VEC_length (tree, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo)))
+ if (VEC_length (tree, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo))
+ || VEC_length (ddr_p, LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo)))
{
struct loop *nloop;
- tree cond_expr;
+ tree cond_expr = NULL_TREE;
tree cond_expr_stmt_list = NULL_TREE;
basic_block condition_bb;
block_stmt_iterator cond_exp_bsi;
@@ -5845,9 +5990,23 @@ vect_transform_loop (loop_vec_info loop_vinfo)
edge new_exit_e, e;
tree orig_phi, new_phi, arg;
unsigned prob = 4 * REG_BR_PROB_BASE / 5;
+ tree gimplify_stmt_list;
- cond_expr = vect_create_cond_for_align_checks (loop_vinfo,
+ if (VEC_length (tree, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo)))
+ cond_expr =
+ vect_create_cond_for_align_checks (loop_vinfo, &cond_expr_stmt_list);
+
+ if (VEC_length (ddr_p, LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo)))
+ vect_create_cond_for_alias_checks (loop_vinfo, &cond_expr,
&cond_expr_stmt_list);
+
+ cond_expr =
+ fold_build2 (NE_EXPR, boolean_type_node, cond_expr, integer_zero_node);
+ cond_expr =
+ force_gimple_operand (cond_expr, &gimplify_stmt_list, true,
+ NULL_TREE);
+ append_to_statement_list (gimplify_stmt_list, &cond_expr_stmt_list);
+
initialize_original_copy_tables ();
nloop = loop_version (loop, cond_expr, &condition_bb,
prob, prob, REG_BR_PROB_BASE - prob, true);
diff --git a/gcc/tree-vectorizer.c b/gcc/tree-vectorizer.c
index 6834e25..6dc0c72 100644
--- a/gcc/tree-vectorizer.c
+++ b/gcc/tree-vectorizer.c
@@ -1414,8 +1414,11 @@ new_loop_vec_info (struct loop *loop)
LOOP_VINFO_DATAREFS (res) = VEC_alloc (data_reference_p, heap, 10);
LOOP_VINFO_DDRS (res) = VEC_alloc (ddr_p, heap, 10 * 10);
LOOP_VINFO_UNALIGNED_DR (res) = NULL;
- LOOP_VINFO_MAY_MISALIGN_STMTS (res)
- = VEC_alloc (tree, heap, PARAM_VALUE (PARAM_VECT_MAX_VERSION_CHECKS));
+ LOOP_VINFO_MAY_MISALIGN_STMTS (res) =
+ VEC_alloc (tree, heap, PARAM_VALUE (PARAM_VECT_MAX_VERSION_FOR_ALIGNMENT_CHECKS));
+ LOOP_VINFO_MAY_ALIAS_DDRS (res) =
+ VEC_alloc (ddr_p, heap, PARAM_VALUE (PARAM_VECT_MAX_VERSION_FOR_ALIAS_CHECKS));
+
return res;
}
@@ -1495,6 +1498,7 @@ destroy_loop_vec_info (loop_vec_info loop_vinfo)
free_data_refs (LOOP_VINFO_DATAREFS (loop_vinfo));
free_dependence_relations (LOOP_VINFO_DDRS (loop_vinfo));
VEC_free (tree, heap, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo));
+ VEC_free (ddr_p, heap, LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo));
free (loop_vinfo);
loop->aux = NULL;
diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h
index 40f2205..d96b944 100644
--- a/gcc/tree-vectorizer.h
+++ b/gcc/tree-vectorizer.h
@@ -133,6 +133,10 @@ typedef struct _loop_vec_info {
/* All data dependences in the loop. */
VEC (ddr_p, heap) *ddrs;
+ /* Data Dependence Relations defining address ranges that are candidates
+ for a run-time aliasing check. */
+ VEC (ddr_p, heap) *may_alias_ddrs;
+
/* Statements in the loop that have data references that are candidates for a
runtime (loop versioning) misalignment check. */
VEC(tree,heap) *may_misalign_stmts;
@@ -157,6 +161,7 @@ typedef struct _loop_vec_info {
#define LOOP_VINFO_UNALIGNED_DR(L) (L)->unaligned_dr
#define LOOP_VINFO_MAY_MISALIGN_STMTS(L) (L)->may_misalign_stmts
#define LOOP_VINFO_LOC(L) (L)->loop_line_number
+#define LOOP_VINFO_MAY_ALIAS_DDRS(L) (L)->may_alias_ddrs
#define NITERS_KNOWN_P(n) \
(host_integerp ((n),0) \