Tyler Kenney via llvm-dev
2016-Aug-23 13:58 UTC
[llvm-dev] Help in understanding physreg LiveVariables
<div class="socmaildefaultfont" dir="ltr" style="font-family:Arial;font-size:10.5pt" ><div class="socmaildefaultfont" dir="ltr" style="font-family:Arial;font-size:10.5pt" ><div dir="ltr" > </div> <div dir="ltr" >Hi all,</div> <div dir="ltr" > </div> <div dir="ltr" > </div> <div dir="ltr" >The documentation at the top of LiveVariables.cpp states the following:<br><br> "It ... assumes that physical registers are only live within a single basic block (allowing it to do a single local analysis to resolve physical register lifetimes in each basic block). If a physical register is not register allocatable, it is not tracked. "</div> <div dir="ltr" > </div> <div dir="ltr" >This is consistent with the behaviour I'm witnessing, but I don't understand why it's designed this way. I am developing an out-of-tree backend and I have the following scenario:</div> <div dir="ltr" > </div> <div dir="ltr" > -physreg X marked as a live-in for a successor MBB (A.K.A., a live-out of the current block)<br> -physreg X is a member of an allocatable reg-class<br> -the only reference to physreg X in the current block is a<strong>: %physregX<def> = COPY %vreg43<kill></strong></div> <div dir="ltr" > </div> <div dir="ltr" >That is the IR immediately before the Live Variables pass. The problem is that LiveVariables is marking physregX as dead, meaning that after LiveVariables, the IR above becomes:</div> <div dir="ltr" > </div> <div dir="ltr" > </div> <div dir="ltr" > <strong>%physregX<def,dead> = COPY %vreg43<kill></strong></div> <div dir="ltr" > </div> <div dir="ltr" > </div> <div dir="ltr" >...and this eventually causes the COPY to be eliminated rather than lowered to machine instructions. Why does LiveVariables assume physical registers are only live within a single basic block? I have confirmed that if I remove the allocatable check in runOnBlock() [if (!TRI->isInAllocatableClass(LI.PhysReg))] and instead add all successor live-ins to LiveOuts regardless of regclass allocatability, my copy is not marked dead and not subsequently eliminated. This seems consistent with the aforementioned comment, so I don't think it's a bug but I really don't understand the intention here. If anyone could shed some light on why allocatable live-in's are pretty much ignored here, that'd be really helpful.</div> <div dir="ltr" > </div> <div dir="ltr" >Thanks in advance,</div> <div dir="ltr" >Tyler</div> <div dir="ltr" > </div></div></div><BR>
Matthias Braun via llvm-dev
2016-Aug-23 18:46 UTC
[llvm-dev] Help in understanding physreg LiveVariables
> On Aug 23, 2016, at 6:58 AM, Tyler Kenney via llvm-dev <llvm-dev at lists.llvm.org> wrote: > > > Hi all, > > > The documentation at the top of LiveVariables.cpp states the following: > > "It ... assumes that physical registers are only live within a single basic block (allowing it to do a single local analysis to resolve physical register lifetimes in each basic block). If a physical register is not register allocatable, it is not tracked. " > > This is consistent with the behaviour I'm witnessing, but I don't understand why it's designed this way. I am developing an out-of-tree backend and I have the following scenario: > > -physreg X marked as a live-in for a successor MBB (A.K.A., a live-out of the current block) > -physreg X is a member of an allocatable reg-class > -the only reference to physreg X in the current block is a: %physregX<def> = COPY %vreg43<kill> > > That is the IR immediately before the Live Variables pass. The problem is that LiveVariables is marking physregX as dead, meaning that after LiveVariables, the IR above becomes: > > > %physregX<def,dead> = COPY %vreg43<kill> > > > ...and this eventually causes the COPY to be eliminated rather than lowered to machine instructions. Why does LiveVariables assume physical registers are only live within a single basic block? I have confirmed that if I remove the allocatable check in runOnBlock() [if (!TRI->isInAllocatableClass(LI.PhysReg))] and instead add all successor live-ins to LiveOuts regardless of regclass allocatability, my copy is not marked dead and not subsequently eliminated. This seems consistent with the aforementioned comment, so I don't think it's a bug but I really don't understand the intention here. If anyone could shed some light on why allocatable live-in's are pretty much ignored here, that'd be really helpful.The long term plan is to get rid of LiveVariables and use LiveIntervalAnalysis for everything. However the TwoAddressInstructionPass has never been converted properly (some code was added to that pass to deal with LiveIntervals but the work was never completed so this is currently broken). If someone could get this working we could finally get rid of LiveVariables... However apart from the LiveVariables situation I would expect the assumption that physregs are only live within a basic block to be a valid one. What stops you to immediate copy the physregs from/to a virtual register for each use/def? That also gives the register allocator more freedom. If on the other hand a value must be in a register even though there are no apparent def/use operand then you probably have something on your hand that should be marked as non-allocatable or better reserved. - Matthias -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20160823/c6818840/attachment.html>
Tyler Kenney via llvm-dev
2016-Aug-23 20:38 UTC
[llvm-dev] Help in understanding physreg LiveVariables
<div class="socmaildefaultfont" dir="ltr" style="font-family:Arial;font-size:10.5pt" ><div dir="ltr" style="font-family:Arial;font-size:10.5pt" ><div dir="ltr" >Matthias,</div> <div dir="ltr" > </div> <div dir="ltr" >Thanks for the response.</div> <div dir="ltr" > </div> <div dir="ltr" >In short, I'm using physregs because my current design, in some cases, needs to create an entirely new var/reg during instruction legalization. This value can be passed from one basic block to another and, therefore, must be added as a live-in to a number of basic blocks. I was unable to find a way to add a virt reg as a live-in to an MBB, thus the need for physregs. I asked about adding new inputs & outputs to basic blocks during instruction legalization/selection earlier on:</div> <div dir="ltr" > </div> <div dir="ltr" ><a href="http://lists.llvm.org/pipermail/llvm-dev/2016-June/100387.html" >http://lists.llvm.org/pipermail/llvm-dev/2016-June/100387.html</a></div> <div dir="ltr" > </div> <div dir="ltr" >Tim Northover responded with some useful insight but I did not really get a direct answer to my question on how to add MBB inputs (or if it's possible). The solution that I developed myself is to use virtual registers within MBBs and build CopyFrom/ToReg nodes at the BB boundaries with a physreg number, then add this physreg as a live-in where appropriate. This has been working for a few weeks now and, until I discovered this new issue where my live-in is ignored, had no known issues.</div> <div dir="ltr" > </div> <div dir="ltr" >So, to answer your question, what stops me from copying the physreg to a virtual register after the last def (and also stops me from avoiding pre-RA physregs entirely) is that I do not know how to add a virt reg live-in (and ensure the proper phi nodes get updated/created).</div> <div dir="ltr" > </div> <div dir="ltr" >If it's assumed that allocatable (and unreserved) PhysRegs are only live within a basic block, why is it possible to add such a physreg as an MBB live-in? Should there be an assertion added to MachineBasicBlock::addLiveIn() ?</div> <div dir="ltr" > </div> <div dir="ltr" >Tyler</div> <div dir="ltr" > </div> <div dir="ltr" > </div> <blockquote data-history-content-modified="1" dir="ltr" style="border-left:solid #aaaaaa 2px; margin-left:5px; padding-left:5px; direction:ltr; margin-right:0px" >----- Original message -----<br>From: mbraun@apple.com<br>To: Tyler Kenney/Marlborough/IBM@IBMUS<br>Cc: llvm-dev@lists.llvm.org<br>Subject: Re: [llvm-dev] Help in understanding physreg LiveVariables<br>Date: Tue, Aug 23, 2016 2:47 PM<br> <br><!--Notes ACF <meta http-equiv="Content-Type" content="text/html charset=utf8" >--> <div><blockquote type="cite" ><div>On Aug 23, 2016, at 6:58 AM, Tyler Kenney via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org" target="_blank" >llvm-dev@lists.llvm.org</a>> wrote:</div> <div><div dir="ltr" style="font-family:Arial;font-size:10.5pt" ><div dir="ltr" style="font-family:Arial;font-size:10.5pt" ><div dir="ltr" > </div> <div dir="ltr" >Hi all,</div> <div dir="ltr" > </div> <div dir="ltr" > </div> <div dir="ltr" >The documentation at the top of LiveVariables.cpp states the following:<br><br> "It ... assumes that physical registers are only live within a single basic block (allowing it to do a single local analysis to resolve physical register lifetimes in each basic block). If a physical register is not register allocatable, it is not tracked. "</div></div></div></div></blockquote> <blockquote type="cite" ><div><div dir="ltr" style="font-family:Arial;font-size:10.5pt" ><div dir="ltr" style="font-family:Arial;font-size:10.5pt" ><div dir="ltr" > </div> <div dir="ltr" >This is consistent with the behaviour I'm witnessing, but I don't understand why it's designed this way. I am developing an out-of-tree backend and I have the following scenario:</div> <div dir="ltr" > </div> <div dir="ltr" > -physreg X marked as a live-in for a successor MBB (A.K.A., a live-out of the current block)<br> -physreg X is a member of an allocatable reg-class<br> -the only reference to physreg X in the current block is a<strong>: %physregX<def> = COPY %vreg43<kill></strong></div> <div dir="ltr" > </div> <div dir="ltr" >That is the IR immediately before the Live Variables pass. The problem is that LiveVariables is marking physregX as dead, meaning that after LiveVariables, the IR above becomes:</div> <div dir="ltr" > </div> <div dir="ltr" > </div> <div dir="ltr" > <strong>%physregX<def,dead> = COPY %vreg43<kill></strong></div> <div dir="ltr" > </div> <div dir="ltr" > </div> <div dir="ltr" >...and this eventually causes the COPY to be eliminated rather than lowered to machine instructions. Why does LiveVariables assume physical registers are only live within a single basic block? I have confirmed that if I remove the allocatable check in runOnBlock() [if (!TRI->isInAllocatableClass(LI.PhysReg))] and instead add all successor live-ins to LiveOuts regardless of regclass allocatability, my copy is not marked dead and not subsequently eliminated. This seems consistent with the aforementioned comment, so I don't think it's a bug but I really don't understand the intention here. If anyone could shed some light on why allocatable live-in's are pretty much ignored here, that'd be really helpful.</div></div></div></div></blockquote> <div> </div> <div>The long term plan is to get rid of LiveVariables and use LiveIntervalAnalysis for everything. However the TwoAddressInstructionPass has never been converted properly (some code was added to that pass to deal with LiveIntervals but the work was never completed so this is currently broken). If someone could get this working we could finally get rid of LiveVariables...</div> <div> </div> <div>However apart from the LiveVariables situation I would expect the assumption that physregs are only live within a basic block to be a valid one. What stops you to immediate copy the physregs from/to a virtual register for each use/def? That also gives the register allocator more freedom. If on the other hand a value must be in a register even though there are no apparent def/use operand then you probably have something on your hand that should be marked as non-allocatable or better reserved.</div> <div> </div> <div>- Matthias</div> <div> </div></div></blockquote> <div dir="ltr" > </div></div></div><BR>
Apparently Analagous Threads
- Help in understanding physreg LiveVariables
- Help in understanding physreg LiveVariables
- Help in understanding physreg LiveVariables
- [LLVMdev] implicit CC register Defs cause "physreg was not killed in defining block!" assert
- [LLVMdev] implicit CC register Defs cause "physreg was not killed in defining block!" assert