I just added a new type of MachineOperand to the code generator:
MO_RegisterMask.
Register mask operands are used on machine instructions that clobber large sets
of registers, typically calls. Instead of a long list of <imp-def>
operands, a call now has a single <regmask> operand that contains a
pointer to a bit mask of call-preserved registers. This reduces memory usage and
improves compile times significantly.
The register mask depends on the current sub-target and the calling convention
used in the call. This means that it is no longer necessary for targets to have
multiple call opcodes with different sets of clobbered registers.
Currently, only the ARM and X86 targets have been converted to use register
masks. Owners of the other targets in the tree should consider converting as
well.
The conversion is quite simple, copy from ARM and X86 as needed:
- Move callee saved register lists to *CallingConv.td by defining
CalleeSavedRegs instances. TableGen will produce *_SaveList and *_RegMask
arrays. Use them to implement the TRI::getCalleeSavedRegs() and
TRI::getCallPreservedRegMask() hooks.
- Fix target-dependent code to understand regmask operands. The
target-independent passes have already been fixed.
- Update *TargetLowering::LowerCall() to add a RegisterMaskSDNode operand to
call SDNodes.
- Update your fast isel call emission to do the same.
- Remove Defs = […] from call instruction definitions. RISC architectures may
want to keep a link register def, ARM did.
- Remove duplicate call opcodes that are no longer necessary.
/jakob