diff options
-rw-r--r-- | gcc/ChangeLog | 15 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/vect/vect-91.c | 70 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/vect/vect-dv-2.c | 3 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/vect/vect-ifcvt-1.c | 3 | ||||
-rw-r--r-- | gcc/testsuite/gfortran.dg/vect/vect-4.f90 | 10 | ||||
-rw-r--r-- | gcc/tree-vect-analyze.c | 24 | ||||
-rw-r--r-- | gcc/tree-vect-transform.c | 8 | ||||
-rw-r--r-- | gcc/tree-vectorizer.c | 10 | ||||
-rw-r--r-- | gcc/tree-vectorizer.h | 9 |
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); |