[llvm-dev] Trying to insert a COPY in foldMemoryOperandImpl()
Jonas Paulsson via llvm-dev
llvm-dev at lists.llvm.org
Wed May 15 11:47:34 PDT 2019
I am working on a patch for the SystemZ backend that aims to make
three-address instructions the default, since those instructions are not
more expensive than their two-address counterparts, and this change
helps the register allocator to reduce spilling and register moves.
However, the reg/memory instructions that can be used to fold a reload
only accept a single register (corresponding to folding the RHS operand
of the 2-address register instruction).
Since in many cases the 3-address instructions end up with a register
allocation that could be used with the corresponding 2-address
instruction (dst and LHS assigned to the same phys-reg), it would be
nice to still fold the memory operand in these cases where RHS is
spilled. This is a bit more involved than doing this for a 2-address
instruction since the dst-reg and LHS reg have different virtual registers.
My progress so far can be found at https://reviews.llvm.org/D60888. A
short example here is when %9 is spilled:
%20:gr64bit = AGRK %19:gr64bit, %9:gr64bit
By passing the VirtRegMap to foldMemoryOperandImpl(), it can be checked
that %20 and %19 are allocated to the same phys-reg, which means that
the reload of %9 can be folded into a single SystemZ instruction.
The problem at this point is that RA can still change its allocation for
instance by evicting one of %20 and %19 and reassign that register to a
different one. Therefore I had the idea of inserting a COPY before the
AGRK, which would typically be deleted by MachineCopyProp as an identity
copy after regalloc is done:
=> %9 ends up on the stack =>
%20:gr64bit = COPY %19:gr64bit
%20:gr64bit = AG %20:gr64bit(tied-def 0), %stack.0
My problem now is what to do about updating the LiveIntervals of %20 and
I am not even sure if inserting a COPY here in the middle of the
register allocation during spilling is feasible, and if so, what is the
best way to do the updating?
Since the caller in this case (InlineSpiller) inserts any new
instructions into SlotIndexes, I thought it would be logical for it to
also handle the LiveInterval updating. It however does not do this
currently (see Phabricator post for suggestion).
An alternative approach may be to tell InlineSpiller that the Target is
taking care of the updating, and that way this simple case of inserting
a COPY in the SystemZ backend could be handled by the backend.
So, in summary, does this patch seem reasonable, and how should the
LiveIntervals best be updated? Any examples?
Thanks for any help,
More information about the llvm-dev