summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog15
-rw-r--r--gcc/testsuite/ChangeLog11
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-91.c70
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-dv-2.c3
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-ifcvt-1.c3
-rw-r--r--gcc/testsuite/gfortran.dg/vect/vect-4.f9010
-rw-r--r--gcc/tree-vect-analyze.c24
-rw-r--r--gcc/tree-vect-transform.c8
-rw-r--r--gcc/tree-vectorizer.c10
-rw-r--r--gcc/tree-vectorizer.h9
10 files changed, 146 insertions, 17 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 63217307609..13c5668e3bc 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,18 @@
+2005-06-10 Dorit Nuzman <dorit@il.ibm.com>
+
+ * tree-vect-analyze.c (vect_analyze_data_ref_dependence): DRs whose
+ dependence-distance modulo VF is 0 are recorded in the
+ SAME_ALIGN_REFs VEC in each DR.
+ (vect_enhance_data_refs_alignment): Avoid 80 column overflow. The
+ alignment information of DRs that are in the SAME_ALIGN_REFs VEC of the
+ DR we want to peel for, is set to 0.
+ * tree-vect-transform.c (vect_do_peeling_for_loop_bound): Fix printout.
+ * tree-vectorizer.c (destroy_loop_vec_info): Free the SAME_ALIGN_REFs
+ VEC.
+ * tree-vectorizer.h (dr_p): New type. Defined to use the VEC API.
+ (_stmt_vec_info): Added new field same_align_refs.
+ (STMT_VINFO_SAME_ALIGN_REFS): New macro.
+
2005-06-10 Nathan Sidwell <nathan@codesourcery.com>
* vec.h (VEC_safe_grow): Append MEM_STAT_INFO.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 7fc18e98ed6..5c33debf421 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,14 @@
+2005-06-10 Dorit Nuzman <dorit@il.ibm.com>
+
+ * gfortran.dg/vect/vect-4.f90: Update comments. Only one unaligned
+ access will be generated when this loop is vectorized. Test that
+ accesses with same alignment were detected.
+ * gcc.dg/vect/vect-dv-2.c: Remove "vect_no_align" from xfail.
+ Test that accesses with same alignment were detected.
+ * gcc.dg/vect/vect-ifcvt-1.c: Likewise.
+ * gcc.dg/vect/vect-91.c: New test. Test that accesses with same
+ alignment were detected.
+
2005-06-09 Gabriel Dos Reis <gdr@integrable-solutions.net>
* gcc.dg/Wcxx-compat-1.c: New.
diff --git a/gcc/testsuite/gcc.dg/vect/vect-91.c b/gcc/testsuite/gcc.dg/vect/vect-91.c
new file mode 100644
index 00000000000..80afd692d35
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-91.c
@@ -0,0 +1,70 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_int } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 256
+
+extern int a[N];
+
+/* The alignment of 'pa' is unknown.
+ Yet we do know that both the read access and write access have
+ the same alignment. Peeling to align one of the accesses will
+ align the other.
+
+ Not vectorized yet due to problems in dataref analysis that
+ are fixed in autovect-branch but not yet in mainline. */
+
+int
+main1 (int * pa)
+{
+ int i;
+
+ for (i = 0; i < N; i++)
+ {
+ pa[i] = pa[i] + 1;
+ }
+
+ return 0;
+}
+
+/* The alignment of 'a' is unknown.
+ Yet we do know that both the read access and write access have
+ the same alignment. Peeling to align one of the accesses will
+ align the other. */
+
+int
+main2 ()
+{
+ int i;
+
+ for (i = 0; i < N; i++)
+ {
+ a[i] = a[i] + 1;
+ }
+
+ return 0;
+}
+
+int
+main3 ()
+{
+ int i;
+
+ for (i = 0; i < N; i++)
+ {
+ a[i] = a[i+20];
+ }
+
+ return 0;
+}
+
+/* Currently only the loops in main2 and main3 get vectorized. After the merge
+ of the datarefs-analysis cleanups from autovect-branch to mainline, the loop
+ in main1 will also be vectorized. */
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" } } */
+/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" } } */
+/* { dg-final { scan-tree-dump-times "accesses have the same alignment." 2 "vect" } } */
+/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 2 "vect" } } */
+/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-dv-2.c b/gcc/testsuite/gcc.dg/vect/vect-dv-2.c
index 24d5eb3c4b9..69d619ed1ea 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-dv-2.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-dv-2.c
@@ -69,5 +69,6 @@ int main ()
-/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" { xfail vect_no_align } } } */
+/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" } } */
+/* { dg-final { scan-tree-dump-times "accesses have the same alignment." 2 "vect" } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-ifcvt-1.c b/gcc/testsuite/gcc.dg/vect/vect-ifcvt-1.c
index 715e9906974..7b40998568b 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-ifcvt-1.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-ifcvt-1.c
@@ -70,5 +70,6 @@ int main ()
-/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" { xfail vect_no_align } } } */
+/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" } } */
+/* { dg-final { scan-tree-dump-times "accesses have the same alignment." 2 "vect" } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gfortran.dg/vect/vect-4.f90 b/gcc/testsuite/gfortran.dg/vect/vect-4.f90
index 77664f8fa08..e83c05c5e50 100644
--- a/gcc/testsuite/gfortran.dg/vect/vect-4.f90
+++ b/gcc/testsuite/gfortran.dg/vect/vect-4.f90
@@ -1,14 +1,18 @@
! { dg-do compile }
! { dg-require-effective-target vect_float }
+! Peeling to align the store to Y will also align the load from Y.
+! The load from X may still be misaligned.
+
SUBROUTINE SAXPY(X, Y, A)
DIMENSION X(64), Y(64)
Y = Y + A * X
END
-! fail to vectorize until the patch that ignores dependence-distance 0 is
-! brought from autovect.
+! fail to vectorize due to aliasing problems in dataref analysis that are
+! solved in autvect-branch but not yet in mainline.
! { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } }
! { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { xfail *-*-* } } }
-! { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { xfail *-*-* } } }
+! { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail *-*-* } } }
+! { dg-final { scan-tree-dump-times "accesses have the same alignment." 1 "vect" { xfail *-*-* } } }
! { dg-final { cleanup-tree-dump "vect" } }
diff --git a/gcc/tree-vect-analyze.c b/gcc/tree-vect-analyze.c
index 0b8e26ce9e1..da033c82874 100644
--- a/gcc/tree-vect-analyze.c
+++ b/gcc/tree-vect-analyze.c
@@ -853,7 +853,8 @@ vect_analyze_data_ref_dependence (struct data_reference *dra,
int dist = 0;
unsigned int loop_depth = 0;
struct loop *loop_nest = loop;
-
+ stmt_vec_info stmtinfo_a = vinfo_for_stmt (DR_STMT (dra));
+ stmt_vec_info stmtinfo_b = vinfo_for_stmt (DR_STMT (drb));
if (!vect_base_addr_differ_p (dra, drb, &differ_p))
{
@@ -924,10 +925,13 @@ vect_analyze_data_ref_dependence (struct data_reference *dra,
dist = DDR_DIST_VECT (ddr)[loop_depth];
/* Same loop iteration. */
- if (dist == 0)
+ if (dist % vectorization_factor == 0)
{
- if (vect_print_dump_info (REPORT_DETAILS, LOOP_LOC (loop_vinfo)))
- fprintf (vect_dump, "dependence distance 0.");
+ /* Two references with distance zero have the same alignment. */
+ VEC_safe_push (dr_p, heap, STMT_VINFO_SAME_ALIGN_REFS (stmtinfo_a), drb);
+ VEC_safe_push (dr_p, heap, STMT_VINFO_SAME_ALIGN_REFS (stmtinfo_b), dra);
+ if (vect_print_dump_info (REPORT_ALIGNMENT, LOOP_LOC (loop_vinfo)))
+ fprintf (vect_dump, "accesses have the same alignment.");
return false;
}
@@ -1146,7 +1150,9 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
varray_type loop_read_datarefs = LOOP_VINFO_DATAREF_READS (loop_vinfo);
varray_type loop_write_datarefs = LOOP_VINFO_DATAREF_WRITES (loop_vinfo);
varray_type datarefs;
+ VEC(dr_p,heap) *same_align_drs;
struct data_reference *dr0 = NULL;
+ struct data_reference *dr;
unsigned int i, j;
/*
@@ -1300,7 +1306,8 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
else if (known_alignment_for_access_p (dr)
&& known_alignment_for_access_p (dr0))
{
- int drsize = GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (DR_REF (dr))));
+ int drsize =
+ GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (DR_REF (dr))));
DR_MISALIGNMENT (dr) += npeel * drsize;
DR_MISALIGNMENT (dr) %= UNITS_PER_SIMD_WORD;
@@ -1311,6 +1318,13 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
datarefs = loop_read_datarefs;
}
+ same_align_drs =
+ STMT_VINFO_SAME_ALIGN_REFS (vinfo_for_stmt (DR_STMT (dr0)));
+ for (i = 0; VEC_iterate (dr_p, same_align_drs, i, dr); i++)
+ {
+ DR_MISALIGNMENT (dr) = 0;
+ }
+
DR_MISALIGNMENT (dr0) = 0;
}
}
diff --git a/gcc/tree-vect-transform.c b/gcc/tree-vect-transform.c
index f5724dbbd77..116f01a5fe4 100644
--- a/gcc/tree-vect-transform.c
+++ b/gcc/tree-vect-transform.c
@@ -962,9 +962,9 @@ vectorizable_store (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
{
SSA_NAME_DEF_STMT (def) = *vec_stmt;
- /* If this virtual def has a use outside the loop and a loop peel is performed
- then the def may be renamed by the peel. Mark it for renaming so the
- later use will also be renamed. */
+ /* If this virtual def has a use outside the loop and a loop peel is
+ performed then the def may be renamed by the peel. Mark it for
+ renaming so the later use will also be renamed. */
mark_sym_for_renaming (SSA_NAME_VAR (def));
}
@@ -1776,7 +1776,7 @@ vect_do_peeling_for_loop_bound (loop_vec_info loop_vinfo, tree *ratio,
#endif
if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
- fprintf (vect_dump, "=== vect_transtorm_for_unknown_loop_bound ===");
+ fprintf (vect_dump, "=== vect_do_peeling_for_loop_bound ===");
/* Generate the following variables on the preheader of original loop:
diff --git a/gcc/tree-vectorizer.c b/gcc/tree-vectorizer.c
index 53f5358194e..c6002c446ff 100644
--- a/gcc/tree-vectorizer.c
+++ b/gcc/tree-vectorizer.c
@@ -1457,10 +1457,14 @@ destroy_loop_vec_info (loop_vec_info loop_vinfo)
{
tree stmt = bsi_stmt (si);
stmt_ann_t ann = stmt_ann (stmt);
-
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
- free (stmt_info);
- set_stmt_info ((tree_ann_t)ann, NULL);
+
+ if (stmt_info)
+ {
+ VEC_free (dr_p, heap, STMT_VINFO_SAME_ALIGN_REFS (stmt_info));
+ free (stmt_info);
+ set_stmt_info ((tree_ann_t)ann, NULL);
+ }
}
}
diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h
index 739da71fea9..7892e0a99ca 100644
--- a/gcc/tree-vectorizer.h
+++ b/gcc/tree-vectorizer.h
@@ -158,6 +158,10 @@ enum stmt_vec_info_type {
condition_vec_info_type
};
+typedef struct data_reference *dr_p;
+DEF_VEC_P(dr_p);
+DEF_VEC_ALLOC_P(dr_p,heap);
+
typedef struct _stmt_vec_info {
enum stmt_vec_info_type type;
@@ -230,6 +234,10 @@ typedef struct _stmt_vec_info {
in bytes. */
tree misalignment;
+ /* List of datarefs that are known to have the same alignment as the dataref
+ of this stmt. */
+ VEC(dr_p,heap) *same_align_refs;
+
/* Classify the def of this stmt. */
enum vect_def_type def_type;
@@ -252,6 +260,7 @@ typedef struct _stmt_vec_info {
#define STMT_VINFO_VECT_STEP(S) (S)->step
#define STMT_VINFO_VECT_BASE_ALIGNED_P(S) (S)->base_aligned_p
#define STMT_VINFO_VECT_MISALIGNMENT(S) (S)->misalignment
+#define STMT_VINFO_SAME_ALIGN_REFS(S) (S)->same_align_refs
#define STMT_VINFO_DEF_TYPE(S) (S)->def_type
static inline void set_stmt_info (tree_ann_t ann, stmt_vec_info stmt_info);