Assume I define registers R0…R15 and two register classes RegA and RegB. RegA contains R0 to R7 while RegB contains R0 to R15.
Then I check the machine instruction, it seems that in some cases, the %vreg0 belongs to RegB; in other cases %vreg1 belongs to RegA_RegB. Can you tell me how TableGen decides which is which? At first, I guess &verg0 will be assigned by R8 to R15 only so that %vreg0 belongs to RegB. But it seems my guess is wrong because %verg0 can also be assigned by R0.
Any input is appreciable.
TableGen does not directly make the decision on what class to use for virtual registers, only the constraints on the operand. InstrEmitter ultimately makes this decision, using a combination of factors including the register class you specified for a specific type, whether the class is allocatable, and satisfying the operand register classes defined as a property of the instruction. The register classes defined for the instruction's operands in TableGen influences the selected class. See InstrEmitter::CreateVirtualRegisters and other related functions.
I have another question related to the register classes and register allocation.
In the above example, RegA has 8 registers and RegB has 16 registers. For register allocation, if RegA doesn’t have enough available registers to use, a ‘spill’ and ‘refill’ will be inserted by InlineSpiller by calling storeRegToStackSlot(). Assume in this case, RegB still has enough registers and there is a ‘MOVE’ instruction to move to value between RegA and RegB. I prefer to insert a ‘MOVE’ instruction to mimic the ‘spill’ and ‘refill’. For example, ‘MOVE’ the value from RegA to RegB to mimic the ‘spill’ and ‘MOVE’ the value from RegB to RegA to mimic ‘refill’. Does this sound reasonable? And can you suggest some proper ways to achieve this?