[killloop] Loop reversal
Sebastian Pop
sebastian.pop@cri.ensmp.fr
Mon Oct 24 09:31:00 GMT 2005
Sebastian Pop wrote:
> Zdenek Dvorak wrote:
> > The pass is currently disabled by default, since it exposes a bug in
> > data dependence analysis, thus causing misscompilations (in the test
> > loop-12:foo9, the loop gets reversed, even though this is not
> > correct).
>
> Sorry, I didn't get to fix it yet. I will propose a patch later.
>
Here is a fix for this one. The patch also fixes the computation of
distance vectors as described in http://gcc.gnu.org/PR23411
For example, in the following case,
loop_1
loop_2
A[5] = ...
end_loop_2
end_loop_1
the answer is the set of distance vectors: (0, 1) and (1, 0).
I would like to see this patch also included in mainline after some
more testing on SPEC, etc. I will post a patch for mainline later.
For now, I'm bootntesting this patch on killloop branch, amd64-linux.
Sebastian
* lambda-code.c (lambda_transform_legal_p): Use DDR_NUM_DIST_VECTS
for testing whether the data_dependence_relation contains distance
vectors. Iterate over all distance vectors of the ddr.
* lambda.h: Define a vec of lambda_vector pointers.
* tree-data-ref.c (dump_data_dependence_relation,
dump_data_dependence_direction): Iterate over all distance and
direction vectors of the ddr.
(initialize_data_dependence_relation): Initialize DDR_DIR_VECTS and
DDR_DIST_VECTS.
(build_classic_dist_vector, build_classic_dir_vector): Push a set
of distance/direction vectors instead of a single one.
* tree-data-ref.h (dir_vects, dist_vects): Replace dir/dist
lambda_vectors with a vec of lambda_vectors.
(DDR_DIR_VECT, DDR_DIST_VECT): Redefined as operations on vec.
(DDR_DIR_VECTS, DDR_DIST_VECTS, DDR_NUM_DIR_VECTS,
DDR_NUM_DIST_VECTS): New.
* tree-loop-linear.c (gather_interchange_stats): Test for the
existence of distance vectors only after having checked that there
is a dependence. Iterate over all distance vectors of the ddr.
(linear_transform_loops): Use dump_data_dependence_relation.
* tree-vect-analyze.c (vect_analyze_data_ref_dependence): Test for
distance vectors using DDR_NUM_DIST_VECTS. Iterate over all the
distance vectors of the ddr.
Index: lambda-code.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/lambda-code.c,v
retrieving revision 2.47.2.1
diff -d -u -p -r2.47.2.1 lambda-code.c
--- lambda-code.c 2 Sep 2005 16:42:18 -0000 2.47.2.1
+++ lambda-code.c 24 Oct 2005 08:44:57 -0000
@@ -2591,7 +2591,7 @@ lambda_transform_legal_p (lambda_trans_m
int nb_loops,
varray_type dependence_relations)
{
- unsigned int i;
+ unsigned int i, j;
lambda_vector distres;
struct data_dependence_relation *ddr;
@@ -2628,15 +2628,18 @@ lambda_transform_legal_p (lambda_trans_m
/* If the dependence could not be captured by a distance vector,
conservatively answer that the transform is not valid. */
- if (DDR_DIST_VECT (ddr) == NULL)
+ if (DDR_NUM_DIST_VECTS (ddr) == 0)
return false;
/* Compute trans.dist_vect */
- lambda_matrix_vector_mult (LTM_MATRIX (trans), nb_loops, nb_loops,
- DDR_DIST_VECT (ddr), distres);
+ for (j = 0; j < DDR_NUM_DIST_VECTS (ddr); j++)
+ {
+ lambda_matrix_vector_mult (LTM_MATRIX (trans), nb_loops, nb_loops,
+ DDR_DIST_VECT (ddr, j), distres);
- if (!lambda_vector_lexico_pos (distres, nb_loops))
- return false;
+ if (!lambda_vector_lexico_pos (distres, nb_loops))
+ return false;
+ }
}
return true;
}
Index: lambda.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/lambda.h,v
retrieving revision 2.13.2.1
diff -d -u -p -r2.13.2.1 lambda.h
--- lambda.h 2 Sep 2005 16:42:18 -0000 2.13.2.1
+++ lambda.h 24 Oct 2005 08:44:57 -0000
@@ -30,6 +30,9 @@ Software Foundation, 51 Franklin Street,
integers. */
typedef int *lambda_vector;
+DEF_VEC_P(lambda_vector);
+DEF_VEC_ALLOC_P(lambda_vector,heap);
+
/* An integer matrix. A matrix consists of m vectors of length n (IE
all vectors are the same length). */
typedef lambda_vector *lambda_matrix;
Index: tree-data-ref.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-data-ref.c,v
retrieving revision 2.35.2.4
diff -d -u -p -r2.35.2.4 tree-data-ref.c
--- tree-data-ref.c 5 Oct 2005 23:18:29 -0000 2.35.2.4
+++ tree-data-ref.c 24 Oct 2005 08:45:01 -0000
@@ -626,6 +626,7 @@ dump_data_dependence_relation (FILE *out
else if (DDR_ARE_DEPENDENT (ddr) == NULL_TREE)
{
unsigned int i;
+
for (i = 0; i < DDR_NUM_SUBSCRIPTS (ddr); i++)
{
fprintf (outf, " access_fn_A: ");
@@ -634,15 +635,19 @@ dump_data_dependence_relation (FILE *out
print_generic_stmt (outf, DR_ACCESS_FN (drb, i), 0);
dump_subscript (outf, DDR_SUBSCRIPT (ddr, i));
}
- if (DDR_DIST_VECT (ddr))
+
+ for (i = 0; i < DDR_NUM_DIST_VECTS (ddr); i++)
{
- fprintf (outf, " distance_vect: ");
- print_lambda_vector (outf, DDR_DIST_VECT (ddr), DDR_SIZE_VECT (ddr));
+ fprintf (outf, " distance_vector: ");
+ print_lambda_vector (outf, DDR_DIST_VECT (ddr, i),
+ DDR_SIZE_VECT (ddr));
}
- if (DDR_DIR_VECT (ddr))
+
+ for (i = 0; i < DDR_NUM_DIR_VECTS (ddr); i++)
{
- fprintf (outf, " direction_vect: ");
- print_lambda_vector (outf, DDR_DIR_VECT (ddr), DDR_SIZE_VECT (ddr));
+ fprintf (outf, " direction_vector: ");
+ print_lambda_vector (outf, DDR_DIR_VECT (ddr, i),
+ DDR_SIZE_VECT (ddr));
}
}
@@ -700,7 +705,7 @@ dump_data_dependence_direction (FILE *fi
void
dump_dist_dir_vectors (FILE *file, varray_type ddrs)
{
- unsigned int i;
+ unsigned int i, j;
for (i = 0; i < VARRAY_ACTIVE_SIZE (ddrs); i++)
{
@@ -710,12 +715,21 @@ dump_dist_dir_vectors (FILE *file, varra
if (DDR_ARE_DEPENDENT (ddr) == NULL_TREE
&& DDR_AFFINE_P (ddr))
{
- fprintf (file, "DISTANCE_V (");
- print_lambda_vector (file, DDR_DIST_VECT (ddr), DDR_SIZE_VECT (ddr));
- fprintf (file, ")\n");
- fprintf (file, "DIRECTION_V (");
- print_lambda_vector (file, DDR_DIR_VECT (ddr), DDR_SIZE_VECT (ddr));
- fprintf (file, ")\n");
+ for (j = 0; j < DDR_NUM_DIST_VECTS (ddr); j++)
+ {
+ fprintf (file, "DISTANCE_V (");
+ print_lambda_vector (file, DDR_DIST_VECT (ddr, j),
+ DDR_SIZE_VECT (ddr));
+ fprintf (file, ")\n");
+ }
+
+ for (j = 0; j < DDR_NUM_DIR_VECTS (ddr); j++)
+ {
+ fprintf (file, "DIRECTION_V (");
+ print_lambda_vector (file, DDR_DIR_VECT (ddr, j),
+ DDR_SIZE_VECT (ddr));
+ fprintf (file, ")\n");
+ }
}
}
fprintf (file, "\n\n");
@@ -2002,9 +2016,9 @@ initialize_data_dependence_relation (str
DDR_ARE_DEPENDENT (res) = NULL_TREE;
DDR_SUBSCRIPTS_VECTOR_INIT (res, DR_NUM_DIMENSIONS (a));
DDR_SIZE_VECT (res) = 0;
- DDR_DIST_VECT (res) = NULL;
- DDR_DIR_VECT (res) = NULL;
-
+ DDR_DIR_VECTS (res) = NULL;
+ DDR_DIST_VECTS (res) = NULL;
+
for (i = 0; i < DR_NUM_DIMENSIONS (a); i++)
{
struct subscript *subscript;
@@ -3070,7 +3084,9 @@ build_classic_dist_vector (struct data_d
{
unsigned i;
lambda_vector dist_v, init_v;
+ bool init_b = false;
+ DDR_SIZE_VECT (ddr) = nb_loops;
dist_v = lambda_vector_new (nb_loops);
init_v = lambda_vector_new (nb_loops);
lambda_vector_clear (dist_v, nb_loops);
@@ -3168,9 +3184,38 @@ build_classic_dist_vector (struct data_d
dist_v[loop_depth] = dist;
init_v[loop_depth] = 1;
+ init_b = true;
}
}
-
+
+ /* Save the distance vector if we initialized one. */
+ if (init_b)
+ {
+ lambda_vector save_v;
+
+ /* Verify a basic constraint: classic distance vectors should always
+ be lexicographically positive. */
+ if (!lambda_vector_lexico_pos (dist_v, DDR_SIZE_VECT (ddr)))
+ {
+ if (DDR_SIZE_VECT (ddr) == 1)
+ /* This one is simple to fix, and can be fixed.
+ Multidimensional arrays cannot be fixed that simply. */
+ lambda_vector_negate (dist_v, dist_v, DDR_SIZE_VECT (ddr));
+ else
+ /* This is not valid: we need the delta test for properly
+ fixing all this. */
+ return false;
+ }
+
+ save_v = lambda_vector_new (DDR_SIZE_VECT (ddr));
+ lambda_vector_copy (dist_v, save_v, DDR_SIZE_VECT (ddr));
+ VEC_safe_push (lambda_vector, heap, DDR_DIST_VECTS (ddr), save_v);
+
+ /* There is nothing more to do when there are no outer loops. */
+ if (DDR_SIZE_VECT (ddr) == 1)
+ goto classic_dist_done;
+ }
+
/* There is a distance of 1 on all the outer loops:
Example: there is a dependence of distance 1 on loop_1 for the array A.
@@ -3188,59 +3233,63 @@ build_classic_dist_vector (struct data_d
/* Get the common ancestor loop. */
lca = find_common_loop (loop_a, loop_b);
-
- lca_depth = lca->depth;
- lca_depth -= first_loop_depth;
+ lca_depth = lca->depth - first_loop_depth;
+
gcc_assert (lca_depth >= 0);
gcc_assert (lca_depth < nb_loops);
-
+
/* For each outer loop where init_v is not set, the accesses are
in dependence of distance 1 in the loop. */
- if (lca != loop_a
- && lca != loop_b
- && init_v[lca_depth] == 0)
- dist_v[lca_depth] = 1;
-
- lca = lca->outer;
-
- if (lca)
+ while (lca->depth != 0)
{
- lca_depth = lca->depth - first_loop_depth;
- while (lca->depth != 0)
- {
- /* If we're considering just a sub-nest, then don't record
- any information on the outer loops. */
- if (lca_depth < 0)
- break;
+ /* If we're considering just a sub-nest, then don't record
+ any information on the outer loops. */
+ if (lca_depth < 0)
+ break;
- gcc_assert (lca_depth < nb_loops);
+ gcc_assert (lca_depth < nb_loops);
- if (init_v[lca_depth] == 0)
- dist_v[lca_depth] = 1;
- lca = lca->outer;
- lca_depth = lca->depth - first_loop_depth;
-
+ /* If we haven't yet determined a distance for this outer
+ loop, push a new distance vector composed of the previous
+ distance, and a distance of 1 for this outer loop.
+ Example:
+
+ | loop_1
+ | loop_2
+ | A[10]
+ | endloop_2
+ | endloop_1
+
+ Saved vectors are of the form (dist_in_1, dist_in_2).
+ First, we save (0, 1), then we have to save (1, 0). */
+ if (init_v[lca_depth] == 0)
+ {
+ lambda_vector save_v = lambda_vector_new (DDR_SIZE_VECT (ddr));
+
+ lambda_vector_copy (dist_v, save_v, DDR_SIZE_VECT (ddr));
+ save_v[lca_depth] = 1;
+ VEC_safe_push (lambda_vector, heap, DDR_DIST_VECTS (ddr), save_v);
}
+
+ lca = lca->outer;
+ lca_depth = lca->depth - first_loop_depth;
}
}
-
- DDR_DIST_VECT (ddr) = dist_v;
- DDR_SIZE_VECT (ddr) = nb_loops;
- /* Verify a basic constraint: classic distance vectors should always
- be lexicographically positive. */
- if (!lambda_vector_lexico_pos (DDR_DIST_VECT (ddr),
- DDR_SIZE_VECT (ddr)))
+ classic_dist_done:;
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
{
- if (DDR_SIZE_VECT (ddr) == 1)
- /* This one is simple to fix, and can be fixed.
- Multidimensional arrays cannot be fixed that simply. */
- lambda_vector_negate (DDR_DIST_VECT (ddr), DDR_DIST_VECT (ddr),
- DDR_SIZE_VECT (ddr));
- else
- /* This is not valid: we need the delta test for properly
- fixing all this. */
- return false;
+ fprintf (dump_file, "(build_classic_dist_vector\n");
+
+ for (i = 0; i < DDR_NUM_DIST_VECTS (ddr); i++)
+ {
+ fprintf (dump_file, " dist_vector = (");
+ print_lambda_vector (dump_file, DDR_DIST_VECT (ddr, i),
+ DDR_SIZE_VECT (ddr));
+ fprintf (dump_file, " )\n");
+ }
+ fprintf (dump_file, ")\n");
}
return true;
@@ -3262,11 +3311,14 @@ build_classic_dir_vector (struct data_de
{
unsigned i;
lambda_vector dir_v, init_v;
+ bool init_b = false;
dir_v = lambda_vector_new (nb_loops);
init_v = lambda_vector_new (nb_loops);
lambda_vector_clear (dir_v, nb_loops);
lambda_vector_clear (init_v, nb_loops);
+
+ DDR_SIZE_VECT (ddr) = nb_loops;
if (DDR_ARE_DEPENDENT (ddr) != NULL_TREE)
return true;
@@ -3370,9 +3422,19 @@ build_classic_dir_vector (struct data_de
dir_v[loop_depth] = dir;
init_v[loop_depth] = 1;
+ init_b = true;
}
}
-
+
+ /* Save the direction vector if we initialized one. */
+ if (init_b)
+ {
+ lambda_vector save_v = lambda_vector_new (DDR_SIZE_VECT (ddr));
+
+ lambda_vector_copy (dir_v, save_v, DDR_SIZE_VECT (ddr));
+ VEC_safe_push (lambda_vector, heap, DDR_DIR_VECTS (ddr), save_v);
+ }
+
/* There is a distance of 1 on all the outer loops:
Example: there is a dependence of distance 1 on loop_1 for the array A.
@@ -3395,37 +3457,30 @@ build_classic_dir_vector (struct data_de
gcc_assert (lca_depth >= 0);
gcc_assert (lca_depth < nb_loops);
- /* For each outer loop where init_v is not set, the accesses are
- in dependence of distance 1 in the loop. */
- if (lca != loop_a
- && lca != loop_b
- && init_v[lca_depth] == 0)
- dir_v[lca_depth] = dir_positive;
-
- lca = lca->outer;
- if (lca)
+ while (lca->depth != 0)
{
- lca_depth = lca->depth - first_loop_depth;
- while (lca->depth != 0)
+ /* If we're considering just a sub-nest, then don't record
+ any information on the outer loops. */
+ if (lca_depth < 0)
+ break;
+
+ gcc_assert (lca_depth < nb_loops);
+
+ if (init_v[lca_depth] == 0)
{
- /* If we're considering just a sub-nest, then don't record
- any information on the outer loops. */
- if (lca_depth < 0)
- break;
+ lambda_vector save_v = lambda_vector_new (DDR_SIZE_VECT (ddr));
- gcc_assert (lca_depth < nb_loops);
+ lambda_vector_copy (dir_v, save_v, DDR_SIZE_VECT (ddr));
+ save_v[lca_depth] = dir_positive;
+ VEC_safe_push (lambda_vector, heap, DDR_DIR_VECTS (ddr), save_v);
+ }
- if (init_v[lca_depth] == 0)
- dir_v[lca_depth] = dir_positive;
- lca = lca->outer;
- lca_depth = lca->depth - first_loop_depth;
+ lca = lca->outer;
+ lca_depth = lca->depth - first_loop_depth;
- }
}
}
-
- DDR_DIR_VECT (ddr) = dir_v;
- DDR_SIZE_VECT (ddr) = nb_loops;
+
return true;
}
Index: tree-data-ref.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-data-ref.h,v
retrieving revision 2.10.2.2
diff -d -u -p -r2.10.2.2 tree-data-ref.h
--- tree-data-ref.h 5 Oct 2005 23:18:29 -0000 2.10.2.2
+++ tree-data-ref.h 24 Oct 2005 08:45:01 -0000
@@ -217,14 +217,15 @@ struct data_dependence_relation
the data_dependence_relation. */
varray_type subscripts;
- /* The size of the direction/distance vectors. */
+ /* The size of the direction/distance vectors: the depth of the
+ analyzed loop nest. */
int size_vect;
/* The classic direction vector. */
- lambda_vector dir_vect;
+ VEC(lambda_vector,heap) *dir_vects;
/* The classic distance vector. */
- lambda_vector dist_vect;
+ VEC(lambda_vector,heap) *dist_vects;
};
#define DDR_A(DDR) DDR->a
@@ -237,8 +238,17 @@ struct data_dependence_relation
#define DDR_SUBSCRIPT(DDR, I) VARRAY_GENERIC_PTR (DDR_SUBSCRIPTS (DDR), I)
#define DDR_NUM_SUBSCRIPTS(DDR) VARRAY_ACTIVE_SIZE (DDR_SUBSCRIPTS (DDR))
#define DDR_SIZE_VECT(DDR) DDR->size_vect
-#define DDR_DIR_VECT(DDR) DDR->dir_vect
-#define DDR_DIST_VECT(DDR) DDR->dist_vect
+
+#define DDR_DIST_VECTS(DDR) ((DDR)->dist_vects)
+#define DDR_DIR_VECTS(DDR) ((DDR)->dir_vects)
+#define DDR_NUM_DIST_VECTS(DDR) \
+ (VEC_length (lambda_vector, DDR_DIST_VECTS (DDR)))
+#define DDR_NUM_DIR_VECTS(DDR) \
+ (VEC_length (lambda_vector, DDR_DIR_VECTS (DDR)))
+#define DDR_DIR_VECT(DDR, I) \
+ VEC_index (lambda_vector, DDR_DIR_VECTS (DDR), I)
+#define DDR_DIST_VECT(DDR, I) \
+ VEC_index (lambda_vector, DDR_DIST_VECTS (DDR), I)
Index: tree-loop-linear.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-loop-linear.c,v
retrieving revision 2.17
diff -d -u -p -r2.17 tree-loop-linear.c
--- tree-loop-linear.c 25 Jul 2005 12:04:50 -0000 2.17
+++ tree-loop-linear.c 24 Oct 2005 08:45:01 -0000
@@ -98,7 +98,7 @@ gather_interchange_stats (varray_type de
unsigned int *nb_deps_not_carried_by_loop,
unsigned int *access_strides)
{
- unsigned int i;
+ unsigned int i, j;
*dependence_steps = 0;
*nb_deps_not_carried_by_loop = 0;
@@ -106,7 +106,6 @@ gather_interchange_stats (varray_type de
for (i = 0; i < VARRAY_ACTIVE_SIZE (dependence_relations); i++)
{
- int dist;
struct data_dependence_relation *ddr =
(struct data_dependence_relation *)
VARRAY_GENERIC_PTR (dependence_relations, i);
@@ -114,21 +113,24 @@ gather_interchange_stats (varray_type de
/* If we don't know anything about this dependence, or the distance
vector is NULL, or there is no dependence, then there is no reuse of
data. */
-
- if (DDR_DIST_VECT (ddr) == NULL
- || DDR_ARE_DEPENDENT (ddr) == chrec_dont_know
- || DDR_ARE_DEPENDENT (ddr) == chrec_known)
+ if (DDR_ARE_DEPENDENT (ddr) == chrec_dont_know
+ || DDR_ARE_DEPENDENT (ddr) == chrec_known
+ || DDR_NUM_DIST_VECTS (ddr) == 0)
continue;
-
-
- dist = DDR_DIST_VECT (ddr)[loop->depth - first_loop->depth];
- if (dist == 0)
- (*nb_deps_not_carried_by_loop) += 1;
- else if (dist < 0)
- (*dependence_steps) += -dist;
- else
- (*dependence_steps) += dist;
+ for (j = 0; j < DDR_NUM_DIST_VECTS (ddr); j++)
+ {
+ int dist = DDR_DIST_VECT (ddr, j)[loop->depth - first_loop->depth];
+
+ if (dist == 0)
+ (*nb_deps_not_carried_by_loop) += 1;
+
+ else if (dist < 0)
+ (*dependence_steps) += -dist;
+
+ else
+ (*dependence_steps) += dist;
+ }
}
/* Compute the access strides. */
@@ -307,16 +309,7 @@ linear_transform_loops (struct loops *lo
VARRAY_GENERIC_PTR (dependence_relations, j);
if (DDR_ARE_DEPENDENT (ddr) == NULL_TREE)
- {
- fprintf (dump_file, "DISTANCE_V (");
- print_lambda_vector (dump_file, DDR_DIST_VECT (ddr),
- DDR_SIZE_VECT (ddr));
- fprintf (dump_file, ")\n");
- fprintf (dump_file, "DIRECTION_V (");
- print_lambda_vector (dump_file, DDR_DIR_VECT (ddr),
- DDR_SIZE_VECT (ddr));
- fprintf (dump_file, ")\n");
- }
+ dump_data_dependence_relation (dump_file, ddr);
}
fprintf (dump_file, "\n\n");
}
Index: tree-vect-analyze.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-vect-analyze.c,v
retrieving revision 2.33.2.2
diff -d -u -p -r2.33.2.2 tree-vect-analyze.c
--- tree-vect-analyze.c 5 Oct 2005 23:18:30 -0000 2.33.2.2
+++ tree-vect-analyze.c 24 Oct 2005 08:45:01 -0000
@@ -570,9 +570,9 @@ static bool
vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr,
loop_vec_info loop_vinfo)
{
+ unsigned int i;
struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
int vectorization_factor = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
- int dist = 0;
unsigned int loop_depth = 0;
struct loop *loop_nest = loop;
struct data_reference *dra = DDR_A (ddr);
@@ -596,7 +596,7 @@ vect_analyze_data_ref_dependence (struct
return true;
}
- if (!DDR_DIST_VECT (ddr))
+ if (DDR_NUM_DIST_VECTS (ddr) == 0)
{
if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
{
@@ -614,48 +614,54 @@ vect_analyze_data_ref_dependence (struct
loop_nest = loop_nest->outer;
loop_depth++;
}
-
- dist = DDR_DIST_VECT (ddr)[loop_depth];
- if (vect_print_dump_info (REPORT_DR_DETAILS))
- fprintf (vect_dump, "dependence distance = %d.",dist);
- /* Same loop iteration. */
- if (dist % vectorization_factor == 0)
+ for (i = 0; i < DDR_NUM_DIST_VECTS (ddr); i++)
{
- /* 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))
- fprintf (vect_dump, "accesses have the same alignment.");
- if (vect_print_dump_info (REPORT_DR_DETAILS))
- {
- fprintf (vect_dump, "dependence distance modulo vf == 0 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 false;
- }
+ int dist = DDR_DIST_VECT (ddr, i)[loop_depth];
- if (abs (dist) >= vectorization_factor)
- {
- /* Dependence distance does not create dependence, as far as vectorization
- is concerned, in this case. */
if (vect_print_dump_info (REPORT_DR_DETAILS))
- fprintf (vect_dump, "dependence distance >= VF.");
- return false;
- }
-
- if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
- {
- fprintf (vect_dump,
- "not vectorized: possible dependence between data-refs ");
- print_generic_expr (vect_dump, DR_REF (dra), TDF_SLIM);
- fprintf (vect_dump, " and ");
- print_generic_expr (vect_dump, DR_REF (drb), TDF_SLIM);
+ fprintf (vect_dump, "dependence distance = %d.", dist);
+
+ /* Same loop iteration. */
+ if (dist % vectorization_factor == 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))
+ fprintf (vect_dump, "accesses have the same alignment.");
+ if (vect_print_dump_info (REPORT_DR_DETAILS))
+ {
+ fprintf (vect_dump, "dependence distance modulo vf == 0 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);
+ }
+ continue;
+ }
+
+ if (abs (dist) >= vectorization_factor)
+ {
+ /* Dependence distance does not create dependence, as far as vectorization
+ is concerned, in this case. */
+ if (vect_print_dump_info (REPORT_DR_DETAILS))
+ fprintf (vect_dump, "dependence distance >= VF.");
+ continue;
+ }
+
+ if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
+ {
+ fprintf (vect_dump,
+ "not vectorized: possible dependence between data-refs ");
+ 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;
}
-
- return true;
+
+ return false;
}
More information about the Gcc-patches
mailing list