Hi, I've come across a problem while working on an LLVM backend for a new target architecture. This architecture has two single-ported register files. Each instruction can only read one operand from each register file, but can write to either. I tried implementing it naïvely in TableGen with two definitions per instruction, so I had: def AllRegs : RegisterClass< ... (add interleave (XRegs, YRegs))>; and in the InstrInfo.td: def Instr_xy: Instruction(outs AllRegs:$dst), (ins XRegs:$src1, YRegs:$src2), "...", [(set AllRegs:$dst, (OpNode XRegs:$src1, YRegs:$src2))] def Instr_yx: Instruction(outs AllRegs:$dst), (ins YRegs:$src1, XRegs:$src2), "...", [(set AllRegs:$dst, (OpNode YRegs:$src1, XRegs:$src2))] for each instruction. However, upon failing the first match, it insisted on swapping the registers between the two classes and sticking with that instruction. I also tried using ComplexPatterns, but to no avail. I'm sure this is entirely possible, but I can't see how it's done. Thanks, Fraser -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20121004/92f539e9/attachment.html>
Jakob Stoklund Olesen
2012-Oct-04 20:46 UTC
[LLVMdev] RegisterClass constraints in TableGen
On Oct 4, 2012, at 8:20 AM, Fraser Cormack <frasercrmck at gmail.com> wrote:> Hi, > > I've come across a problem while working on an LLVM backend for a new target architecture. > > This architecture has two single-ported register files. Each instruction can only read one operand from each register file, but can write to either. I tried implementing it naïvely in TableGen with two definitions per instruction, so I had: > > def AllRegs : RegisterClass< ... (add interleave (XRegs, YRegs))>; > > and in the InstrInfo.td: > > def Instr_xy: Instruction(outs AllRegs:$dst), (ins XRegs:$src1, YRegs:$src2), "...", [(set AllRegs:$dst, (OpNode XRegs:$src1, YRegs:$src2))] > > def Instr_yx: Instruction(outs AllRegs:$dst), (ins YRegs:$src1, XRegs:$src2), "...", [(set AllRegs:$dst, (OpNode YRegs:$src1, XRegs:$src2))] > > for each instruction. However, upon failing the first match, it insisted on swapping the registers between the two classes and sticking with that instruction.LLVM's register allocator's can't model that constraint, and we don't support the multiple alternatives you describe either. Perhaps you could let isel always use one variant, and write a special pre-RA pass to switch the opcodes? /jakob