On Wed, May 3, 2017 at 11:07 AM, Richard Biener
<richard.guent...@gmail.com> wrote:
> 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?
At the moment operand_equal_p method looks more powerful than
dependence analysis, for example, it can handle the same memory
reference with pointer/array_ref forms like in PR65206.  However,
given dependence check is not expensive here, is it possible to build
the patch on top of it when it fails?

Thanks,
bin
>
>> 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