Richard Sandiford schrieb:
Georg-Johann Lay <a...@gjlay.de> writes:

2) The secondary reload hook is always called with
   regclass = GENERAL_REGS, even in cases where the class
   is known to be NO_LD_REGS like, e.g. when preparing arguments
   for a function call. Why this? I would expect to get the smallest
   available regclass. If a reg lies in LD_REGS, a secondary reload
   is not needed, but how can I know if class is always GENERAL_REGS?
   Is it ensured that secondary reload hook gets never called when
   a constraint alternative matches, like "d,i"?

As far as the last bit goes: once reload has decided that it needs to
reload A into B, it's uses the secondary reload hook (and only that hook)
to decide whether a secondary reload is needed.  The movsi constraints
only matter when reloading a pre-reload movsi instruction.

Ok, so even if there is an "A,B" alternative (or superset) in
respective mov insn, reload will query secondary reload hook.

What does "reloading a pre-reload mov instruction" mean?


I just meant a move instruction that existed before reload started.
If you have a movsi instruction:

   (set (reg:SI A) (const_int X))

before reload, then reload will use the movsi constraints to decide
how to reload it.  But reloads themselves are effectively move "operations"
that have yet to be created.  This means that there are no instructions
for reload to match against.  The point of the hooks is to help reload
decide how these conceptual move operations should be decomposed into
real instructions, and what additional temporary registers are needed
for those instructions.


I think the reason you only ever see GENERAL_REGS being passed in is
because (from a quick look at avr.md) very few non-move patterns use
the "d" and "l" constraints.  They all seem to use the "r" constraint.
Thus reloads from those instructions will use GENERAL_REGS rather than
NO_LD_REGS.

Thanks for that clarification. I though that when there is a need to
do a move, the movXX constraints would apply.

"r" is the union of "l" and "d" just for 8- and 16-bit modes. For SI
there is reg:SI 14 which spans both "l" (14,15) and "d" (16,17) so
that this reg is neither in "l" nor "d" but in "r". So the constraint
would have to be "ldr".

Unfortunately, the internals doc on constraints are not very
comprehensible and there is much space for misunderstanding and
speculation on how to apply them correctly.


Using "ldr" over "r" would have no effect.  "ldr" is the union of
"l", "d" and "r", which as you say is simply "r".


If you want to make reload use NO_LD_REGS for these GENERAL_REGS reloads,
at least when the reloaded value is a constant, then it might be worth
defining TARGET_PREFERRED_RELOAD_CLASS.

It's preferred to load constants into LD_REGS, because these regs have
instructions to do that. However, LD_REGS are already very busy, and I
suspect it is no good idea to increase register pressure on them even
more.


I doubt it, TBH.  If reload picks a non-LD_REGS register for a constant
reload, won't your secondary reload hook say that an LD_REGS temporary
is needed?  So you get the LD_REGS register either way.  What you're
doing by defining TARGET_PREFERRED_RELOAD_CLASS is avoiding the need
for both an LD_REGS and a non-LD_REGS register.
>
> Richard
>

The current implementation does not need an intermediate reg. The asm template saves a QI LD_REG in a temporary reg (r0 which is fixed and designed as temporary reg for purposes like that) and uses that LD_REG to copy the const into the non-LD_REG byte by byte. This takes 10 instructions for an SI constant; to get a const into LD_REG SI just takes 4 instructions, one for each byte.

The implementation then hopes that peep2 comes up with a LD_REG clobber reg, and in that case that clobber reg is used to get the constant into the non-LD_REG. The peep2 pattern is similar to the old style input reload with a QI clobber.

That way, reload need not to supply a clobber reg.

My idea was to supply a QI clobber during reload already, so that the copy to and from the fixed temporary reg could be always avoided. There is no need for SI temporary, just for a QI clobber reg. But it's usesless if there is no way to tell if the actual reg where the value is to be stored is LD_REGS or not.

Johann

Reply via email to