https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64715

--- Comment #19 from Richard Biener <rguenth at gcc dot gnu.org> ---
(In reply to Jakub Jelinek from comment #14)
> Or, as discussed on IRC we can consider MEM_REFs where first operand isn't
> just
> SSA_NAME or ADDR_EXPR of a decl, but allow also ADDR_EXPR of
> handled_component_p (with base being a decl or MEM_REF with SSA_NAME first
> operand).
> 
> Or add a new tree code, like OFFSETTED_ADDR_EXPR which would be like
> ADDR_EXPR, but with integer offset address to the ADDR_EXPR.

Thinking about this some more we already have the ability to combine

 _2 = &a.b[i].c;
 _3 = _2 + 8;

by using handled-components:

  &ARRAY_REF <VIEW_CONVERT_EXPR <(__typeof__ (a.b[i].c)[])&a.b[i].c>, 8 /
__sizeof__(a.b[i].c)>

that is, we could attack this by implementing pointer arithmetic as represented
by the frontend in the way it is defined by the C standard (in terms of array
indexing).

  ptr + idx

would be lowered as

  &ARRAY_REF <VIEW_CONVERT_EXPR <(__typeof__ (*ptr) []) *ptr>, idx>

thereby also avoiding the need to apply promotion of idx to sizetype to
avoid the possible overflow of the multiplication by sizeof (*ptr).

Of course it would be nice to avoid the "awkward" VIEW_CONVERT_EXPR here,
but adding a new kind of handled-component isn't exactly non-intrusive either.

Btw, there is an alternative to the array-ref/view-convert-expr form that
is less restrictive on the actual 'idx'.  We could simply use

  COMPONENT_REF <*ptr, <NULL field-decl>, explicit-offset>

though the fact that COMPONENT_REFs have alias analysis effects and that
the lowered offset is measured in DECL_OFFSET_ALIGN units of the field-decl
makes that non-trivial to support as well.

That said, the alternative is to add a new handled-component, say,
OFFSET_VIEW_CONVERT_EXPR <type, base, offset>, that would have the
same effect as doing

  _ptr = &base + offset;
  MEM [_ptr, offset];

thus offset carries type-based alias information and 'type' carries
alignment info.  Type-based alias analysis would stop at
OFFSET_VIEW_CONVERT_EXPR as it stops now at VIEW_CONVERT_EXPRs.

Now we could also simply change VIEW_CONVERT_EXPR to take an (optional?)
offset parameter.

I like all of the above choices more than special-casing an address-only
variant for offsets.  All of the above enable us to avoid making
variable-indexed indirect references addressable like we have to do now
because of the restrictions of MEM_REF bases / offsets.  The ARRAY_REF
variant allows to handle non-constant pointer offsets as well while
the offsetted VIEW_CONVERT_EXPR would handle only constant offsets
(but allow non-"element"-size increments and arbitrary effective alias
sets on the memory reference).

We should already handle the ARRAY_REF <VIEW_CONVERT_EXPR <...> ...> form
correctly today, we just don't create it.

Reply via email to