From 748bbe72024ab2840c6b8ab60cef124c4c83fbeb Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Wed, 31 May 2017 12:05:10 +0000 Subject: [PATCH] Alternative check for vector refs with same alignment vect_find_same_alignment_drs uses the ddr dependence distance to tell whether two references have the same alignment. Although that's safe with the current code, there's no particular reason why a dependence distance of 0 should mean that the accesses start on the same byte. E.g. a reference to a full complex value could in principle depend on a reference to the imaginary component. A later patch adds support for this kind of dependence. On the other side, checking modulo vf is pessimistic when the step divided by the element size is a factor of 2. This patch instead looks for cases in which the drs have the same base, offset and step, and for which the difference in their constant initial values is a multiple of the alignment. 2017-05-03 Richard Sandiford gcc/ * tree-vect-data-refs.c (vect_find_same_alignment_drs): Remove loop_vinfo argument and use of dependence distance vectors. Check instead whether the two references differ only in their initial value and assume that they have the same alignment if the difference is a multiple of the vector alignment. (vect_analyze_data_refs_alignment): Update call accordingly. gcc/testsuite/ * gcc.dg/vect/vect-103.c: Update wording of dump message. From-SVN: r248730 --- gcc/ChangeLog | 9 ++++ gcc/testsuite/ChangeLog | 4 ++ gcc/testsuite/gcc.dg/vect/vect-103.c | 2 +- gcc/tree-vect-data-refs.c | 77 +++++++++++----------------- 4 files changed, 43 insertions(+), 49 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4cca99661b3..c6266526f48 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2017-05-31 Richard Sandiford + + * tree-vect-data-refs.c (vect_find_same_alignment_drs): Remove + loop_vinfo argument and use of dependence distance vectors. + Check instead whether the two references differ only in their + initial value and assume that they have the same alignment if the + difference is a multiple of the vector alignment. + (vect_analyze_data_refs_alignment): Update call accordingly. + 2017-05-31 Martin Liska PR target/79155 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9fec6120618..cbad5692d38 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2017-05-31 Richard Sandiford + + * gcc.dg/vect/vect-103.c: Update wording of dump message. + 2017-05-31 Bin Cheng * gcc.dg/vect/pr80815-3.c: New test. diff --git a/gcc/testsuite/gcc.dg/vect/vect-103.c b/gcc/testsuite/gcc.dg/vect/vect-103.c index fb2a8578c5d..e0fd1b61e02 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-103.c +++ b/gcc/testsuite/gcc.dg/vect/vect-103.c @@ -55,5 +55,5 @@ int main (void) } /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ -/* { dg-final { scan-tree-dump-times "dependence distance modulo vf == 0" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "accesses have the same alignment" 1 "vect" } } */ diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c index 5103ba1e6f2..e8e2658e218 100644 --- a/gcc/tree-vect-data-refs.c +++ b/gcc/tree-vect-data-refs.c @@ -2140,20 +2140,12 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo) vectorization factor. */ static void -vect_find_same_alignment_drs (struct data_dependence_relation *ddr, - loop_vec_info loop_vinfo) +vect_find_same_alignment_drs (struct data_dependence_relation *ddr) { - unsigned int i; - struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo); - int vectorization_factor = LOOP_VINFO_VECT_FACTOR (loop_vinfo); struct data_reference *dra = DDR_A (ddr); struct data_reference *drb = DDR_B (ddr); stmt_vec_info stmtinfo_a = vinfo_for_stmt (DR_STMT (dra)); stmt_vec_info stmtinfo_b = vinfo_for_stmt (DR_STMT (drb)); - int dra_size = GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (DR_REF (dra)))); - int drb_size = GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (DR_REF (drb)))); - lambda_vector dist_v; - unsigned int loop_depth; if (DDR_ARE_DEPENDENT (ddr) == chrec_known) return; @@ -2161,48 +2153,37 @@ vect_find_same_alignment_drs (struct data_dependence_relation *ddr, if (dra == drb) return; - if (DDR_ARE_DEPENDENT (ddr) == chrec_dont_know) - return; - - /* Loop-based vectorization and known data dependence. */ - if (DDR_NUM_DIST_VECTS (ddr) == 0) - return; - - /* Data-dependence analysis reports a distance vector of zero - for data-references that overlap only in the first iteration - but have different sign step (see PR45764). - So as a sanity check require equal DR_STEP. */ - if (!operand_equal_p (DR_STEP (dra), DR_STEP (drb), 0)) + if (!operand_equal_p (DR_BASE_OBJECT (dra), DR_BASE_OBJECT (drb), + OEP_ADDRESS_OF) + || !operand_equal_p (DR_OFFSET (dra), DR_OFFSET (drb), 0) + || !operand_equal_p (DR_STEP (dra), DR_STEP (drb), 0)) return; - loop_depth = index_in_loop_nest (loop->num, DDR_LOOP_NEST (ddr)); - FOR_EACH_VEC_ELT (DDR_DIST_VECTS (ddr), i, dist_v) + /* Two references with distance zero have the same alignment. */ + offset_int diff = (wi::to_offset (DR_INIT (dra)) + - wi::to_offset (DR_INIT (drb))); + if (diff != 0) { - int dist = dist_v[loop_depth]; - - if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, - "dependence distance = %d.\n", dist); + /* Get the wider of the two alignments. */ + unsigned int align_a = TYPE_ALIGN_UNIT (STMT_VINFO_VECTYPE (stmtinfo_a)); + unsigned int align_b = TYPE_ALIGN_UNIT (STMT_VINFO_VECTYPE (stmtinfo_b)); + unsigned int max_align = MAX (align_a, align_b); + + /* Require the gap to be a multiple of the larger vector alignment. */ + if (!wi::multiple_of_p (diff, max_align, SIGNED)) + return; + } - /* Same loop iteration. */ - if (dist == 0 - || (dist % vectorization_factor == 0 && dra_size == drb_size)) - { - /* Two references with distance zero have the same alignment. */ - STMT_VINFO_SAME_ALIGN_REFS (stmtinfo_a).safe_push (drb); - STMT_VINFO_SAME_ALIGN_REFS (stmtinfo_b).safe_push (dra); - if (dump_enabled_p ()) - { - dump_printf_loc (MSG_NOTE, vect_location, - "accesses have the same alignment.\n"); - dump_printf (MSG_NOTE, - "dependence distance modulo vf == 0 between "); - dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (dra)); - dump_printf (MSG_NOTE, " and "); - dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (drb)); - dump_printf (MSG_NOTE, "\n"); - } - } + STMT_VINFO_SAME_ALIGN_REFS (stmtinfo_a).safe_push (drb); + STMT_VINFO_SAME_ALIGN_REFS (stmtinfo_b).safe_push (dra); + if (dump_enabled_p ()) + { + dump_printf_loc (MSG_NOTE, vect_location, + "accesses have the same alignment: "); + dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (dra)); + dump_printf (MSG_NOTE, " and "); + dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (drb)); + dump_printf (MSG_NOTE, "\n"); } } @@ -2226,7 +2207,7 @@ vect_analyze_data_refs_alignment (loop_vec_info vinfo) unsigned int i; FOR_EACH_VEC_ELT (ddrs, i, ddr) - vect_find_same_alignment_drs (ddr, vinfo); + vect_find_same_alignment_drs (ddr); vec datarefs = vinfo->datarefs; struct data_reference *dr; -- 2.30.2