tree-vectorizer.h (struct _stmt_vec_info): Add new field read_write_dep and macros for its access.
* 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. From-SVN: r121026
This commit is contained in:
parent
52b213f385
commit
6004caaf4d
@ -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>
|
||||
|
||||
|
@ -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
|
||||
|
77
gcc/testsuite/gcc.dg/vect/vect-strided-same-dr.c
Normal file
77
gcc/testsuite/gcc.dg/vect/vect-strided-same-dr.c
Normal file
@ -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" } } */
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user