From a8cf7702cb82312e61c45744d402be05174dddb9 Mon Sep 17 00:00:00 2001 From: rguenth Date: Fri, 21 Feb 2014 13:18:54 +0000 Subject: [PATCH] 2014-02-21 Richard Biener PR tree-optimization/60276 * tree-vectorizer.h (struct _stmt_vec_info): Add min_neg_dist field. (STMT_VINFO_MIN_NEG_DIST): New macro. * tree-vect-data-refs.c (vect_analyze_data_ref_dependence): Record STMT_VINFO_MIN_NEG_DIST. * tree-vect-stmts.c (vectorizable_load): Verify if assumptions made for negative dependence distances still hold. * gcc.dg/vect/pr60276.c: New testcase. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@207992 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 10 +++++++ gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/gcc.dg/vect/pr60276.c | 52 +++++++++++++++++++++++++++++++++++++ gcc/tree-vect-data-refs.c | 7 +++++ gcc/tree-vect-stmts.c | 28 ++++++++++++++++++++ gcc/tree-vectorizer.h | 5 ++++ 6 files changed, 107 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/vect/pr60276.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2acc2dfd99f..d93ac6d37d9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,15 @@ 2014-02-21 Richard Biener + PR tree-optimization/60276 + * tree-vectorizer.h (struct _stmt_vec_info): Add min_neg_dist field. + (STMT_VINFO_MIN_NEG_DIST): New macro. + * tree-vect-data-refs.c (vect_analyze_data_ref_dependence): Record + STMT_VINFO_MIN_NEG_DIST. + * tree-vect-stmts.c (vectorizable_load): Verify if assumptions + made for negative dependence distances still hold. + +2014-02-21 Richard Biener + PR middle-end/60291 * tree-ssa-live.c (mark_all_vars_used_1): Do not walk DECL_INITIAL for globals not in the current function context. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a247f720eed..ef9d0f53797 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2014-02-21 Richard Biener + + PR tree-optimization/60276 + * gcc.dg/vect/pr60276.c: New testcase. + 2014-02-21 Janus Weil PR fortran/60234 diff --git a/gcc/testsuite/gcc.dg/vect/pr60276.c b/gcc/testsuite/gcc.dg/vect/pr60276.c new file mode 100644 index 00000000000..d4ad2198062 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr60276.c @@ -0,0 +1,52 @@ +/* { dg-do run } */ + +extern void abort (void); + +static void +foo (int *out, const int *lp, unsigned samples) +{ + int x, target; + for (x = 0, target = 0; x < (int)samples; x += 2, target++) + { + out[x] = lp[target]; + out[x - 1] = out[x - 2] + out[x]; + } +} + +static void +foo_novec (int *out, const int *lp, unsigned samples) +{ + int x, target; + for (x = 0, target = 0; x < (int)samples; x += 2, target++) + { + out[x] = lp[target]; + out[x - 1] = out[x - 2] + out[x]; + __asm__ volatile ("" : : : "memory"); + } +} + +int main(void) +{ + const int lp[25] = { + 0, 2, 4, 6, 8, + 10, 12, 14, 16, + 18, 20, 22, 24, + 26, 28, 30, 32, + 34, 36, 38, 40, + 42, 44, 46, 48, + }; + int out[49] = {0}; + int out2[49] = {0}; + int s; + + foo (out + 2, lp + 1, 48); + foo_novec (out2 + 2, lp + 1, 48); + + for (s = 0; s < 49; s++) + if (out[s] != out2[s]) + 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 e973b34a1a7..fbc35a3fe3c 100644 --- a/gcc/tree-vect-data-refs.c +++ b/gcc/tree-vect-data-refs.c @@ -403,6 +403,13 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr, if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, "dependence distance negative.\n"); + /* Record a negative dependence distance to later limit the + amount of stmt copying / unrolling we can perform. + Only need to handle read-after-write dependence. */ + if (DR_IS_READ (drb) + && (STMT_VINFO_MIN_NEG_DIST (stmtinfo_b) == 0 + || STMT_VINFO_MIN_NEG_DIST (stmtinfo_b) > (unsigned)dist)) + STMT_VINFO_MIN_NEG_DIST (stmtinfo_b) = dist; continue; } diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c index 7e47feb61fc..70fb411f8f5 100644 --- a/gcc/tree-vect-stmts.c +++ b/gcc/tree-vect-stmts.c @@ -5629,6 +5629,20 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt, return false; } + /* Invalidate assumptions made by dependence analysis when vectorization + on the unrolled body effectively re-orders stmts. */ + if (ncopies > 1 + && STMT_VINFO_MIN_NEG_DIST (stmt_info) != 0 + && ((unsigned)LOOP_VINFO_VECT_FACTOR (loop_vinfo) + > STMT_VINFO_MIN_NEG_DIST (stmt_info))) + { + if (dump_enabled_p ()) + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "cannot perform implicit CSE when unrolling " + "with negative dependence distance\n"); + return false; + } + if (!STMT_VINFO_RELEVANT_P (stmt_info) && !bb_vinfo) return false; @@ -5686,6 +5700,20 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt, else if (!vect_grouped_load_supported (vectype, group_size)) return false; } + + /* Invalidate assumptions made by dependence analysis when vectorization + on the unrolled body effectively re-orders stmts. */ + if (!PURE_SLP_STMT (stmt_info) + && STMT_VINFO_MIN_NEG_DIST (stmt_info) != 0 + && ((unsigned)LOOP_VINFO_VECT_FACTOR (loop_vinfo) + > STMT_VINFO_MIN_NEG_DIST (stmt_info))) + { + if (dump_enabled_p ()) + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "cannot perform implicit CSE when performing " + "group loads with negative dependence distance\n"); + return false; + } } diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h index 51367ea2500..f8efe471e06 100644 --- a/gcc/tree-vectorizer.h +++ b/gcc/tree-vectorizer.h @@ -622,6 +622,10 @@ typedef struct _stmt_vec_info { is 1. */ unsigned int gap; + /* The minimum negative dependence distance this stmt participates in + or zero if none. */ + unsigned int min_neg_dist; + /* Not all stmts in the loop need to be vectorized. e.g, the increment of the loop induction variable and computation of array indexes. relevant indicates whether the stmt needs to be vectorized. */ @@ -677,6 +681,7 @@ typedef struct _stmt_vec_info { #define STMT_VINFO_GROUP_SAME_DR_STMT(S) (S)->same_dr_stmt #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 +#define STMT_VINFO_MIN_NEG_DIST(S) (S)->min_neg_dist #define GROUP_FIRST_ELEMENT(S) (S)->first_element #define GROUP_NEXT_ELEMENT(S) (S)->next_element -- 2.11.4.GIT