this patch adds a mechanism to control the inferring of new register classes.
The main issue this is trying to solve is that when we have overlapping register classes and register tuples like in this example:
def SRegs : MyClass<16, [i16], (sequence "S%u", 0, 15)>;
def SRegslow : MyClass<16, [i16], (trunc SRegs, 5)>;
def SRegshigh : MyClass<16, [i16], (shl SRegs, 5)>;
def Stup3 : RegisterTuples<[ssub0, ssub1, ssub3], [
(shl SRegs, 0), (shl SRegs, 1), (shl SRegs, 2) ]>;
def SRegs3 : MyClass<32, [untyped], (add Stup3)>;
Then tablegen tries to generate all the possible register classes definitions to answer to getMatchingSuperRegClass().
This includes classes like:
The more tuples you have and the more overlapping constraints you have the worse this can become.
This approach tries to give knob to use to stop tablegen to infer classes for certain register classes.
This knob consist in a mask (tentatively called a ClassMask) that partitions the register file in sections. If the masks of two register classes are disjoint we do not generate inferred classes out of them.
If we rewrote the above definitions for SReglow and SReghigh like this
def SRegslow : MyClass<16, [i16], (trunc SRegs, 5)>
let ClassMask = 1;
def SRegshigh : MyClass<16, [i16], (shl SRegs, 5)>
let ClassMask = 2;
Then the two masks for the two classes would be disjoint (0x1 and 0x2) and tablegen wouldn't generate inferred classes for the combinations of those two classes.
I have to admit that I'm not an expert in the generation of the register representations, so I'm not 100% sure this is the best approach, but this is a step in the direction of limiting the generation of inferred classes for this case.
This patch is also a kind of RFC in figuring out if there is a better solution for this issue when you have register tuples and you try to add constrained register classes.
I wonder if anybody else encountered a similar problem with their targets