[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


Hi,

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 
%19.

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,

Jonas



More information about the llvm-dev mailing list