Question about isel patterns

I am looking for a way to define patterns without specifying the type
of the root node in the RHS result.
I want to be able to write something like this:

def : Pat<(i64 imm:$in), (GenDAG imm:$in)>;
(GenDAG is a custom function that returns the DAG that replaces the
node in the LHS.)

A little background:

Mips emits a sequence of instructions to load immediate constants that
do not fit in the 16-bit
immediate field of an instruction. The number or types of instructions
in the sequence vary depending
on the value of the immediate, so it seems impractical to list all the
possible matching patterns.
Note that I am trying to make the instruction sequence as short as
possible, so simply partitioning the
immediate into four 16-bit parts will not work.

Here are some examples:

1. Imm = 0x000000007fff0000
LUi $dst, 7ffff // load immediate to upper 16-bit

2. Imm = 0x000000007fffffff
LUi $r0, 7ffff
ORi $dst, $r0, fffff

3. Imm = 0x00000fffffffffff
ADDiu $r0, $zero, 1
SLL $r1, $r0, 44 // 44-bit shift left logical
ADDiu $dst, $r1, fffff // add -1. the imm operand 0xffff is
sign-extended to 64-bit when added.

Currently, I have the following patterns (the last instruction of the
sequence, or the root of the DAG, can be ADDiu, ORi, SLL or LUi):

def : Pat<(isImmADDiu:$imm), (ADDiu (RegOpnd imm:$imm), (ImmOpnd imm:$imm))>;
def : Pat<(isImmORi:$imm), (ORi (RegOpnd imm:$imm), (ImmOpnd imm:$imm))>;
def : Pat<(isImmSLL:$imm), (SLL (RegOpnd imm:$imm), (ImmOpnd imm:$imm))>;
def : Pat<(isImmLUi:$imm), (LUi (ImmOpnd imm:$imm))>;

isImm*, RegOpnd and ImmOpnd all call a function which computes the
instruction sequence (the result is cached).

ImmOpnd and RegOpnd are SDNodeXForms that return the immediate and
register operands of the
root node. For example, when the immediate in the third example is matched,
RegOpnd returns (SLL (ADDiu $zero, 1), 44) and ImmOpnd returns (ffff).

isImmADDiu is a predicate that returns true if the last instruction of
the sequence (root of the DAG) is ADDiu.

Why not just add a case to MipsDAGToDAGISel::Select?


For some reason, I never thought of doing that.

Thank you for the tip.