What guarantees, if any, does the scheduler make when two selection nodes are linked by a Flag type? Can I expect the machine instructions that are selected from the two nodes to be scheduled consecutively? I'm trying to implement code generation for SELECT_CC nodes in a back end that I'm working on. The compare operations on the architecture communicate via bits in a global status register, much like on MSP430. In fact, I've modeled my implementation after that of the MSP430. So I have custom target nodes akin to MSP430cmp and MSP430selectcc and pseudo-instructions like MSP430::Select16. The back end lowers SELECT_CC nodes to MSP430cmp/MSP430selectcc pairs that are linked together by Flag values. The instruction selection pass converts the MSP430selectcc node to a MSP430::Select16 pseudo-instruction which is later expanded to a condition branch by a custom inserter. I'm still trying to figure out exactly why, but for some inputs the DeadMachineInstructionElim pass eliminates the compare instruction. What appears to be happening is that one of the register-to-register move instructions of the block occurs between the compare and conditional branch when the pass iterates over the instructions in reverse order. Since the architecture's move instruction defines the status register, the define by the compare instruction is deemed unused. And so the instruction is eliminated. Any ideas on why a move instruction would be showing up between the compare and branch? -Ken
Arnaud Allard de Grandmaison
2010-Jun-03 07:07 UTC
[LLVMdev] Flags and Custom Inserters in code generation
Hi Ken, I have also been hit by the same issue on one of our backends, where the CopyRegToReg instruction is cloberring the flags. It took me quite some time to understand why. The culprit is the PHIElimination phase which assumes CopyRegToReg does NOT clobbers the flags. I attached the patch I have been using for llvm-2.6. It is taking advantage of the fact that the only implicit register def / use is for the flags, at least for my backends; the patch could require some tweaking for your backend. Best regards, -- Arnaud de Grandmaison -----Original Message----- From: llvmdev-bounces at cs.uiuc.edu [mailto:llvmdev-bounces at cs.uiuc.edu] On Behalf Of Ken Dyck Sent: Wednesday, June 02, 2010 8:35 PM To: llvmdev at cs.uiuc.edu Subject: [LLVMdev] Flags and Custom Inserters in code generation What guarantees, if any, does the scheduler make when two selection nodes are linked by a Flag type? Can I expect the machine instructions that are selected from the two nodes to be scheduled consecutively? I'm trying to implement code generation for SELECT_CC nodes in a back end that I'm working on. The compare operations on the architecture communicate via bits in a global status register, much like on MSP430. In fact, I've modeled my implementation after that of the MSP430. So I have custom target nodes akin to MSP430cmp and MSP430selectcc and pseudo-instructions like MSP430::Select16. The back end lowers SELECT_CC nodes to MSP430cmp/MSP430selectcc pairs that are linked together by Flag values. The instruction selection pass converts the MSP430selectcc node to a MSP430::Select16 pseudo-instruction which is later expanded to a condition branch by a custom inserter. I'm still trying to figure out exactly why, but for some inputs the DeadMachineInstructionElim pass eliminates the compare instruction. What appears to be happening is that one of the register-to-register move instructions of the block occurs between the compare and conditional branch when the pass iterates over the instructions in reverse order. Since the architecture's move instruction defines the status register, the define by the compare instruction is deemed unused. And so the instruction is eliminated. Any ideas on why a move instruction would be showing up between the compare and branch? -Ken _______________________________________________ LLVM Developers mailing list LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev -------------- next part -------------- A non-text attachment was scrubbed... Name: PHIElimination.patch Type: application/octet-stream Size: 1760 bytes Desc: PHIElimination.patch URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20100603/d22ead3e/attachment.obj>
Christoph Erhardt
2010-Jun-03 10:23 UTC
[LLVMdev] Flags and Custom Inserters in code generation
Hi Ken, you can work around this issue by setting isTerminator = 1 for both the comparison and the branch instruction. The PHI elimination pass inserts all moves before the terminator group of the basic block. This was proposed in http://lists.cs.uiuc.edu/pipermail/llvmdev/2009-July/023709.html and works for me. Regards, Christoph Am 02.06.2010 20:35, schrieb Ken Dyck:> What guarantees, if any, does the scheduler make when two selection > nodes are linked by a Flag type? Can I expect the machine instructions > that are selected from the two nodes to be scheduled consecutively? > > I'm trying to implement code generation for SELECT_CC nodes in a back > end that I'm working on. The compare operations on the architecture > communicate via bits in a global status register, much like on MSP430. > In fact, I've modeled my implementation after that of the MSP430. So I > have custom target nodes akin to MSP430cmp and MSP430selectcc and > pseudo-instructions like MSP430::Select16. The back end lowers SELECT_CC > nodes to MSP430cmp/MSP430selectcc pairs that are linked together by Flag > values. The instruction selection pass converts the MSP430selectcc node > to a MSP430::Select16 pseudo-instruction which is later expanded to a > condition branch by a custom inserter. > > I'm still trying to figure out exactly why, but for some inputs the > DeadMachineInstructionElim pass eliminates the compare instruction. What > appears to be happening is that one of the register-to-register move > instructions of the block occurs between the compare and conditional > branch when the pass iterates over the instructions in reverse order. > Since the architecture's move instruction defines the status register, > the define by the compare instruction is deemed unused. And so the > instruction is eliminated. > > Any ideas on why a move instruction would be showing up between the > compare and branch? > > -Ken