On Wed, Mar 16, 2016 at 5:17 PM, Bin.Cheng <amker.ch...@gmail.com> wrote:
> On Wed, Mar 16, 2016 at 12:20 PM, Richard Biener
> <richard.guent...@gmail.com> wrote:
>>
>> On Wed, Mar 16, 2016 at 10:59 AM, Bin Cheng <bin.ch...@arm.com> wrote:
>> > Hi,
>> > ......
>> > Bootstrap and test on x86_64 and AArch64.  Is it OK, not sure if it's GCC 
>> > 7?
>>
>> Hmm.
> Hi,
> Thanks for reviewing.
>>
>> +  equal_p = true;
>> +  if (e1->base_address && e2->base_address)
>> +    equal_p &= operand_equal_p (e1->base_address, e2->base_address, 0);
>> +  if (e1->offset && e2->offset)
>> +    equal_p &= operand_equal_p (e1->offset, e2->offset, 0);
>>
>> surely better to return false early.
>>
>> I think we don't want this in tree-data-refs.h also because of ...
>>
>> @@ -615,15 +619,29 @@
>> hash_memrefs_baserefs_and_store_DRs_read_written_info
>> (data_reference_p a)
>>    data_reference_p *master_dr, *base_master_dr;and REALPART) before 
>> creating the DR (or adjust the equality function
> and hashing
>>    tree ref = DR_REF (a);
>>    tree base_ref = DR_BASE_OBJECT (a);
>> +  innermost_loop_behavior *innermost = &DR_INNERMOST (a);
>>    tree ca = bb_predicate (gimple_bb (DR_STMT (a)));
>>    bool exist1, exist2;
>>
>> -  while (TREE_CODE (ref) == COMPONENT_REF
>> -        || TREE_CODE (ref) == IMAGPART_EXPR
>> -        || TREE_CODE (ref) == REALPART_EXPR)
>> -    ref = TREE_OPERAND (ref, 0);
>> +  /* If reference in DR has innermost loop behavior and it is not
>> +     a compound memory reference, we store it to innermost_DR_map,
>> +     otherwise to ref_DR_map.  */
>> +  if (TREE_CODE (ref) == COMPONENT_REF
>> +      || TREE_CODE (ref) == IMAGPART_EXPR
>> +      || TREE_CODE (ref) == REALPART_EXPR
>> +      || !(DR_BASE_ADDRESS (a) || DR_OFFSET (a)
>> +          || DR_INIT (a) || DR_STEP (a) || DR_ALIGNED_TO (a)))
>> +    {
>> +      while (TREE_CODE (ref) == COMPONENT_REF
>> +            || TREE_CODE (ref) == IMAGPART_EXPR
>> +            || TREE_CODE (ref) == REALPART_EXPR)
>> +       ref = TREE_OPERAND (ref, 0);
>> +
>> +      master_dr = &ref_DR_map->get_or_insert (ref, &exist1);
>> +    }
>> +  else
>> +    master_dr = &innermost_DR_map->get_or_insert (innermost, &exist1);
>>
>> we don't want an extra hashmap but replace ref_DR_map entirely.  So we'd 
>> need to
>> strip outermost non-variant handled-components (COMPONENT_REF, IMAGPART
>> and REALPART) before creating the DR (or adjust the equality function
>> and hashing
>> to disregard them which means subtracting their offset from DR_INIT.
> I am not sure if I understand correctly.  But for component reference,
> it is the base object that we want to record/track.  For example,
>
>   for (i = 0; i < N; i++) {
>     m = *data++;
>
>     m1 = p1->x - m;
>     m2 = p2->x + m;
>
>     p3->y = (m1 >= m2) ? p1->y : p2->y;
>
>     p1++;
>     p2++;
>     p3++;
>   }
> We want to infer that reads of p1/p2 in condition statement won't trap
> because there are unconditional reads of the structures, though the
> unconditional reads are actual of other sub-objects.  Here it is the
> invariant part of address that we want to track.

Well, the variant parts - we want to strip invariant parts as far as we can
(offsetof (x) and offsetof (y))

> Also illustrated by this example, we can't rely on data-ref analyzer
> here.  Because in gathering/scattering cases, the address could be not
> affine at all.

Sure, but that's a different issue.

>>
>> To adjust the references we collect you'd maybe could use a callback
>> to get_references_in_stmt
>> to adjust them.
>>
>> OTOH post-processing the DRs in if_convertible_loop_p_1 can be as simple as
> Is this a part of the method you suggested above, or is it an
> alternative one?  If it's the latter, then I have below questions
> embedded.

It is an alternative to adding a hook to get_references_in_stmt and
probably "easier".

>>
>> Index: tree-if-conv.c
>> ===================================================================
>> --- tree-if-conv.c      (revision 234215)
>> +++ tree-if-conv.c      (working copy)
>> @@ -1235,6 +1220,38 @@ if_convertible_loop_p_1 (struct loop *lo
>>
>>    for (i = 0; refs->iterate (i, &dr); i++)
>>      {
>> +      tree *refp = &DR_REF (dr);
>> +      while ((TREE_CODE (*refp) == COMPONENT_REF
>> +             && TREE_OPERAND (*refp, 2) == NULL_TREE)
>> +            || TREE_CODE (*refp) == IMAGPART_EXPR
>> +            || TREE_CODE (*refp) == REALPART_EXPR)
>> +       refp = &TREE_OPERAND (*refp, 0);
>> +      if (refp != &DR_REF (dr))
>> +       {
>> +         tree saved_base = *refp;
>> +         *refp = integer_zero_node;
>> +
>> +         if (DR_INIT (dr))
>> +           {
>> +             tree poffset;
>> +             int punsignedp, preversep, pvolatilep;
>> +             machine_mode pmode;
>> +             HOST_WIDE_INT pbitsize, pbitpos;
>> +             get_inner_reference (DR_REF (dr), &pbitsize, &pbitpos, 
>> &poffset,
>> +                                  &pmode, &punsignedp, &preversep, 
>> &pvolatilep,
>> +                                  false);
>> +             gcc_assert (poffset == NULL_TREE);
>> +
>> +             DR_INIT (dr)
>> +               = wide_int_to_tree (ssizetype,
>> +                                   wi::sub (DR_INIT (dr),
>> +                                            pbitpos / BITS_PER_UNIT));
>> +           }
>> +
>> +         *refp = saved_base;
>> +         DR_REF (dr) = *refp;
>> +       }
> Looks to me the code is trying to resolve difference between two (or
> more) component references, which is DR_INIT in the code.  But DR_INIT
> is not the only thing needs to be handled.  For a structure containing
> two sub-arrays, DR_OFFSET may be different too.

Yes, but we can't say that if

  a->a[i]

doesn't trap that then

  a->b[i]

doesn't trap either.  We can only "strip" outermost
non-variable-offset components.

But maybe I'm missing what example you are thinking of.

> Actually I did try to replace ref_DR_map.  For memory reference
> doesn't have innermost affine behavior, we need to modify DR fields by
> populating it with artificial data.  This results in some kind of
> over-designed code.  IMHO, modifying some DR structures outside of
> data-ref analyzer isn't that good.  After comparing the two methods, I
> think may be this one is better, of course with the cost of two
> different maps.

IMHO the code is already somewhat awful in using data-ref analysis at all
(for what it does it certainly doesn't need it).  Note that in the case
data-ref analysis cannot analyze innermost behavior we're good as well
with my proposed code - we simply leave DR_INIT NULL (but still strip
outermost components).

Richard.

> I might be misunderstanding your idea, so please correct if I was wrong.
>
> Thanks,
> bin
>> +
>>        dr->aux = XNEW (struct ifc_dr);
>>        DR_BASE_W_UNCONDITIONALLY (dr) = false;
>>        DR_RW_UNCONDITIONALLY (dr) = false;
>>
>>
>> Can you add a testcase for the vectorization?
>>
>> Richard.
>>

Reply via email to