This implements a preliminary interface for targets to specify how a given operation should be legalized, with a fewproof of concept legalizations for integer addition.
ISelDAG seems to have overloaded "Expand" to mean quite a few different possible legalization strategies, which I'd like to avoid for GlobalISel. So at the moment, the possible generic options are:
- Legal (nothing to do)
- NarrowScalar (e.g. i64 -> i32 twice, <4 x i64> -> <4 x i32>).
- WidenScalar (e.g. i8 -> i32, <8 x i1> -> <8 x i8>).
- FewerElements (e.g. <4 x i64> -> <2 x i64> twice).
- MoreElements (e.g. <2 x i8> -> <8 x i8>).
- Libcall (self-explanatory).
- Custom (as with ISelDAG, target will handle it).
I am hoping scalarization can be considered a special case of "FewerElements" where the legal number of elements is 1 since the distinction between "<1 x %type>" and "%type" that exists now is a bit sketchy.
For an operation that is illegal on a vector type, we first legalize the underlying scalar (with a separate "setScalarInVectorAction" interface specifying how because, for example, "G_ADD <8 x i8>" may be fine but "G_ADD i8" only representable by promoting to i64). After that we know that the operation is legal for *some* number of vector elements and the second step is to find that.
Some extension will be needed to handle operations with more than one type (for example "i1 = G_ICMP i8 %a, %b"). In this and some other cases what should happen to the result is independent of the operands. I have some vague ideas on this, but nothing concrete.
One other thought, not on the wider picture but the specific G_ADD case in this patch was: just how many G_ADDs do we need/want? For now I've stuck with ADD/ADDC/ADDE, but I'm increasingly convinced that the last two are redundant (ADDC is just "ADDE a, b, 0") and I'm starting to think that it might be better to just have ADDE at the MIR level (with G_ADD being "res, thing<dead> = G_ADDE a, b, 0"). We could still have convenience queries and MIRBuilder methods to produce simple adds.
Any bright ideas or other comments welcome!
Cheers.
Tim.
I think we need to say something about what happens to the definition and arguments of MI.
My goal was to have transformations that take legal mir and produce legal mir. For that to be possible, we need to preserve the definition and arguments (with what I called the extract and build_sequence operations in the talk.)
We need to say that somewhere. Moreover, we need to say what happen to the extract and build_sequence operations that are created. Do we legalize them now, do we return a list of them, etc.?
I think the latter is preferable but maybe we want to also provide an option for the former.
Also, please comment on what is the boolean supposed to mean.