spill to register not stack?

Given an architecture with two classes of registers: A is general purpose and has an "adequate" number of registers, and C which is special purpose and has very few (e.g. one) register. There are cheap instructions that directly copy from C to A and vice versa.

If we need another C register and they are all live, we need to spill one. Currently as far as I can tell, the only way to do that is spill to the stack. Is there a knob I can turn to get the spill from C to go to an A register?

Thanks,
brian

On PowerPC, we implemented support for spilling GPR registers to vector registers. Essentially, it requires specifying the correct register class in getLargestLegalSuperClass() as well as storeRegToStackSlot()/loadRegFromStackSlot(). You can see what is controlled with the EnableGPRToVecSpills option.

If you also want to use this method for spilling callee-saved registers to other registers, you can do what we do on PPC in assignCalleeSavedSpillSlots() to specify the destination register. This should also ensure that the CFI directives are emitted correctly. Keep in mind that this can likely only be done for leaf functions since you’ll likely be spilling these to caller-saved registers of the other class.

Hope this helps,
Nemanja

Hi Brian,

+1 on what Nemanja said: specifying large register classes is the key.

More details here:
http://lists.llvm.org/pipermail/llvm-dev/2019-December/137700.html

Cheers,
-Quentin

Thank you Nemanja and Quentin! I did the following:

1. Defined a register class AC that is the union of A and C.

2. In *RegisterInfo, implement getLargestLegalSuperClass, which when queried for C returns AC.

3. In *InstrInfo, teach copyPhysReg how to copy between registers in A and C.

And voila, spills to register work!

Maybe there should be a FAQ for implementers of backends and this should be in it.

Thanks again,
brian

Thank you Nemanja and Quentin! I did the following:

1. Defined a register class AC that is the union of A and C.

2. In *RegisterInfo, implement getLargestLegalSuperClass, which when queried for C returns AC.

3. In *InstrInfo, teach copyPhysReg how to copy between registers in A and C.

And voila, spills to register work!

Great!

Maybe there should be a FAQ for implementers of backends and this should be in it.

Yeah, I should really get to it. It comes back every now and then.
Do you have a suggestion on where we should put that so that it is easily discoverable for backend authors?

Cheers,
-Quentin

Thank you Nemanja and Quentin! I did the following:

1. Defined a register class AC that is the union of A and C.

2. In *RegisterInfo, implement getLargestLegalSuperClass, which when queried for C returns AC.

3. In *InstrInfo, teach copyPhysReg how to copy between registers in A and C.

And voila, spills to register work!

Great!

Maybe there should be a FAQ for implementers of backends and this should be in it.

Yeah, I should really get to it. It comes back every now and then.
Do you have a suggestion on where we should put that so that it is easily discoverable for backend authors?

Being an old grey beard, I like to be able to grep FAQs. But maybe the obvious place is an appendix to "Writing an LLVM Backend".

brian