This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH][RFC] Introduce MEM_REF
Hi,
On Thu, Apr 01, 2010 at 02:52:50PM +0200, Richard Guenther wrote:
> On Thu, 1 Apr 2010, Martin Jambor wrote:
>
> > Hi,
> >
> > On Wed, Mar 10, 2010 at 05:16:30PM +0100, Richard Guenther wrote:
> > >
> > > To address 1) and 2) the MEM_REF tree has an explicit type that is
> > > used for TBAA. It happens to be that this needs to be a pointer
> > > type (because of the TYPE_REF_CAN_ALIAS_ALL flag). Thus the
> > > MEM_REF operation implicitly contains a pointer-conversion.
> > > MEM_REF <T*, p> is *(T*)p. Conveniently we encode this pointer-type
> > > using a tree constant operand
> >
> > I fail to understand the above. An explicit pointer type - which I
> > understand is different from the type of the expr and which is
> > necessary because of a pointer type flag - encoded as an integer
> > offset? I'm afraid this is another of my stupid questions but could
> > you please rephrase that?
>
> Sure.
>
> MEM_REF should explicitly encode type-based aliasing information of
> the access. Thus, in principle storing the alias-set number is
> enough. Now as we have no means to merge alias-set numbers from
> different TUs with LTO we have to use a type instead (we can
> merge types and types do have alias-sets associated). When
> we choose the kind of type we have to choose one that we can
> get the alias-set from of a pointer dereference. As we do have
> flags on pointer types that affect the alias-set of a dereference
> operation it has to be a pointer type.
>
> So, type-based alias information of a MEM_REF access is explicitly
> represented as a pointer type, T *, the alias-set is that returned
> by get_deref_alias_set (T *).
>
> Now, it's inconvenient to store a type in a tree operand (you
> get funny ICEs all over the place). So we go one step further
> and introduce a constant offset operand - which as a pointer
> offset is of the same precision as the pointer. Now, very
> conveniently we can also encode the pointer type T * here, by
> just making the integer constant use that type.
>
> What does that mean in practice? It means that we can for example
> express
>
> float *p;
> int i;
> memcpy (&i, p, 4);
>
> as (after re-writing i into SSA form)
>
> i_2 = MEM_REF <p_1, (char *) 0>;
>
> with TREE_TYPE (MEM_REF) == int. Thus, we read an int from *(p + 0)
> using alias-set zero (that of *(char *)). Without MEM_REF we
> have to use something like
>
> int *q {ref-all};
> q_3 = (int * {ref-all})p_1;
> i_2 = *q_3;
>
> where using of alias-set zero is encoded in the pointer type of q_3.
> This makes the conversion in q_3 = (int * {ref-all})p_1; not useless
> and thus we cannot copy-propagate the value-equivalent p_1 into
> the uses of q_3 (and thus fail to detect pointer equivalences in
> many cases).
>
> Hope this clarifies things.
It certainly does, thanks!
Martin