summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorirar <irar@138bc75d-0d04-0410-961f-82ee72b054a4>2007-01-21 09:22:56 +0000
committerirar <irar@138bc75d-0d04-0410-961f-82ee72b054a4>2007-01-21 09:22:56 +0000
commite51f51369523d5faab32134f260cca822e323ba2 (patch)
tree05e8577ec4efe6bacd28333f67700b524ca9e2a3 /gcc
parent72b3fc432141c1b4fe54f39eeb29a59b7123a18e (diff)
downloadgcc-e51f51369523d5faab32134f260cca822e323ba2.tar.gz
* tree-vectorizer.h (struct _stmt_vec_info): Add new field
read_write_dep and macros for its access. * tree-vectorizer.c (new_stmt_vec_info): Initialize the new field. * tree-vect-analyze.c (vect_analyze_data_ref_dependence): Remove argument, call vect_check_interleaving for every independent pair of data-refs. Mark loads that access the same memory location as a store in the loop. (vect_check_dependences): Remove. (vect_analyze_data_ref_dependences): Remove vect_check_dependences call, fix the call to vect_analyze_data_ref_dependence. (vect_analyze_data_ref_access): For statements that access the same data-ref, check that they are not stores; for loads, check that there is no store that access the same location. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@121026 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog16
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-strided-same-dr.c77
-rw-r--r--gcc/tree-vect-analyze.c87
-rw-r--r--gcc/tree-vectorizer.c1
-rw-r--r--gcc/tree-vectorizer.h5
6 files changed, 138 insertions, 52 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 62680caf704..de0752707b2 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,19 @@
+2007-01-21 Ira Rosen <irar@il.ibm.com>
+
+ * tree-vectorizer.h (struct _stmt_vec_info): Add new field
+ read_write_dep and macros for its access.
+ * tree-vectorizer.c (new_stmt_vec_info): Initialize the new field.
+ * tree-vect-analyze.c (vect_analyze_data_ref_dependence): Remove
+ argument, call vect_check_interleaving for every independent pair of
+ data-refs. Mark loads that access the same memory location as a store
+ in the loop.
+ (vect_check_dependences): Remove.
+ (vect_analyze_data_ref_dependences): Remove vect_check_dependences
+ call, fix the call to vect_analyze_data_ref_dependence.
+ (vect_analyze_data_ref_access): For statements that access the same
+ data-ref, check that they are not stores; for loads, check that there
+ is no store that access the same location.
+
2007-01-20 Roger Sayle <roger@eyesopen.com>
Joseph Myers <joseph@codesourcery.com>
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 320c9020359..d248286770e 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2007-01-21 Ira Rosen <irar@il.ibm.com>
+
+ * gcc.dg/vect/vect-strided-same-dr.c: New test.
+
2007-01-20 Andrew Pinski <pinskia@gmail.com>
PR objc/30479
diff --git a/gcc/testsuite/gcc.dg/vect/vect-strided-same-dr.c b/gcc/testsuite/gcc.dg/vect/vect-strided-same-dr.c
new file mode 100644
index 00000000000..f04658d1d07
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-strided-same-dr.c
@@ -0,0 +1,77 @@
+/* { dg-require-effective-target vect_int } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 128
+
+typedef struct {
+ unsigned short a;
+ unsigned short b;
+} s;
+
+s buffer1[N], buffer2[N];
+
+int
+main1 (s * __restrict__ pIn, s* __restrict__ pOut)
+{
+ unsigned short i, x, y, d;
+ s *p, *q;
+
+ p = pIn;
+ q = pOut;
+
+ for (i = 0; i < N/2; i++)
+ {
+ x = pIn->a + 5;
+ y = pIn->a + 2;
+ pOut->a = x;
+ pOut->b = pIn->b;
+ pOut++;
+ pOut->a = y;
+ pOut->b = pIn->b;
+ pOut++;
+ pIn++;
+ }
+
+ /* check results: */
+ for (i = 0; i < N/2; i++)
+ {
+ if (q->a != p->a + 5
+ || q->b != p->b)
+ abort ();
+ q++;
+ if (q->a != p->a + 2
+ || q->b != p->b)
+ abort ();
+ q++;
+ p++;
+ }
+
+ return 0;
+}
+
+int main (void)
+{
+ short i;
+
+ for (i = 0; i < N*2; i++)
+ {
+ buffer1[i].a = i;
+ buffer1[i].b = i + 8;
+ buffer2[i].a = i * 3;
+ buffer2[i].b = i * 2;
+ if (buffer1[i].a == 500)
+ abort();
+ }
+
+ check_vect ();
+
+ main1 (buffer1, buffer2);
+
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_interleave && vect_extract_even_odd } } } } */
+/* { dg-final { cleanup-tree-dump "vect" } } */
+
diff --git a/gcc/tree-vect-analyze.c b/gcc/tree-vect-analyze.c
index 114f8236a6c..c53c34e2c51 100644
--- a/gcc/tree-vect-analyze.c
+++ b/gcc/tree-vect-analyze.c
@@ -57,7 +57,7 @@ static bool vect_determine_vectorization_factor (loop_vec_info);
static bool exist_non_indexing_operands_for_use_p (tree, tree);
static tree vect_get_loop_niters (struct loop *, tree *);
static bool vect_analyze_data_ref_dependence
- (struct data_dependence_relation *, loop_vec_info, bool);
+ (struct data_dependence_relation *, loop_vec_info);
static bool vect_compute_data_ref_alignment (struct data_reference *);
static bool vect_analyze_data_ref_access (struct data_reference *);
static bool vect_can_advance_ivs_p (loop_vec_info);
@@ -877,8 +877,7 @@ vect_check_interleaving (struct data_reference *dra,
static bool
vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr,
- loop_vec_info loop_vinfo,
- bool check_interleaving)
+ loop_vec_info loop_vinfo)
{
unsigned int i;
struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
@@ -895,8 +894,7 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr,
if (DDR_ARE_DEPENDENT (ddr) == chrec_known)
{
/* Independent data accesses. */
- if (check_interleaving)
- vect_check_interleaving (dra, drb);
+ vect_check_interleaving (dra, drb);
return false;
}
@@ -951,7 +949,18 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr,
fprintf (vect_dump, " and ");
print_generic_expr (vect_dump, DR_REF (drb), TDF_SLIM);
}
- continue;
+
+ /* 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))
+ DR_GROUP_READ_WRITE_DEPENDENCE (stmtinfo_a) = true;
+ else
+ {
+ if (DR_IS_READ (drb))
+ DR_GROUP_READ_WRITE_DEPENDENCE (stmtinfo_b) = true;
+ }
+
+ continue;
}
if (abs (dist) >= vectorization_factor)
@@ -979,36 +988,6 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr,
}
-/* Function vect_check_dependences.
-
- Return TRUE if there is a store-store or load-store dependence between
- data-refs in DDR, otherwise return FALSE. */
-
-static bool
-vect_check_dependences (struct data_dependence_relation *ddr)
-{
- struct data_reference *dra = DDR_A (ddr);
- struct data_reference *drb = DDR_B (ddr);
-
- if (DDR_ARE_DEPENDENT (ddr) == chrec_known || dra == drb)
- /* Independent or same data accesses. */
- return false;
-
- if (DR_IS_READ (dra) == DR_IS_READ (drb) && DR_IS_READ (dra))
- /* Two loads. */
- return false;
-
- if (vect_print_dump_info (REPORT_DR_DETAILS))
- {
- fprintf (vect_dump, "possible store or store/load 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);
- }
- return true;
-}
-
-
/* Function vect_analyze_data_ref_dependences.
Examine all the data references in the loop, and make sure there do not
@@ -1020,24 +999,12 @@ vect_analyze_data_ref_dependences (loop_vec_info loop_vinfo)
unsigned int i;
VEC (ddr_p, heap) *ddrs = LOOP_VINFO_DDRS (loop_vinfo);
struct data_dependence_relation *ddr;
- bool check_interleaving = true;
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "=== vect_analyze_dependences ===");
- /* We allow interleaving only if there are no store-store and load-store
- dependencies in the loop. */
- for (i = 0; VEC_iterate (ddr_p, ddrs, i, ddr); i++)
- {
- if (vect_check_dependences (ddr))
- {
- check_interleaving = false;
- break;
- }
- }
-
for (i = 0; VEC_iterate (ddr_p, ddrs, i, ddr); i++)
- if (vect_analyze_data_ref_dependence (ddr, loop_vinfo, check_interleaving))
+ if (vect_analyze_data_ref_dependence (ddr, loop_vinfo))
return false;
return true;
@@ -1778,9 +1745,25 @@ vect_analyze_data_ref_access (struct data_reference *dr)
DR_INIT (STMT_VINFO_DATA_REF (
vinfo_for_stmt (next)))))
{
- /* For load use the same data-ref load. (We check in
- vect_check_dependences() that there are no two stores to the
- same location). */
+ if (!DR_IS_READ (data_ref))
+ {
+ if (vect_print_dump_info (REPORT_DETAILS))
+ fprintf (vect_dump, "Two store stmts share the same dr.");
+ return false;
+ }
+
+ /* Check that there is no load-store dependecies for this loads
+ to prevent a case of load-store-load to the same location. */
+ if (DR_GROUP_READ_WRITE_DEPENDENCE (vinfo_for_stmt (next))
+ || DR_GROUP_READ_WRITE_DEPENDENCE (vinfo_for_stmt (prev)))
+ {
+ if (vect_print_dump_info (REPORT_DETAILS))
+ fprintf (vect_dump,
+ "READ_WRITE dependence in interleaving.");
+ return false;
+ }
+
+ /* For load use the same data-ref load. */
DR_GROUP_SAME_DR_STMT (vinfo_for_stmt (next)) = prev;
prev = next;
diff --git a/gcc/tree-vectorizer.c b/gcc/tree-vectorizer.c
index 7fb98577951..ee137314dd4 100644
--- a/gcc/tree-vectorizer.c
+++ b/gcc/tree-vectorizer.c
@@ -1373,6 +1373,7 @@ new_stmt_vec_info (tree stmt, loop_vec_info loop_vinfo)
DR_GROUP_STORE_COUNT (res) = 0;
DR_GROUP_GAP (res) = 0;
DR_GROUP_SAME_DR_STMT (res) = NULL_TREE;
+ DR_GROUP_READ_WRITE_DEPENDENCE (res) = false;
return res;
}
diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h
index f3234032611..a13ee1e5c69 100644
--- a/gcc/tree-vectorizer.h
+++ b/gcc/tree-vectorizer.h
@@ -252,6 +252,9 @@ typedef struct _stmt_vec_info {
/* In case that two or more stmts share data-ref, this is the pointer to the
previously detected stmt with the same dr. */
tree same_dr_stmt;
+ /* For loads only, if there is a store with the same location, this field is
+ TRUE. */
+ bool read_write_dep;
} *stmt_vec_info;
/* Access Functions. */
@@ -273,6 +276,7 @@ typedef struct _stmt_vec_info {
#define STMT_VINFO_DR_GROUP_STORE_COUNT(S) (S)->store_count
#define STMT_VINFO_DR_GROUP_GAP(S) (S)->gap
#define STMT_VINFO_DR_GROUP_SAME_DR_STMT(S)(S)->same_dr_stmt
+#define STMT_VINFO_DR_GROUP_READ_WRITE_DEPENDENCE(S) (S)->read_write_dep
#define DR_GROUP_FIRST_DR(S) (S)->first_dr
#define DR_GROUP_NEXT_DR(S) (S)->next_dr
@@ -280,6 +284,7 @@ typedef struct _stmt_vec_info {
#define DR_GROUP_STORE_COUNT(S) (S)->store_count
#define DR_GROUP_GAP(S) (S)->gap
#define DR_GROUP_SAME_DR_STMT(S) (S)->same_dr_stmt
+#define DR_GROUP_READ_WRITE_DEPENDENCE(S) (S)->read_write_dep
#define STMT_VINFO_RELEVANT_P(S) ((S)->relevant != vect_unused_in_loop)