<div dir="ltr">Hi Arnaud,<div><br></div><div>The conservatively allocatable test is supposed to check two conditions, either of which would be sufficient to make a node allocatable:</div><div><br></div><div>(1) There exists some register that is not aliased by any register option for any neighbor. This is the "safe row" test. It is straightforward, but likely to fire only rarely. </div><div><br></div><div>(2) The sum of the maximum number of registers aliased by any register for each neighbor is less than the number of available registers for this node. This is the "worst-column" test. More intuitively: for each neighbor you compute the maximum number of registers that could be "taken" from this node by an allocation to that neighbor. If you assume (conservatively) that none of these "taken" registers alias one another then you can sum them to find the maximum number of registers that might be unavailable to this node. If this sum is lower than the number of registers available then you're safely allocatable.</div><div><br></div><div>Cheers,</div><div>Lang.</div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Jan 26, 2015 at 11:42 PM, Arnaud A. de Grandmaison <span dir="ltr"><<a href="mailto:arnaud.degrandmaison@arm.com" target="_blank">arnaud.degrandmaison@arm.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div lang="EN-GB" link="blue" vlink="purple"><div><span class=""><p class="MsoNormal"><span style="font-size:11.5pt;font-family:"Calibri","sans-serif"">> A node should never be put into the conservatively allocatable list if there is a chance of it spilling.</span><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d"><u></u><u></u></span></p><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d"><u></u> <u></u></span></p></span><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">I can understand why the logic of NodeMetadata::isConservativelyAllocatable is necessary for the node to be allocatable, but I have not been able to convince myself this is sufficient, especially when the node degree > available registers.<u></u><u></u></span></p><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d"><u></u> <u></u></span></p><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">Cheers,<u></u><u></u></span></p><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">Arnaud<u></u><u></u></span></p><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d"><u></u> <u></u></span></p><p class="MsoNormal" style="margin-left:36.0pt"><b><span lang="EN-US" style="font-size:10.0pt;font-family:"Tahoma","sans-serif"">From:</span></b><span lang="EN-US" style="font-size:10.0pt;font-family:"Tahoma","sans-serif""> <a href="mailto:llvmdev-bounces@cs.uiuc.edu" target="_blank">llvmdev-bounces@cs.uiuc.edu</a> [mailto:<a href="mailto:llvmdev-bounces@cs.uiuc.edu" target="_blank">llvmdev-bounces@cs.uiuc.edu</a>] <b>On Behalf Of </b>Lang Hames<br><b>Sent:</b> 27 January 2015 06:06<br><b>To:</b> Jonas Paulsson<br><b>Cc:</b> <a href="mailto:llvmdev@cs.uiuc.edu" target="_blank">llvmdev@cs.uiuc.edu</a><br><b>Subject:</b> Re: [LLVMdev] PBQP crash<u></u><u></u></span></p><div><div class="h5"><p class="MsoNormal" style="margin-left:36.0pt"><u></u> <u></u></p><div><p class="MsoNormal" style="margin-left:36.0pt">Hi Jonas,<u></u><u></u></p><div><p class="MsoNormal" style="margin-left:36.0pt"><u></u> <u></u></p></div><div><p class="MsoNormal" style="margin-left:36.0pt"><span style="font-size:11.5pt;font-family:"Calibri","sans-serif"">> * The problematic node that was spilled again, was in the ConservativelyAllocatableNodes set during reduce(). The comment in reduce() “Conservatively allocatable nodes will never spill…” indicates that perhaps this is an incorrect insertion, as the regs did in fact run out in this case.</span><u></u><u></u></p></div><div><p class="MsoNormal" style="margin-left:36.0pt"><u></u> <u></u></p></div><div><p class="MsoNormal" style="margin-left:36.0pt"><span style="font-size:11.5pt;font-family:"Calibri","sans-serif"">Arnaud is correct: A node should never be put into the conservatively allocatable list if there is a chance of it spilling. Off the top of my head I can imagine 2 things going wrong here:</span><u></u><u></u></p></div><div><p class="MsoNormal" style="margin-left:36.0pt"><u></u> <u></u></p></div><div><p class="MsoNormal" style="margin-left:36.0pt"><span style="font-size:11.5pt;font-family:"Calibri","sans-serif"">(1) Conservative allocability is mostly-precomputed, and updated with deltas as nodes are removed. It is possible that there is some subtle bug in this code.</span><u></u><u></u></p></div><div><p class="MsoNormal" style="margin-left:36.0pt"><u></u> <u></u></p></div><div><p class="MsoNormal" style="margin-left:36.0pt"><span style="font-size:11.5pt;font-family:"Calibri","sans-serif"">(2) I think the current conservative allocability test bakes in the assumption that all register options have non-infinite cost. If you assign infinite costs to any physical register I would expect this to blow up.</span><u></u><u></u></p></div><div><p class="MsoNormal" style="margin-left:36.0pt"><u></u> <u></u></p></div><div><p class="MsoNormal" style="margin-left:36.0pt"><span style="font-size:11.5pt;font-family:"Calibri","sans-serif"">Are you able to share a test case at all? If so that would be great. If not, I can add an option to the allocator to dump abstract PBQP graphs, and I could use these to test the problem on my end.</span><u></u><u></u></p></div><div><p class="MsoNormal" style="margin-left:36.0pt"><u></u> <u></u></p></div><div><p class="MsoNormal" style="margin-left:36.0pt"><span style="font-size:11.5pt;font-family:"Calibri","sans-serif"">Regards,</span><u></u><u></u></p></div><div><p class="MsoNormal" style="margin-left:36.0pt"><span style="font-size:11.5pt;font-family:"Calibri","sans-serif"">Lang.</span><u></u><u></u></p></div><div><p class="MsoNormal" style="margin-left:36.0pt"><u></u> <u></u></p></div></div><div><p class="MsoNormal" style="margin-left:36.0pt"><u></u> <u></u></p><div><p class="MsoNormal" style="margin-left:36.0pt">On Mon, Jan 26, 2015 at 7:55 AM, Jonas Paulsson <<a href="mailto:jonas.paulsson@ericsson.com" target="_blank">jonas.paulsson@ericsson.com</a>> wrote:<u></u><u></u></p><div><div><p class="MsoNormal" style="margin-left:36.0pt"><span lang="SV">Hi,</span><span lang="EN-US"><u></u><u></u></span></p><p class="MsoNormal" style="margin-left:36.0pt"><span lang="SV"> </span><span lang="EN-US"><u></u><u></u></span></p><p class="MsoNormal" style="margin-left:36.0pt"><span lang="EN-US">I have run into a test case on an out-of-tree target where PBQP fails to complete register allocation after “Attempting to spill already spilled value” (the triggered assert in InlineSpiller::spill().<u></u><u></u></span></p><p class="MsoNormal" style="margin-left:36.0pt"><span lang="EN-US"> <u></u><u></u></span></p><p class="MsoNormal" style="margin-left:36.0pt"><span lang="EN-US">First, the original LiveInterval is spilled. It is a load of a symbol into a narrow register class, i.e. a subset of the class of address registers. InlineSpiller decides to rematerialize the load of the symbol to lie right before its only user, which makes good sense. The original def is removed.<u></u><u></u></span></p><p class="MsoNormal" style="margin-left:36.0pt"><span lang="EN-US"> <u></u><u></u></span></p><p class="MsoNormal" style="margin-left:36.0pt"><span lang="EN-US">The new LiveInterval pushed is thus much smaller in the next PBQP round. The spill cost is marked as ‘inf’ during graph building. This small interval has also a lot of overlapping intervals and thus edges in the PBQP graph. It gets pushed on the node stack to later be popped after 17 others.<u></u><u></u></span></p><p class="MsoNormal" style="margin-left:36.0pt"><span lang="EN-US">Those 17 nodes use up all registers of the narrow reg-class, and the cost vector has become all infinities. Spill option is selected again, and thus the error is a fact of spilling an already spilled value.<u></u><u></u></span></p><p class="MsoNormal" style="margin-left:36.0pt"><span lang="EN-US"> <u></u><u></u></span></p><p class="MsoNormal" style="margin-left:36.0pt"><span lang="EN-US">I wonder what has gone wrong here, and have some initial thoughts:<u></u><u></u></span></p><p class="MsoNormal" style="margin-left:36.0pt"><span lang="EN-US"> <u></u><u></u></span></p><p class="MsoNormal" style="margin-left:36.0pt"><span lang="EN-US">* The problematic node that was spilled again, was in the ConservativelyAllocatableNodes set during reduce(). The comment in reduce() “Conservatively allocatable nodes will never spill…” indicates that perhaps this is an incorrect insertion, as the regs did in fact run out in this case.<u></u><u></u></span></p><p class="MsoNormal" style="margin-left:36.0pt"><span lang="EN-US">   In setup(), the node is first put into not-provably-allocatables. However, one of it’s neigbhour invoked handleDisconnectEdge(), and moves it into conservatively-allocatables, because DeniedOpts had become less than NumOpts (in isConservativelyAllocatable().<u></u><u></u></span></p><p class="MsoNormal" style="margin-left:36.0pt"><span lang="EN-US">* There are lots of spillable nodes being popped before the one that can’t be spilled.  This seems intuitively wrong, as they are intervals that actually could be spilled.<u></u><u></u></span></p><p class="MsoNormal" style="margin-left:36.0pt"><span lang="EN-US"> <u></u><u></u></span></p><p class="MsoNormal" style="margin-left:36.0pt"><span lang="EN-US">I would really appreciate some help and pointers on what might be going wrong here,<u></u><u></u></span></p><p class="MsoNormal" style="margin-left:36.0pt"><span lang="EN-US" style="color:#888888"> <u></u><u></u></span></p><p class="MsoNormal" style="margin-left:36.0pt"><span lang="EN-US" style="color:#888888">Jonas Paulsson<u></u><u></u></span></p><p class="MsoNormal" style="margin-left:36.0pt"><span lang="EN-US" style="color:#888888"> <u></u><u></u></span></p></div></div></div><p class="MsoNormal" style="margin-left:36.0pt"><u></u> <u></u></p></div></div></div></div></div></blockquote></div><br></div>