[llvm-dev] Conditional tablegen expressions with math ops?

Phil Tomson via llvm-dev llvm-dev at lists.llvm.org
Tue May 3 17:20:29 PDT 2016


In our generated asm code we've got a constraint such that two registers in
a ternary op have to be in different "banks", best illustrated with an
example:

   add  r1,r2,r1 # r1 <- r2 + r1

The problem here is that the first operand (the receiver of the value) is
in the same "bank" as the 3rd operand (r1 again). This will cause an extra
cycle to be burned. As it turns out the first and second operands can be in
the same bank, so the issue is with the first and third operand being in
the same bank.

This example is easily "fixed" (the performance is optimized) by swapping
the 2nd and 3rd operands:

  add  r1, r1, r2 # r1 <- r1 + r2


There are four banks and the formula to figure out which bank a register is
in is just: r%4

Which brings me to tablegen:

We've got this in our specialized ArchInstrInfo.td:

// r1 = r2 op r3
//
class ArithOp_RR< bits<7> op,
                  string instr_asm,
                  SDNode opNode,
                  OperandInfo info,
                  InstrItinClass itin >
  : FR3< op,
        (outs info.regClass:$r1),
        (ins info.regClass:$r2, info.regClass:$r3),
        instr_asm # "\t\t$r1, $r2, $r3, " # info.sizeStr,
        [(set info.regClass:$r1, (opNode info.regClass:$r2,
info.regClass:$r3))],
        itin > {
          let isFloat = info.isFloat;
          let opsize = info.sizeCode;
        }

Is there a way to do something like:


// r1 = r2 op r3
//
class ArithOp_RR< bits<7> op,
                  string instr_asm,
                  SDNode opNode,
                  OperandInfo info,
                  InstrItinClass itin >
  : FR3< op,
        (outs info.regClass:$r1),
        (ins info.regClass:$r2, info.regClass:$r3),
if( $r1%4 == $r3%4 ) {
       instr_asm # "\t\t$r1, $r3, $r2, " # info.sizeStr,
        [(set info.regClass:$r1, (opNode info.regClass:$r3,
info.regClass:$r2))],
} else {
       instr_asm # "\t\t$r1, $r2, $r3, " # info.sizeStr,
        [(set info.regClass:$r1, (opNode info.regClass:$r2,
info.regClass:$r3))],
}
        itin > {
          let isFloat = info.isFloat;
          let opsize = info.sizeCode;
        }


Is that even remotely possible? If not, are there other ways to achieve
this sort of thing? Would I be better off doing it in the
ArchASMPrinter.cpp (I would think this could be problematic)? Or is there
somewhere "further up" which would be more appropriate?

Phil
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20160503/fd1b1280/attachment.html>


More information about the llvm-dev mailing list