Sean Silva via llvm-dev
2017-Dec-24 04:43 UTC
[llvm-dev] Canonical way to handle zero registers?
Thanks, that sounds like it would work. Was this based on what any other target did? Or do any other targets take this approach? I just want to make sure that we don't already have a hook suitable for this. Overriding runOnFunction to run what could be described as just a "late SelectionDAG pass" sounds pretty intrusive. Do you remember other approaches that didn't work? -- Sean Silva On Dec 22, 2017 2:17 PM, "Simon Dardis" <Simon.Dardis at mips.com> wrote:> Hi Sean, > > Have you looked at inheriting from llvm:SelectionDAGISel for your target, > invoking runOnMachineFunction to perform > ISEL, then post processing the output by finding the cases where -1 is > synthesized then used and replacing the uses > of the synthesized -1 with the register wired to -1? > > The MIPS backend takes this approach for dealing with the zero register, > see MipSEISelDAGToDAG.cpp for reference. > > Thanks, > Simon > ------------------------------ > *From:* llvm-dev [llvm-dev-bounces at lists.llvm.org] on behalf of Sean > Silva via llvm-dev [llvm-dev at lists.llvm.org] > *Sent:* Friday, December 22, 2017 5:22 AM > *To:* llvm-dev > *Subject:* [llvm-dev] Canonical way to handle zero registers? > > I looked around the codebase and didn't see anything that obviously looked > like the natural place to turn constant zero immediates into zero-registers > (i.e. registers that always return zero when read). Right now we are > expanding them in ISelLowering::LowerOperation but that seems too early. > > The specific issue I'm hitting is that we have a register that reads as -1 > and so when we replace -1 too early with this register, the standard "not" > pattern (xor x, -1) will fail to match to "not". > > Thanks, > Sean Silva >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20171223/9cfab693/attachment.html>
Alex Bradbury via llvm-dev
2017-Dec-24 08:16 UTC
[llvm-dev] Canonical way to handle zero registers?
On 24 December 2017 at 04:43, Sean Silva via llvm-dev <llvm-dev at lists.llvm.org> wrote:> Thanks, that sounds like it would work. Was this based on what any other > target did? Or do any other targets take this approach? > > I just want to make sure that we don't already have a hook suitable for > this. Overriding runOnFunction to run what could be described as just a > "late SelectionDAG pass" sounds pretty intrusive. Do you remember other > approaches that didn't work?An obvious approach that doesn't work: just writing a pattern. This causes assertions, seemingly as some code paths don't like the introduction of a physical register. At least AArch64, Lanai, and RISC-V handle the zero register in TgtDAGToDAGISel::Select. Lanai also has a "-1" register and handles that case in the same place. Copying from LanaiDAGToDAGISel::Select: EVT VT = Node->getValueType(0); switch (Opcode) { case ISD::Constant: if (VT == MVT::i32) { ConstantSDNode *ConstNode = cast<ConstantSDNode>(Node); // Materialize zero constants as copies from R0. This allows the coalescer // to propagate these into other instructions. if (ConstNode->isNullValue()) { SDValue New = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), SDLoc(Node), Lanai::R0, MVT::i32); return ReplaceNode(Node, New.getNode()); } // Materialize all ones constants as copies from R1. This allows the // coalescer to propagate these into other instructions. if (ConstNode->isAllOnesValue()) { SDValue New = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), SDLoc(Node), Lanai::R1, MVT::i32); return ReplaceNode(Node, New.getNode()); } } break; Best, Alex
Simon Dardis via llvm-dev
2017-Dec-24 17:33 UTC
[llvm-dev] Canonical way to handle zero registers?
Hi Sean, I didn't implement that particular functionality as it was before my time at MIPS, Akira (+cc) may recall the specifics why he took that approach. As far as I can see, the MIPS' approach pre-dates the AArch64 style approach which is also used by Lanai & RISCV as Alex highlights, so I believe it was a novel approach. It appears no other targets take this approach of a late SelectionDAG pass. Thanks, Simon ________________________________ From: Sean Silva [chisophugis at gmail.com] Sent: Sunday, December 24, 2017 4:43 AM To: Simon Dardis Cc: llvm-dev Subject: RE: [llvm-dev] Canonical way to handle zero registers? Thanks, that sounds like it would work. Was this based on what any other target did? Or do any other targets take this approach? I just want to make sure that we don't already have a hook suitable for this. Overriding runOnFunction to run what could be described as just a "late SelectionDAG pass" sounds pretty intrusive. Do you remember other approaches that didn't work? -- Sean Silva On Dec 22, 2017 2:17 PM, "Simon Dardis" <Simon.Dardis at mips.com<mailto:Simon.Dardis at mips.com>> wrote: Hi Sean, Have you looked at inheriting from llvm:SelectionDAGISel for your target, invoking runOnMachineFunction to perform ISEL, then post processing the output by finding the cases where -1 is synthesized then used and replacing the uses of the synthesized -1 with the register wired to -1? The MIPS backend takes this approach for dealing with the zero register, see MipSEISelDAGToDAG.cpp for reference. Thanks, Simon ________________________________ From: llvm-dev [llvm-dev-bounces at lists.llvm.org<mailto:llvm-dev-bounces at lists.llvm.org>] on behalf of Sean Silva via llvm-dev [llvm-dev at lists.llvm.org<mailto:llvm-dev at lists.llvm.org>] Sent: Friday, December 22, 2017 5:22 AM To: llvm-dev Subject: [llvm-dev] Canonical way to handle zero registers? I looked around the codebase and didn't see anything that obviously looked like the natural place to turn constant zero immediates into zero-registers (i.e. registers that always return zero when read). Right now we are expanding them in ISelLowering::LowerOperation but that seems too early. The specific issue I'm hitting is that we have a register that reads as -1 and so when we replace -1 too early with this register, the standard "not" pattern (xor x, -1) will fail to match to "not". Thanks, Sean Silva -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20171224/3dd8943b/attachment.html>
Sean Silva via llvm-dev
2017-Dec-26 23:42 UTC
[llvm-dev] Canonical way to handle zero registers?
Thanks! That looks like a winning approach. I swear I grepped around for ISD::Constant but for some reason never found this code. I think maybe I was searching for ISD::Constant with setOperationAction, which in hindsight was narrowing down my search to just lowering, which is exactly what I didn't want! (I was looking for other approaches). I also tried looking in depth at PowerPC but it looks like it doesn't use this approach either. -- Sean Silva On Dec 24, 2017 12:16 AM, "Alex Bradbury" <asb at asbradbury.org> wrote: On 24 December 2017 at 04:43, Sean Silva via llvm-dev <llvm-dev at lists.llvm.org> wrote:> Thanks, that sounds like it would work. Was this based on what any other > target did? Or do any other targets take this approach? > > I just want to make sure that we don't already have a hook suitable for > this. Overriding runOnFunction to run what could be described as just a > "late SelectionDAG pass" sounds pretty intrusive. Do you remember other > approaches that didn't work?An obvious approach that doesn't work: just writing a pattern. This causes assertions, seemingly as some code paths don't like the introduction of a physical register. At least AArch64, Lanai, and RISC-V handle the zero register in TgtDAGToDAGISel::Select. Lanai also has a "-1" register and handles that case in the same place. Copying from LanaiDAGToDAGISel::Select: EVT VT = Node->getValueType(0); switch (Opcode) { case ISD::Constant: if (VT == MVT::i32) { ConstantSDNode *ConstNode = cast<ConstantSDNode>(Node); // Materialize zero constants as copies from R0. This allows the coalescer // to propagate these into other instructions. if (ConstNode->isNullValue()) { SDValue New = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), SDLoc(Node), Lanai::R0, MVT::i32); return ReplaceNode(Node, New.getNode()); } // Materialize all ones constants as copies from R1. This allows the // coalescer to propagate these into other instructions. if (ConstNode->isAllOnesValue()) { SDValue New = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), SDLoc(Node), Lanai::R1, MVT::i32); return ReplaceNode(Node, New.getNode()); } } break; Best, Alex -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20171226/c03c4e28/attachment.html>
Akira Hatanaka via llvm-dev
2017-Dec-27 21:02 UTC
[llvm-dev] Canonical way to handle zero registers?
The function looks for "addiu $dst, $zero, 0" and tries to replace it with $zero. I don't remember whether there was a reason this had to be done after isel. It seems that you can just do it in DAGToDAGISel::Select. On Sun, Dec 24, 2017 at 9:33 AM, Simon Dardis <Simon.Dardis at mips.com> wrote:> Hi Sean, > > I didn't implement that particular functionality as it was before my time > at MIPS, Akira (+cc) may recall the > specifics why he took that approach. > > As far as I can see, the MIPS' approach pre-dates the AArch64 style > approach which is also used by Lanai & > RISCV as Alex highlights, so I believe it was a novel approach. It appears > no other targets take this approach > of a late SelectionDAG pass. > > Thanks, > Simon > ------------------------------ > *From:* Sean Silva [chisophugis at gmail.com] > *Sent:* Sunday, December 24, 2017 4:43 AM > *To:* Simon Dardis > *Cc:* llvm-dev > *Subject:* RE: [llvm-dev] Canonical way to handle zero registers? > > Thanks, that sounds like it would work. Was this based on what any other > target did? Or do any other targets take this approach? > > I just want to make sure that we don't already have a hook suitable for > this. Overriding runOnFunction to run what could be described as just a > "late SelectionDAG pass" sounds pretty intrusive. Do you remember other > approaches that didn't work? > > -- Sean Silva > > On Dec 22, 2017 2:17 PM, "Simon Dardis" <Simon.Dardis at mips.com> wrote: > >> Hi Sean, >> >> Have you looked at inheriting from llvm:SelectionDAGISel for your target, >> invoking runOnMachineFunction to perform >> ISEL, then post processing the output by finding the cases where -1 is >> synthesized then used and replacing the uses >> of the synthesized -1 with the register wired to -1? >> >> The MIPS backend takes this approach for dealing with the zero register, >> see MipSEISelDAGToDAG.cpp for reference. >> >> Thanks, >> Simon >> ------------------------------ >> *From:* llvm-dev [llvm-dev-bounces at lists.llvm.org] on behalf of Sean >> Silva via llvm-dev [llvm-dev at lists.llvm.org] >> *Sent:* Friday, December 22, 2017 5:22 AM >> *To:* llvm-dev >> *Subject:* [llvm-dev] Canonical way to handle zero registers? >> >> I looked around the codebase and didn't see anything that obviously >> looked like the natural place to turn constant zero immediates into >> zero-registers (i.e. registers that always return zero when read). Right >> now we are expanding them in ISelLowering::LowerOperation but that seems >> too early. >> >> The specific issue I'm hitting is that we have a register that reads as >> -1 and so when we replace -1 too early with this register, the standard >> "not" pattern (xor x, -1) will fail to match to "not". >> >> Thanks, >> Sean Silva >> >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20171227/d556c238/attachment.html>