From 96b70ccb09a2af84cfce4c22e84028cefe42b286 Mon Sep 17 00:00:00 2001 From: Sebastian Pop Date: Mon, 24 Oct 2005 13:01:57 +0000 Subject: * 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. git-svn-id: https://gcc.gnu.org/svn/gcc/branches/killloop-branch@105849 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog.killloop | 26 ++++++ gcc/lambda-code.c | 15 ++-- gcc/lambda.h | 3 + gcc/tree-data-ref.c | 221 ++++++++++++++++++++++++++++++------------------ gcc/tree-data-ref.h | 20 +++-- gcc/tree-loop-linear.c | 43 ++++------ gcc/tree-vect-analyze.c | 84 +++++++++--------- 7 files changed, 254 insertions(+), 158 deletions(-) diff --git a/gcc/ChangeLog.killloop b/gcc/ChangeLog.killloop index 416ceb5b543..fdea80f5066 100644 --- a/gcc/ChangeLog.killloop +++ b/gcc/ChangeLog.killloop @@ -1,3 +1,29 @@ +2005-10-24 Sebastian Pop + + * 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. + 2005-10-05 Zdenek Dvorak Merge from mainline (killloop-merge-20051005). diff --git a/gcc/lambda-code.c b/gcc/lambda-code.c index cf995a3f9f4..2d6db22cced 100644 --- a/gcc/lambda-code.c +++ b/gcc/lambda-code.c @@ -2591,7 +2591,7 @@ lambda_transform_legal_p (lambda_trans_matrix trans, 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_matrix trans, /* 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; } diff --git a/gcc/lambda.h b/gcc/lambda.h index 9855b6f73ed..418cb041ca9 100644 --- a/gcc/lambda.h +++ b/gcc/lambda.h @@ -30,6 +30,9 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 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; diff --git a/gcc/tree-data-ref.c b/gcc/tree-data-ref.c index 932715cca13..79285dd7abb 100644 --- a/gcc/tree-data-ref.c +++ b/gcc/tree-data-ref.c @@ -626,6 +626,7 @@ dump_data_dependence_relation (FILE *outf, 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 *outf, 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 *file, 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, varray_type ddrs) 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 (struct data_reference *a, 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_dependence_relation *ddr, { 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_dependence_relation *ddr, 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_dependence_relation *ddr, /* 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_dependence_relation *ddr, { 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_dependence_relation *ddr, 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_dependence_relation *ddr, 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; } diff --git a/gcc/tree-data-ref.h b/gcc/tree-data-ref.h index 0677db5251c..5b90e2d5544 100644 --- a/gcc/tree-data-ref.h +++ b/gcc/tree-data-ref.h @@ -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) diff --git a/gcc/tree-loop-linear.c b/gcc/tree-loop-linear.c index 0b13e2b5524..da790dc842f 100644 --- a/gcc/tree-loop-linear.c +++ b/gcc/tree-loop-linear.c @@ -98,7 +98,7 @@ gather_interchange_stats (varray_type dependence_relations, 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 dependence_relations, 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 dependence_relations, /* 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 *loops) 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"); } diff --git a/gcc/tree-vect-analyze.c b/gcc/tree-vect-analyze.c index a9681bd0c18..ab749fba34a 100644 --- a/gcc/tree-vect-analyze.c +++ b/gcc/tree-vect-analyze.c @@ -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 data_dependence_relation *ddr, 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 data_dependence_relation *ddr, 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; } -- cgit v1.2.3