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

--- Comment #15 from Richard Sandiford <rsandifo at gcc dot gnu.org> ---
(In reply to Michael Matz from comment #14)
> (In reply to Richard Sandiford from comment #13)
> > (In reply to Michael Matz from comment #12)
> > > That's why I struggle a bit, I lack the bigger picture, how LRA is
> > > envisioned to deal with these situations given how targets are supposed 
> > > (and
> > > still documented)
> > > to use the strict/nonstrict distinction of testing for legal operands.
> > The generic address decomposition logic should realise that, in:
> > 
> >   (plus (zero_extend R1) R2)
> > 
> > R2 must be the base and R1 must be the index.  Therefore, R2 must be
> > constrained to BASE_REG_CLASS (or its variants) and R1 must be constrained
> > to INDEX_REG_CLASS (or its variants).
> 
> Yes, I considered adding this handling of (zero_extend Rx) to LRA.  I'm
> confident
> it would fix this instance of the problem, if done correctly (it essentially
> already has code to deal with shortening subregs, which is somewhat similar
> in structure).
It should already be present, via the decompose_*_address mechanism.

FWIW, aarch64 also supports (mem (plus (zero_extend R1) R2)) and works with
LRA, so I don't think there's a fundamental limitation.

> But then I asked myself "what if another target has still
> different representations of address?": Should LRA be continuously extended
> to deal with these and those representations?  Sure, for optimality that
> might
> be necessary.  But in the grand scheme of things, the target should have the
> opportunity, without any changes to LRA code, to be made completely working
> with whatever representations it's using internally.  It needs to have a way
> to say "this address, if written with the assigned hardregs, will be
> invalid, do something".  Alternatively (and better) it needs to have a way
> to say "this
> address, while structurally valid, will need these regsets in those reg
> operands", generally (i.e. it should be possible to have targets with e.g. 4
> register operands, or such).
> 
> If that's not possible then the design of the LRA-target interface is not
> yet complete IMHO.
Yeah, the current approach is the latter one (which I agree is better). 
 legitimate_address_p answers the question “is this address structurally
valid?” while BASE_REG_CLASS and INDEX_REG_CLASS specify the regsets that
should be used to reload registers in structurally valid addresses.

Like you say, in practice it has to be done by using regsets, since the RA
needs to know “what do I need to do to make this valid?”.  It shouldn't have to
use trial and error (trying particular hard registers to see if they're valid).

> > (FWIW, I think it's correct that LRA never passes strict_p==true.
> > The strict_p distinction should go away once reload does.)
> 
> But how could it?  The various target hooks are called from LRA when the
> pseudos are _not_ yet replaced with their MEMs or their hardregs.  How would
> the target know to do this substitution internally for correctness checking?
> How would it know that one pseudo is equivalent to a MEM, and another to a
> hardreg?  Looking at lra_in_progress as some targets are currently doing (and
> my hack does)?  That doesn't sound like a good design, it's simply a hidden
> parameter for the target hook in a global variable.
> 
> So, how else?  Substituting before the hooks are asked is just busy work,
> not asking the target at all means continuously adding stuff to LRA whenever
> a
> target wants something more.
BASE_REG_CLASS and INDEX_REG_CLASS (and their variants) specify what needs to
happen for an address that doesn't currently use hard registers.  And
legitimate_address_p should test whether addresses that *do* currently use hard
registers are using the right registers.

There should be no need for the hooks to do their own pseudo-to-hard-register
lookup.  The idea that one pseudo register maps to one hard register is very
simplistic and doesn't take region-based allocation or inheritance into
account.  IMO it's a concept that should go away when reload does.

And it doesn't make sense IMO to accept (say) %aN index registers or %dN base
registers at any stage, even before allocation.

Reply via email to