Hello all, I am working on adding atomics support to the AVR backend. Because the target can only have one core, it is sufficient to: - Save the status register - Disable interrupts - Do the nonatomic LOAD/STORE/SWAP/ADD - Restore the status register I’d really like to be able to do this at the IR level. What I want to do is write a custom lowering hook to convert ISD::ATOMIC_LOAD into a standard ISD::LOAD with the save/restore/interrupt nodes glued to it. Here’s what I have so far: // Store `SREG` auto Save = DAG.getCopyFromReg(DAG.getEntryNode(), DL, AVR::SREG, MVT::i8); // Disable interrupts (`clr` is equivalent to `bclr 7`). auto ClearInterrupts = DAG.getNode(AVRISD::BCLR, DL, MVT::Glue, DAG.getConstant(7, DL, MVT::i8)); // Perform the nonatomic load. auto *Node = cast<AtomicSDNode>(AtomicOp.getNode()); SDValue Load = DAG.getExtLoad(ISD::EXTLOAD, SDLoc(AtomicOp), AtomicOp.getValueType(), Node->getChain(), Node->getBasePtr(), Node->getMemoryVT(), Node->getMemOperand()); auto Restore = DAG.getCopyToReg(DAG.getEntryNode(), DL, AVR::SREG, Save); return Load; I can’t figure out how I can glue all these nodes together and return the nonatomic load. How can I do this? Cheers, Dylan -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20160604/8ac7af19/attachment.html>
Ping On Sat, Jun 4, 2016 at 4:15 PM, Dylan McKay <dylanmckay34 at gmail.com> wrote:> Hello all, > > I am working on adding atomics support to the AVR backend. > > Because the target can only have one core, it is sufficient to: > > - Save the status register > - Disable interrupts > - Do the nonatomic LOAD/STORE/SWAP/ADD > - Restore the status register > > I’d really like to be able to do this at the IR level. What I want to do > is write a custom lowering hook to convert ISD::ATOMIC_LOAD into a > standard ISD::LOAD with the save/restore/interrupt nodes glued to it. > > Here’s what I have so far: > > // Store `SREG` > auto Save = DAG.getCopyFromReg(DAG.getEntryNode(), DL, AVR::SREG, MVT::i8); > > // Disable interrupts (`clr` is equivalent to `bclr 7`). > auto ClearInterrupts = DAG.getNode(AVRISD::BCLR, DL, MVT::Glue, DAG.getConstant(7, DL, MVT::i8)); > > // Perform the nonatomic load. > auto *Node = cast<AtomicSDNode>(AtomicOp.getNode()); > SDValue Load = DAG.getExtLoad(ISD::EXTLOAD, SDLoc(AtomicOp), AtomicOp.getValueType(), > Node->getChain(), Node->getBasePtr(), > Node->getMemoryVT(), Node->getMemOperand()); > > auto Restore = DAG.getCopyToReg(DAG.getEntryNode(), DL, AVR::SREG, Save); > > return Load; > > I can’t figure out how I can glue all these nodes together and return the > nonatomic load. > > How can I do this? > > Cheers, > Dylan > >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20160609/6422dc9f/attachment.html>
Anton Korobeynikov via llvm-dev
2016-Jun-09 09:04 UTC
[llvm-dev] Gluing arbitrary nodes together
> I can’t figure out how I can glue all these nodes together and return the > nonatomic load. > > How can I do this?Your nodes should produce / consume special "glue" operand. -- With best regards, Anton Korobeynikov Department of Statistical Modelling, Saint Petersburg State University
Krzysztof Parzyszek via llvm-dev
2016-Jun-09 21:40 UTC
[llvm-dev] Gluing arbitrary nodes together
On 6/3/2016 11:15 PM, Dylan McKay via llvm-dev wrote:> > I can’t figure out how I can glue all these nodes together and return > the nonatomic load.Hi Dylan, As Anton said, you would need to use glue values. A node would take a glue as the last operand. That is the input glue, and will cause the node to be glued to the node that produced it. The output glue is one of the SDValues returned by the node (you can find out which one by looking at the dump). The DAG usually like this: Glue0 = MVT::Glue (..., Glue1, ...) = ISD::SOME_NODE_0 Op0, Op1, ..., Glue0 (..., Glue2, ...) = ISD::SOME_NODE_1 Op0, Op1, ..., Glue1 SOME_NODE_n would be created giving it MVT::Glue as the type of the last operand. The problem is that getLoad does not accept glue operands, so there isn't an easy way to use it with loads, which, I think, is the problem you ran into. If you want to have these nodes stick together, using glue may not be sufficient. After the machine instructions are generated, the scheduler may place instructions between the interrupt disable/restore and the atomic load itself. Also, the register allocator may insert some spills there---there are ways that this sequence may get separated. For this, the best approach may be to define a pseudo-instruction, which will be expanded into real instruction in the post-RA expansion pass. If you need it only for the DAG nodes, you could try to manufacture your own load via the generic getNode, forcing glue into it, but that may be more effort than it's worth. Maybe lowering it into your target-specific node would be the best approach after all? -Krzysztof -- Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
Hey Krzysztof, Yeah I mostly had issues with gluing the loads/stores. After the machine instructions are generated, the scheduler may place instructions between the interrupt disable/restore and the atomic load itself. Also, the register allocator may insert some spills there—-there are ways that this sequence may get separated. I didn’t think about that - it makes sense. It looks like building this in the MI stage is the only way. For this, the best approach may be to define a pseudo-instruction, which will be expanded into real instruction in the post-RA expansion pass Agree If you need it only for the DAG nodes, you could try to manufacture your own load via the generic getNode, forcing glue into it, but that may be more effort than it’s worth. Maybe lowering it into your target-specific node would be the best approach after all? It seems pretty tricky to construct all these manually, I agree with your point. I will settle on pseudo instructions. Cheers Krzysztof and Anton :) On Fri, Jun 10, 2016 at 9:40 AM, Krzysztof Parzyszek via llvm-dev < llvm-dev at lists.llvm.org> wrote:> On 6/3/2016 11:15 PM, Dylan McKay via llvm-dev wrote: > >> >> I can’t figure out how I can glue all these nodes together and return >> the nonatomic load. >> > > Hi Dylan, > > As Anton said, you would need to use glue values. A node would take a > glue as the last operand. That is the input glue, and will cause the node > to be glued to the node that produced it. The output glue is one of the > SDValues returned by the node (you can find out which one by looking at the > dump). > > The DAG usually like this: > > Glue0 = MVT::Glue > (..., Glue1, ...) = ISD::SOME_NODE_0 Op0, Op1, ..., Glue0 > (..., Glue2, ...) = ISD::SOME_NODE_1 Op0, Op1, ..., Glue1 > > SOME_NODE_n would be created giving it MVT::Glue as the type of the last > operand. The problem is that getLoad does not accept glue operands, so > there isn't an easy way to use it with loads, which, I think, is the > problem you ran into. > > > If you want to have these nodes stick together, using glue may not be > sufficient. After the machine instructions are generated, the scheduler > may place instructions between the interrupt disable/restore and the atomic > load itself. Also, the register allocator may insert some spills > there---there are ways that this sequence may get separated. > > For this, the best approach may be to define a pseudo-instruction, which > will be expanded into real instruction in the post-RA expansion pass. > > > If you need it only for the DAG nodes, you could try to manufacture your > own load via the generic getNode, forcing glue into it, but that may be > more effort than it's worth. Maybe lowering it into your target-specific > node would be the best approach after all? > > -Krzysztof > > > -- > Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted > by The Linux Foundation > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20160610/5956d3bc/attachment.html>