On Wed, May 3, 2017 at 9:54 AM, Richard Sandiford <richard.sandif...@linaro.org> wrote: > 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.
I'm a bit wary about trusting operand_equal_p over dependence analysis. So, did you (can you) add an assert that the new code computes same alignment in all cases where the old one did? > Tested on aarch64-linux-gnu and x86_64-linux-gnu. OK to install? Otherwise looks ok. Thanks, Richard. > Thanks, > Richard > > > gcc/ > 2017-05-03 Richard Sandiford <richard.sandif...@linaro.org> > > * 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. > > Index: gcc/tree-vect-data-refs.c > =================================================================== > --- gcc/tree-vect-data-refs.c 2017-04-18 19:52:35.060164268 +0100 > +++ gcc/tree-vect-data-refs.c 2017-05-03 08:48:30.536704993 +0100 > @@ -2042,20 +2042,12 @@ vect_enhance_data_refs_alignment (loop_v > 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; > @@ -2063,48 +2055,37 @@ vect_find_same_alignment_drs (struct dat > 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]; > + /* 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; > + } > > - if (dump_enabled_p ()) > - dump_printf_loc (MSG_NOTE, vect_location, > - "dependence distance = %d.\n", dist); > - > - /* 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"); > } > } > > @@ -2128,7 +2109,7 @@ vect_analyze_data_refs_alignment (loop_v > unsigned int i; > > FOR_EACH_VEC_ELT (ddrs, i, ddr) > - vect_find_same_alignment_drs (ddr, vinfo); > + vect_find_same_alignment_drs (ddr); > > vec<data_reference_p> datarefs = vinfo->datarefs; > struct data_reference *dr; > Index: gcc/testsuite/gcc.dg/vect/vect-103.c > =================================================================== > --- gcc/testsuite/gcc.dg/vect/vect-103.c 2015-06-02 23:53:38.000000000 > +0100 > +++ gcc/testsuite/gcc.dg/vect/vect-103.c 2017-05-03 08:48:30.536704993 > +0100 > @@ -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" } } */ >