<div dir="ltr">Dear Community,<div><br></div><div>Sorry for being late for weekly status.</div><div><br></div><div>Please find summary for this week as below:</div><div><br></div><div>Implementation</div><div>============</div><div><p style="margin:0px;line-height:normal;font-family:Helvetica">This week I have implemented support for __attribute__((regmask(“clobbered list here”))). This currently applicable to function declaration only and it provides user a chance to help IPRA by specifying actual register usage by a function which is currently not declared in the module. One such case is when functions written in pure assembly is used inside current module because in such a case if this attribute is not present IPRA will use CC so it will limit performance benefits from IPRA. Alternatively in this particular case one can use preserve_all or preserve_most attribute specified with clang to help IPRA but I believe in some case user may not be able to describe register usage with such CC then attribute “regmask” can help.</p>
<p style="margin:0px;line-height:normal;font-family:Helvetica">For this support I needed to hack clang and LLVM both. How ever it seems that applicability of this kind of attribute is not limited to IPRA so we have initiated discussion on mailing list <a href="https://groups.google.com/d/topic/llvm-dev/w70_WljNCHE/discussion">https://groups.google.com/d/topic/llvm-dev/w70_WljNCHE/discussion</a>.</p>
<p style="margin:0px;line-height:normal;font-family:'Helvetica Neue'">I have also implemented a patch which fixes a very subtle bug in regmask calculation. Thanks to zan jyu Wong <<a href="mailto:zyfwong@gmail.com">zyfwong@gmail.com</a>> for bringing this to notice.</p>
<p style="margin:0px;line-height:normal;font-family:'Helvetica Neue'">For example if CL is only clobbered than CH should not be marked clobbered but CX, RCX and ECX should be mark clobbered. Previously for each modified register all of its aliases are marked clobbered by markRegClobbred() in RegUsageInfoCollector.cpp but that is wrong because when CL is clobbered then MRI::isPhysRegModified() will return true for CL, CX, ECX, RCX which is correct behavior but then for CX, EXC, RCX we mark CH also clobbered as CH is aliased to CX,ECX,RCX so markRegClobbred() is not required because isPhysRegModified already take cares of proper aliasing register. A very simple test case has been added to verify this change.</p><p style="margin:0px;line-height:normal;font-family:'Helvetica Neue'"><br></p><p style="margin:0px;line-height:normal;font-family:'Helvetica Neue'">Testing</p><p style="margin:0px;line-height:normal;font-family:'Helvetica Neue'">=====</p><p style="margin:0px;line-height:normal;font-family:Helvetica">This week I run test-suite with —benchmark-only flag and on average 4% improvement is noted in execution time how ever on average 5% increment is noted in compile time. </p><p style="margin:0px;line-height:normal;font-family:Helvetica"><br></p><p style="margin:0px;line-height:normal;font-family:Helvetica">Study</p><p style="margin:0px;line-height:normal;font-family:Helvetica">====</p><p style="margin:0px;line-height:normal;font-family:Helvetica">For PGO driven IPRA I am able to access profile summary info in LLVM pass to decide if function is hot or cold but to implement it target independently I also need to determine if function is hot or cold inside a TargetFrameLowringImpl but my attempts failed I will look for other ways to solve this problem<span style="font-size:10.9px">.</span></p><p style="margin:0px;line-height:normal;font-family:Helvetica"><span style="font-size:10.9px"><br></span></p><p style="margin:0px;line-height:normal;font-family:Helvetica">Plan for next week</p><p style="margin:0px;line-height:normal;font-family:Helvetica">==============</p><p style="margin:0px;line-height:normal;font-family:Helvetica">1) Work to improve attribute regmask support as per suggestion on RFC.</p><p style="margin:0px;line-height:normal;font-family:Helvetica">2) Implement experiment PGO driven IPRA</p><p style="margin:0px;line-height:normal;font-family:Helvetica"><br></p><p style="margin:0px;line-height:normal;font-family:Helvetica">Sincerely,</p><p style="margin:0px;line-height:normal;font-family:Helvetica">Vivek</p></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Sun, Jul 10, 2016 at 10:12 AM, vivek pandya <span dir="ltr"><<a href="mailto:vivekvpandya@gmail.com" target="_blank">vivekvpandya@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hello LLVM Developers,<div><br></div><div>Please feel free to send any ideas that you can think to improve current IPRA. I will work on it and if possible I will implement that.</div><div><br></div><div>Please consider summary of work done during this week.</div><div><br></div><div>Implementation:</div><div>============</div><div><p style="margin:0px;line-height:normal;font-family:Helvetica">The reviews requests has been updated to reflect the reviews.</p><p style="margin:0px;line-height:normal;font-family:Helvetica"><br></p><p style="margin:0px;line-height:normal;font-family:Helvetica">Testing:</p><p style="margin:0px;line-height:normal;font-family:Helvetica">=====</p><p style="margin:0px;line-height:normal;font-family:Helvetica">To get more benefit from IPRA I experimented it with LTO and results were positive. For the SPASS application (one of the multi source benchmark in test suite) execution time is reduce by 0.02s when LTO+IPRA compare to LTO only. The current IPRA works at compile time and its optimization scope is limited to a module so LTO produces a large module from small modules then generates machine code for that. So it will help IPRA by providing a huge module with very less external functions. to use IPRA with LTO one can pass following arguments to clang : -flto -Wl,-mllvm,-enable-ipra . A more detailed discussion can be found here <a href="https://groups.google.com/d/topic/llvm-dev/Vkd-NOytdcA/discussion" target="_blank">https://groups.google.com/d/topic/llvm-dev/Vkd-NOytdcA/discussion</a></p><p style="margin:0px;line-height:normal;font-family:Helvetica"><br></p><p style="margin:0px;line-height:normal;font-family:Helvetica">Study:</p><p style="margin:0px;line-height:normal;font-family:Helvetica">=====</p><p style="margin:0px;line-height:normal;font-family:Helvetica">Majority of time I have spent on finding new ideas to improve current IPRA. As current approach can only see information with in current module it is very hard to improve it further. Most of the approaches described in literatures requirers help from a program analyzer and intra-procedural register allocation and register allocation for the whole module is differed until IPRA is completed. Also these approaches requires a heavy data flow analysis so that is totally orthogonal to current approach. But still we am able to identified two possible improvements and many thanks to Peter Lawrence for his suggestions and questions. </p><p style="margin:0px;line-height:normal;font-family:Helvetica">
</p><ol>
<li style="margin:0px;line-height:normal;font-family:Helvetica"><span style="line-height:normal"></span>First improvement is to help IPRA by using __attribute__. This can be particularly use full when working with a library or external code which is written completely in assembly and a user is able to provide accurate register usage information. So idea is to supply regmask details for such external function with __attribute__ in function declaration and let IPRA propagate it to improve register allocation.  I will be working on this next week.</li>
<li style="margin:0px;line-height:normal;font-family:Helvetica"><span style="line-height:normal"></span>Second improvement is to make less frequently executed function save every register it clobbers thus making it preserving all registers and propagating this information to more frequently executed callers to improve its register allocation. This leads us to PGO driven IPRA. More details can be found here. <a href="https://groups.google.com/d/topic/llvm-dev/jhC7L50el8k/discussion" target="_blank">https://groups.google.com/d/topic/llvm-dev/jhC7L50el8k/discussion</a></li></ol></div><div class="gmail_extra">Plan for Next Week:</div><div class="gmail_extra">===============</div><div class="gmail_extra">1) Start implementing above two improvements.</div><div class="gmail_extra">2) Run test-suite with --benchmark option so that more precisely  improvement can be calculated.</div><div class="gmail_extra"><br></div><div class="gmail_extra">Sincerely,</div><div class="gmail_extra">Vivek</div><div><div class="h5"><div class="gmail_extra"><br><div class="gmail_quote">On Sun, Jul 3, 2016 at 5:43 PM, vivek pandya <span dir="ltr"><<a href="mailto:vivekvpandya@gmail.com" target="_blank">vivekvpandya@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hello LLVM Developers.<div><br></div><div>This week much of my time is consumed in debugging IPRA's effect on higher level optimization specifically due to not having callee saved registers. I think it was hard but I learned a lot and LLDB helped me a lot. </div><div><br></div><div>Here is summary for this week:</div><div><br></div><div>Implementation:</div><div>============</div><div><p style="margin:0px;line-height:normal;font-family:Helvetica">Implemented a very simple check to prevent no callee saved registers optimization to functions which are recursive or may be optimized as tail call. A simple statistic added to count number of functions optimized for not having callee saved registers.</p><p style="margin:0px;line-height:normal;font-family:Helvetica"><br></p><p style="margin:0px;line-height:normal;font-family:Helvetica">Testing:</p><p style="margin:0px;line-height:normal;font-family:Helvetica">======</p><p style="margin:0px;line-height:normal;font-family:Helvetica">Debugged failing test cases due to no callee saved registers optimization. More details with examples can be found here <a href="https://groups.google.com/d/topic/llvm-dev/TSoYxeMMzxM/discussion" target="_blank">https://groups.google.com/d/topic/llvm-dev/TSoYxeMMzxM/discussion</a> . Now all test in llvm test-suite pass.</p><p style="margin:0px;line-height:normal;font-family:Helvetica"><br></p><p style="margin:0px;line-height:normal;font-family:Helvetica">Study:</p><p style="margin:0px;line-height:normal;font-family:Helvetica">=====</p><p style="margin:0px;line-height:normal;font-family:Helvetica">To find some ideas to improve current IPRA I read 2 papers namely “Minimizing Register Usage Penalty at Procedure Calls” by Fred C. Chow and “Register Allocation Across Procedure and Module Boundaries” by Santhanam and Odnert. </p><p style="margin:0px;line-height:normal;font-family:Helvetica">1) From the first paper I like the idea of shrink wrap analysis and LLVM currently have this optimization but the approach is completely different. I have initiated a discussion for that, it can be found here <a href="https://groups.google.com/d/topic/llvm-dev/_mZoGUQDMGo/discussion" target="_blank">https://groups.google.com/d/topic/llvm-dev/_mZoGUQDMGo/discussion</a> I would like to talk to Quentin Colombet more about this.</p><p style="margin:0px;line-height:normal;font-family:Helvetica"></p><p style="margin:0px;line-height:normal;font-family:Helvetica">2) From the second paper I like the idea of spill code motion, in this optimization spill due to callee saved register is pushed to less frequently called caller, but the approach mentioned in that paper requiems call frequency details and also it differs register allocation to very late, the optimization it self requires register usage details but it operates on register usage estimation done in earlier stage. This optimization also requires help from intra-procedural register allocators. I would like to have more discussion on this over IRC this Monday with my mentors.</p></div><div><br></div><div><span><div style="font-size:13px">Plan for next week:</div><div style="font-size:13px">==============</div><div style="font-size:13px">1) Rebase pending patches and get the review process completed.</div></span><div style="font-size:13px">2) Discuss how can identified ideas can be implemented with in current infrastructure.</div><div style="font-size:13px">3) Discuss how to handle indirect function call with in IPRA.</div><div style="font-size:13px"><br></div></div><div style="font-size:13px">Sincerely,</div><div style="font-size:13px">Vivek</div><div><br></div></div><div><div><div class="gmail_extra"><br><div class="gmail_quote">On Sun, Jun 26, 2016 at 5:18 PM, vivek pandya <span dir="ltr"><<a href="mailto:vivekvpandya@gmail.com" target="_blank">vivekvpandya@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hello LLVM Developers,<div><br></div><div>Please follow summary of work done during this week.</div><div><br></div><div>Implementation:</div><div>============</div><div><p style="margin:0px;line-height:normal;font-family:Helvetica">During this week patch for bug fix 28144 is updated after finding more refinement in remarks calculation. As per suggestion from Matthias Braun and Hal Finkel regmask calculation code is same as MachineRegisterInfo::isPhysRegModified() except no check of isNoReturnDef() is required. So we proposed to add a bool argument SkipNoReturnDef with default value false to isPhysRegModified method so that with out breaking current use of isPhysRegModified we can reuse that code for the purpose of IPRA. The patch can be found here : <a href="http://reviews.llvm.org/D21395" target="_blank">http://reviews.llvm.org/D21395</a></p>
<p style="margin:0px;line-height:normal;font-family:Helvetica">With IPRA to improve code quality, call site with local functions are forced to have caller saved registers ( more improved heuristics will be implemented ) I have been experimenting this on my local machine and I discovered that tail call optimization is getting affected due to this optimization and some test case in test-suite fails with segmentation fault or infinite recursion due to counter value gets overwritten. Please find more details and example bug at <a href="https://groups.google.com/d/msg/llvm-dev/TSoYxeMMzxM/rb9e_M2iEwAJ" target="_blank">https://groups.google.com/d/msg/llvm-dev/TSoYxeMMzxM/rb9e_M2iEwAJ</a></p>
<p style="margin:0px;line-height:normal;font-family:Helvetica">I have also tried a very simple method to handle indirect function in IPRA but at higher optimization level, indirect function calls are getting converted to direct function calls so I request interested community member to guide me. We can have discussion about this on Monday morning (PDT). More discussion on this can be found at here : <a href="https://groups.google.com/d/msg/llvm-dev/dPk3lKwH1kU/GNfhD_jKEQAJ" target="_blank">https://groups.google.com/d/msg/llvm-dev/dPk3lKwH1kU/GNfhD_jKEQAJ</a></p><p style="margin:0px;line-height:normal;font-family:Helvetica"><br></p><p style="margin:0px;line-height:normal;font-family:Helvetica">Testing:</p><p style="margin:0px;line-height:normal;font-family:Helvetica">======</p><p style="margin:0px;line-height:normal;font-family:Helvetica">During this week I think that IPRA optimization is more stabilized after having bug fix so have run test-suite with that and also as per suggestion form Quentin Colombet I tested test-suite with only codegen order changed to bottom up on call graph.  Overall this codegen order improves runtime and compile time. I have shared results here:</p><p style="margin:0px;line-height:normal;font-family:Arial;color:rgb(18,85,204)"><span style="text-decoration:underline"><a href="https://docs.google.com/document/d/1At3QqEWmeDEXnDVz-CGh2GDlYQR3VRz3ipIfcXoLC3c/edit?usp=sharing" target="_blank">https://docs.google.com/document/d/1At3QqEWmeDEXnDVz-CGh2GDlYQR3VRz3ipIfcXoLC3c/edit?usp=sharing</a></span></p><p style="margin:0px;line-height:normal;font-family:Arial;color:rgb(35,35,35);min-height:15px"><br></p><p style="margin:0px;line-height:normal;font-family:Helvetica">


