<div dir="auto"><div>I dont know the history behind CostPerUse word so I may be missing the background associated with it. It seems that it's misnomer for what it is intended. At first sight, the word indicates that the cost is a function of uses of the register - more the uses more the cost. How do we want to define the value of CostPerUse. Should it be a function of uses? or just the target? </div><div dir="auto"><br><br><div class="gmail_quote" dir="auto"><div dir="ltr" class="gmail_attr">On Sat, May 30, 2020, 4:53 PM Devadasan, Christudasan via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org" target="_blank" rel="noreferrer">llvm-dev@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">





<div lang="EN-US" link="#0563C1" vlink="#954F72">
<div>
<p style="margin:0in;margin-bottom:.0001pt"><span style="font-size:10.0pt;font-family:"Arial",sans-serif;color:#0078d7">[AMD Official Use Only - Internal Distribution Only]</span><u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">Please ignore the header “AMD Official Use Only”. I forgot to remove it while posting the email to llvm-dev.<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">Regards,<u></u><u></u></p>
<p class="MsoNormal">Christudasan<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<div>
<div style="border:none;border-top:solid #e1e1e1 1.0pt;padding:3.0pt 0in 0in 0in">
<p class="MsoNormal"><b>From:</b> Devadasan, Christudasan <br>
<b>Sent:</b> Friday, May 29, 2020 7:46 PM<br>
<b>To:</b> <a href="mailto:llvm-dev@lists.llvm.org" rel="noreferrer noreferrer" target="_blank">llvm-dev@lists.llvm.org</a><br>
<b>Subject:</b> [llvm-dev] Dynamically determine the CostPerUse value in the register allocator.<u></u><u></u></p>
</div>
</div>
<p class="MsoNormal"><u></u> <u></u></p>
<p style="margin:0in;margin-bottom:.0001pt"><span style="font-size:10.0pt;font-family:"Arial",sans-serif;color:#0078d7">[AMD Official Use Only - Internal Distribution Only]</span><u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">Hi All,<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">For the AMDGPU architecture, during RA, we prefer to have a cost associated with the registers (CostPerUse) based on a target entity (for instance, the Calling Convention of the current MachineFunction).<u></u><u></u></p>
<p class="MsoNormal">Presently CostPerUse is a one-time static value (either zero or a positive value) generated through table-gen.<u></u><u></u></p>
<p class="MsoNormal">The current implementation doesn’t allow us to control the reg-cost on the fly.<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">The AMDGPU ABI has recently been revised by introducing more caller-saved VGPRs (the exact details are explained towards the end of this e-mail), and found that having a dynamic register cost is important to achieve an optical allocation.
<u></u><u></u></p>
<p class="MsoNormal">Precisely, it is important to limit the number of VGPRs allocated for a kernel/device-function to a smallest value since it will have a direct impact on the occupancy. The occupancy means the number of wavefronts that can be launched at
 runtime for a kernel program.<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">Some initial thoughts on how to fix it:<u></u><u></u></p>
<ol style="margin-top:0in" start="1" type="1">
<li style="margin-left:0in">Have a target interface (a switch) to enable/discard the CostPerUse value.<u></u><u></u></li><li style="margin-left:0in">Get the register cost in the same way we define various calling conventions (*CallingConv.td).<u></u><u></u></li><li style="margin-left:0in">Compute the CostPerUse in the way the AllocationOrder for the registers is determined during RA.<u></u><u></u></li></ol>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">The first one is the easiest method and that solves the immediate problem we currently address.<u></u><u></u></p>
<p class="MsoNormal">However, the other two options are better if we want to associate different reg-cost values for different calling conventions (I presume, it will arise at some point).
<u></u><u></u></p>
<p class="MsoNormal">Other than these options, there can be a better way to fix it. Any suggestion in this regard would be helpful.
<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">AMDGPU ABI changes and the motivation for this discussion:<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">Before the new ABI change:<u></u><u></u></p>
<p class="MsoNormal" style="text-indent:.5in">Apart from the initial reserved 32 argument registers, all VGPRs are callee-saved registers (VGPR32 - VGPR255).<u></u><u></u></p>
<p class="MsoNormal">With the new ABI:<u></u><u></u></p>
<p class="MsoNormal" style="margin-left:.5in">We made VGPR32 - VGPR255 into equal number of callee-saved and caller-saved registers.<u></u><u></u></p>
<p class="MsoNormal" style="margin-left:.5in">For the same occupancy reason, these two sets are interleaved at a split boundary of 8.<u></u><u></u></p>
<p class="MsoNormal" style="margin-left:1.0in">VGPR32-VGPR39 (Caller-saved)<u></u><u></u></p>
<p class="MsoNormal" style="margin-left:1.0in">VGPR40-VGPR47 (Callee-saved)<u></u><u></u></p>
<p class="MsoNormal" style="margin-left:1.0in">VGPR48-VGPR55 (Caller-saved)<u></u><u></u></p>
<p class="MsoNormal" style="margin-left:1.0in">              -<u></u><u></u></p>
<p class="MsoNormal" style="margin-left:1.0in">              -<u></u><u></u></p>
<p class="MsoNormal" style="margin-left:1.0in">VGPR248-VGPR255 (Callee-saved)<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">With the new ABI, the allocator’s preference for callee-saved vs caller-saved depends on the input program.
<u></u><u></u></p>
<p class="MsoNormal">RA may end up allocating more caller-saved registers than the callee-saved in certain cases. The other way of allocation is possible too (more callee-saved registers)<u></u><u></u></p>
<p class="MsoNormal">In either case, there will be unallocated registers left behind, bumping up the final VGPRs into a considerable number. It will have a bad impact on the occupancy.<u></u><u></u></p>
<p class="MsoNormal">To override the default allocation preferences of RA, we tried to set a cost for all VGPRs such that the higher indices will have higher cost.
<u></u><u></u></p>
<p class="MsoNormal">It eliminated the problem by allocating all lower registers before picking the higher one, and with an expense of some spills in certain cases which is acceptable.
<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">But for the kernels with no device-function calls, the register cost is unnecessary. Because there is no ABI for such kernel programs.<u></u><u></u></p>
<p class="MsoNormal">It caused a performance penalty for such kernels due to the register cost.<u></u><u></u></p>
<p class="MsoNormal">That’s the exact reason we need a method to determine dynamically either to have a reg-cost or not to have one.<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">Regards,<u></u><u></u></p>
<p class="MsoNormal">Christudasan<u></u><u></u></p>
</div>
</div>

_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:llvm-dev@lists.llvm.org" rel="noreferrer noreferrer" target="_blank">llvm-dev@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer noreferrer noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br>
</blockquote></div>
</div></div>