I attempt to optimize the use of the ‘CMP’ instruction on my architecture by removing the instruction instances where the Status Register already had the correct status flags.
The cmp instruction in my architecture is the typical one that compares two registers, or a register with an immediate, and sets the Status Flags accordingly. I implemented my ‘cmp’ instruction in LLVM by custom lowering the SETCC, SELECT_CC and BR_CC in the usual way, mostly following the ARM implementation. In particular the target cmp instruction is created and glued to a target conditional instruction, such as a conditional branch, or a conditional select.
The generated code may look like this:
add R0, R1, R2
cmp R0, #0
This works fine, but now I would want to go one step further:
As part of the SETCC and SELECT_CC lowering, I can determine if the conditions are met in my architecture to avoid generating a ‘cmp’ instruction at all. For example, if the left operand of the SETCC is an ‘addition’, the right operand is constant zero, and the condition is 'ISD::CondCode::SETEQ, I can safely assume that the Status Register in my architecture already has the right condition just before the ‘cmp’, which has been set by the target ‘add’ instruction. So at this point I want to avoid generating the ‘cmp’ because it is redundant.
My goal is to replace the assembly code shown above, by just this:
add R0, R1, R2
The ‘cmp’ was redundant in this case because the add instruction already set the Z (zero) flag
I tried several things, but I got stuck in some way in all of them. For example, an approach that I tried is to have a ‘dummy_cmp’ instruction, that I generate instead of the regular ‘cmp’ when the comparison is redundant. The ‘dummy_cmp’ must be removed at a latter stage, ideally during the selDAGToDAG phase, but I failed to do so.
- So my first question is. How do I remove the ‘dummy_cmp’ node in the MyTargetISelDAGtoDAG::Select() function?
Another approach that I tried, which I regard as preferable, is to directly avoid the creation of a ‘cmp’ instruction during ISelLowering. Instead of ‘cmp’, use the LHS operand of the SETCC operand if it mets the conditions described above. The problem that I found with this approach is that the ‘cmp’ is just a ‘glue’ to the target branch or select instruction, however, the LHS is an actual operand (for example an ‘add’ node), so I need to create a ‘glue’ for it, in order to be attached to the target branch instruction.
- My second question is therefore, how do I create a ‘glue’ for an existing ‘add’ node that I can attach to the target conditional instruction as a replacement of the ‘cmp’ instruction?