</p><p style="margin:0px;line-height:normal;font-family:Arial;color:rgb(18,85,204)"><span style="text-decoration:underline"><a href="https://docs.google.com/document/d/1hS-Cj3mEDqUCTKTYaJpoJpVOBk5E2wHK9XSGLowNPeM/edit?usp=sharing" target="_blank">https://docs.google.com/document/d/1hS-Cj3mEDqUCTKTYaJpoJpVOBk5E2wHK9XSGLowNPeM/edit?usp=sharing</a></span></p></div><div><br></div><div>Plan for next week:</div><div>==============</div><div>1) Rebase pending patches and get the review process completed.</div><div>2) Solve tail call related bug.</div><div>3) Discuss some ideas and heuristics for improving IPRA.</div><div>4) Discuss how to handle indirect function call with in IPRA.</div><div>5) More testing with llvm test-suite</div><div><br></div><div>Sincerely,</div><div>Vivek</div><div><br></div></div><div><div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Jun 21, 2016 at 9:26 AM, vivek pandya <span dir="ltr"><<a href="mailto:vivekvpandya@gmail.com" target="_blank">vivekvpandya@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote"><span>On Tue, Jun 21, 2016 at 1:45 AM, Matthias Braun <span dir="ltr"><<a href="mailto:matze@braunis.de" target="_blank">matze@braunis.de</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span><br>
> On Jun 20, 2016, at 12:53 PM, Sanjoy Das via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>> wrote:<br>
><br>
> Hi Vivek,<br>
><br>
> vivek pandya via llvm-dev wrote:<br>
> >     int foo() {<br>
> >     return 12;<br>
> >     }<br>
> ><br>
> >     int bar(int a) {<br>
> >     return foo() + a;<br>
> >     }<br>
> ><br>
> >     int (*fp)() = 0;<br>
> >     int (*fp1)(int) = 0;<br>
> ><br>
> >     int main() {<br>
> >     fp = foo;<br>
> >     fp();<br>
> >     fp1 = bar;<br>
> >     fp1(15);<br>
> >     return 0;<br>
> >     }<br>
><br>
> IMO it is waste of time trying to do a better job at the IPRA level on<br>
> IR like the above ^.  LLVM should be folding the indirect calls to<br>
> direct calls at the IR level, and if it isn't that's a bug in the IR<br>
> level optimizer.<br>
</span>+1 from me.<br>
<br></blockquote></span><div>Yes at -O3 level simple indirect calls including virtual functions are getting optimized to direct call.</div><span><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
The interesting cases are the non-obvious ones (assumeing foo/bar have the same parameters). Things gets interesting once you have uncertainty in the mix. The minimally interesting case would look like this:<br>
<br>
int main() {<br>
    int (*fp)();<br>
    if (rand()) {<br>
        fp = foo;<br>
    } else {<br>
        fp = bar;<br>
    }<br>
    fp(42);<br>
}<br></blockquote><div> </div></span><div>I tried this case and my simple hack fails to optimize it :-) . This requires discussion on IRC.</div><div><br></div><div>Sincerely,</div><div>-Vivek</div><span><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
However predicting the possible targets of a call is IMO a question of computing a call graph datastructure and improving upon that. We should be sure that we discuss and implement this independently of the register allocation work!<br>
<span><font color="#888888"><br>
- Matthias<br>
<br>
</font></span></blockquote></span></div><br></div></div>
</blockquote></div><br></div>
</div></div></blockquote></div><br></div>
</div></div></blockquote></div><br></div></div></div></div>
</blockquote></div><br></div>