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" } } */
>

Reply via email to