diff options
author | Richard Biener <rguenther@suse.de> | 2013-04-15 14:08:41 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2013-04-15 14:08:41 +0000 |
commit | 5185d248d5a554d394c80126646160abbf4f0bfa (patch) | |
tree | 52afb1966c9cc2b68285ff2632e2f574ef6e4c9d /gcc | |
parent | a24243a0e5e09bd562eeb362c1c89ee497ea67e7 (diff) | |
download | gcc-5185d248d5a554d394c80126646160abbf4f0bfa.zip gcc-5185d248d5a554d394c80126646160abbf4f0bfa.tar.gz gcc-5185d248d5a554d394c80126646160abbf4f0bfa.tar.bz2 |
re PR tree-optimization/56933 (Vectorizer missing read-write dependency for interleaved accesses)
2013-04-15 Richard Biener <rguenther@suse.de>
PR tree-optimization/56933
* tree-vectorizer.h (struct _stmt_vec_info): Remove read_write_dep
member.
(GROUP_READ_WRITE_DEPENDENCE): Remove.
(STMT_VINFO_GROUP_READ_WRITE_DEPENDENCE): Likewise.
* tree-vect-data-refs.c (vect_analyze_group_access): Move
dependence check ...
vect_analyze_data_ref_dependence (vect_analyze_data_ref_dependence):
... here.
* tree-vect-stmts.c (new_stmt_vec_info): Do not initialize
GROUP_READ_WRITE_DEPENDENCE.
* gcc.dg/vect/pr56933.c: New testcase.
From-SVN: r197972
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 14 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/vect/pr56933.c | 40 | ||||
-rw-r--r-- | gcc/tree-vect-data-refs.c | 47 | ||||
-rw-r--r-- | gcc/tree-vect-stmts.c | 1 | ||||
-rw-r--r-- | gcc/tree-vectorizer.h | 6 |
6 files changed, 87 insertions, 26 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index fd1731e..db1b373 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2013-04-15 Richard Biener <rguenther@suse.de> + + PR tree-optimization/56933 + * tree-vectorizer.h (struct _stmt_vec_info): Remove read_write_dep + member. + (GROUP_READ_WRITE_DEPENDENCE): Remove. + (STMT_VINFO_GROUP_READ_WRITE_DEPENDENCE): Likewise. + * tree-vect-data-refs.c (vect_analyze_group_access): Move + dependence check ... + vect_analyze_data_ref_dependence (vect_analyze_data_ref_dependence): + ... here. + * tree-vect-stmts.c (new_stmt_vec_info): Do not initialize + GROUP_READ_WRITE_DEPENDENCE. + 2013-04-15 Andreas Krebbel <Andreas.Krebbel@de.ibm.com> * emit-rtl.c (reset_all_used_flags): New function. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index efc3ded..4613593 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2013-04-15 Richard Biener <rguenther@suse.de> + + PR tree-optimization/56933 + * gcc.dg/vect/pr56933.c: New testcase. + 2013-04-15 Kyrylo Tkachov <kyrylo.tkachov@arm.com> * gcc.target/arm/anddi3-opt.c: New test. diff --git a/gcc/testsuite/gcc.dg/vect/pr56933.c b/gcc/testsuite/gcc.dg/vect/pr56933.c new file mode 100644 index 0000000..93a7da2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr56933.c @@ -0,0 +1,40 @@ +/* { dg-do run } */ + +extern void abort (void); +void __attribute__((noinline,noclone)) +foo (double *b, double *d, double *f) +{ + int i; + for (i = 0; i < 1024; i++) + { + d[2*i] = 2. * d[2*i]; + d[2*i+1] = 4. * d[2*i+1]; + b[i] = d[2*i] - 1.; + f[i] = d[2*i+1] + 2.; + } +} +int main() +{ + double b[1024], d[2*1024], f[1024]; + int i; + for (i = 0; i < 2*1024; i++) + d[i] = 1.; + foo (b, d, f); + for (i = 0; i < 1024; i+= 2) + { + if (d[2*i] != 2.) + abort (); + if (d[2*i+1] != 4.) + abort (); + } + for (i = 0; i < 1024; i++) + { + if (b[i] != 1.) + abort (); + if (f[i] != 6.) + abort (); + } + return 0; +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c index 64f2a8b..1fe5047 100644 --- a/gcc/tree-vect-data-refs.c +++ b/gcc/tree-vect-data-refs.c @@ -341,14 +341,34 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr, dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (drb)); } - /* For interleaving, mark that there is a read-write dependency if - necessary. We check before that one of the data-refs is store. */ - if (DR_IS_READ (dra)) - GROUP_READ_WRITE_DEPENDENCE (stmtinfo_a) = true; - else - { - if (DR_IS_READ (drb)) - GROUP_READ_WRITE_DEPENDENCE (stmtinfo_b) = true; + /* When we perform grouped accesses and perform implicit CSE + by detecting equal accesses and doing disambiguation with + runtime alias tests like for + .. = a[i]; + .. = a[i+1]; + a[i] = ..; + a[i+1] = ..; + *p = ..; + .. = a[i]; + .. = a[i+1]; + where we will end up loading { a[i], a[i+1] } once, make + sure that inserting group loads before the first load and + stores after the last store will do the right thing. */ + if ((STMT_VINFO_GROUPED_ACCESS (stmtinfo_a) + && GROUP_SAME_DR_STMT (stmtinfo_a)) + || (STMT_VINFO_GROUPED_ACCESS (stmtinfo_b) + && GROUP_SAME_DR_STMT (stmtinfo_b))) + { + gimple earlier_stmt; + earlier_stmt = get_earlier_stmt (DR_STMT (dra), DR_STMT (drb)); + if (DR_IS_WRITE + (STMT_VINFO_DATA_REF (vinfo_for_stmt (earlier_stmt)))) + { + if (dump_enabled_p ()) + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "READ_WRITE dependence in interleaving."); + return true; + } } continue; @@ -2097,17 +2117,6 @@ vect_analyze_group_access (struct data_reference *dr) return false; } - /* Check that there is no load-store dependencies for this loads - to prevent a case of load-store-load to the same location. */ - if (GROUP_READ_WRITE_DEPENDENCE (vinfo_for_stmt (next)) - || GROUP_READ_WRITE_DEPENDENCE (vinfo_for_stmt (prev))) - { - if (dump_enabled_p ()) - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "READ_WRITE dependence in interleaving."); - return false; - } - /* For load use the same data-ref load. */ GROUP_SAME_DR_STMT (vinfo_for_stmt (next)) = prev; diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c index 3590e39..bdd4d64 100644 --- a/gcc/tree-vect-stmts.c +++ b/gcc/tree-vect-stmts.c @@ -5962,7 +5962,6 @@ new_stmt_vec_info (gimple stmt, loop_vec_info loop_vinfo, GROUP_STORE_COUNT (res) = 0; GROUP_GAP (res) = 0; GROUP_SAME_DR_STMT (res) = NULL; - GROUP_READ_WRITE_DEPENDENCE (res) = false; return res; } diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h index 0f1a02a..8071149 100644 --- a/gcc/tree-vectorizer.h +++ b/gcc/tree-vectorizer.h @@ -460,10 +460,6 @@ typedef struct _stmt_vec_info { /* Stmt is part of some pattern (computation idiom) */ bool in_pattern_p; - /* For loads only, if there is a store with the same location, this field is - TRUE. */ - bool read_write_dep; - /* The stmt to which this info struct refers to. */ gimple stmt; @@ -589,7 +585,6 @@ typedef struct _stmt_vec_info { #define STMT_VINFO_GROUP_STORE_COUNT(S) (S)->store_count #define STMT_VINFO_GROUP_GAP(S) (S)->gap #define STMT_VINFO_GROUP_SAME_DR_STMT(S) (S)->same_dr_stmt -#define STMT_VINFO_GROUP_READ_WRITE_DEPENDENCE(S) (S)->read_write_dep #define STMT_VINFO_GROUPED_ACCESS(S) ((S)->first_element != NULL && (S)->data_ref_info) #define STMT_VINFO_LOOP_PHI_EVOLUTION_PART(S) (S)->loop_phi_evolution_part @@ -599,7 +594,6 @@ typedef struct _stmt_vec_info { #define GROUP_STORE_COUNT(S) (S)->store_count #define GROUP_GAP(S) (S)->gap #define GROUP_SAME_DR_STMT(S) (S)->same_dr_stmt -#define GROUP_READ_WRITE_DEPENDENCE(S) (S)->read_write_dep #define STMT_VINFO_RELEVANT_P(S) ((S)->relevant != vect_unused_in_scope) |