<html><body><p><font size="2">Hi David,</font><br><br><font size="2">So I've began doing some implementation on the outlining portion of the code.  Currently, I got the partial inliner to outline cold regions (single entry, single exit) of the code, based solely on the existence of ProfileSummaryInfo (ie. profiling data).  However, I have some concerns on how this will co-exist with the existing code that peels early returns.</font><br><br><font size="2">The control flow looks something like this:</font><br><br><font size="2" face="Courier New">// New Code: find cold regions to outline</font><br><font size="2" face="Courier New">if (!computeOutliningInfoForColdRegions()) {</font><br><font size="2" face="Courier New">  // If we can't find any cold regions, then fall-back to early return peeling</font><br><font size="2" face="Courier New">  if (!computeOutliningInfo) {</font><br><font size="2" face="Courier New">     return nullptr;   </font><br><font size="2" face="Courier New">  }</font><br><font size="2" face="Courier New">}</font><br><font size="2" face="Courier New">// Try to outline the identified regions</font><br><font size="2" face="Courier New">// Then try to inline the cloned function</font><br><br><font size="2">My concern is during inlining, if we fail to inline the cloned function, we give up and discard all cloned and outlined functions.  But with these two types of outlining we're doing, it's possible to attempt to inline the cloned function that has outlined cold regions, and if we cannot do so, try to inline a different clone that has peeled early returns (ie. the way we have it today).  This would require us to clone the original function twice and modify one based on cold region outlining and the other early return peeling, with the latter being our fall-back option if we fail to inline the first clone.</font><br><br><font size="2">What are your thoughts?</font><br><br><font size="2">Graham Yiu<br>LLVM Compiler Development<br>IBM Toronto Software Lab<br>Office: (905) 413-4077      C2-707/8200/Markham<br>Email: gyiu@ca.ibm.com</font><br><br><img width="16" height="16" src="cid:1__=8FBB0B15DFCF46F78f9e8a93df938690918c8FB@" border="0" alt="Inactive hide details for Graham Yiu---08/15/2017 08:04:28 PM---Hey David, Yes, we'll need to consider the effect on live range"><font size="2" color="#424282">Graham Yiu---08/15/2017 08:04:28 PM---Hey David, Yes, we'll need to consider the effect on live ranges for regions we want to outline.  In</font><br><br><font size="2" color="#5F5F5F">From:        </font><font size="2">Graham Yiu/Toronto/IBM</font><br><font size="2" color="#5F5F5F">To:        </font><font size="2">Xinliang David Li <xinliangli@gmail.com></font><br><font size="2" color="#5F5F5F">Cc:        </font><font size="2">llvm-dev <llvm-dev@lists.llvm.org></font><br><font size="2" color="#5F5F5F">Date:        </font><font size="2">08/15/2017 08:04 PM</font><br><font size="2" color="#5F5F5F">Subject:        </font><font size="2">Re: [llvm-dev] [RFC] Enhance Partial Inliner by using a general outlining scheme for cold blocks</font><br><hr width="100%" size="2" align="left" noshade style="color:#8091A5; "><br><br><font size="2">Hey David,</font><br><br><font size="2">Yes, we'll need to consider the effect on live ranges for regions we want to outline.  In my experience, outlining live-exit regions seem to cause the most harm as we ruin chances to keep data in registers as you were alluding to.  It's unclear, however, what the exact effect of outlining regions with live-entries would be.</font><br><br><font size="2">I'll probably try to avoid regions that are not single entry & single exit at least initially, to simplify the transformation and analysis.  Are multi-exit regions common in your experience?</font><br><br><font size="2">And of course, I agree, we should reuse as much of the current partial inlining infrastructure as possible.  I'll likely run some ideas by you as I begin to make changes.</font><br><br><font size="2">Cheers,</font><br><br><font size="2">Graham Yiu<br>LLVM Compiler Development<br>IBM Toronto Software Lab<br>Office: (905) 413-4077      C2-407/8200/Markham<br>Email: gyiu@ca.ibm.com</font><br><br><br><img width="16" height="16" src="cid:1__=8FBB0B15DFCF46F78f9e8a93df938690918c8FB@" border="0" alt="Inactive hide details for Xinliang David Li ---08/15/2017 05:36:07 PM---Hi Graham, Making partial inlining more general is some"><font size="2" color="#424282">Xinliang David Li ---08/15/2017 05:36:07 PM---Hi Graham, Making partial inlining more general is something worth doing. Regarding your implementat</font><br><br><font size="2" color="#5F5F5F">From:        </font><font size="2">Xinliang David Li <xinliangli@gmail.com></font><br><font size="2" color="#5F5F5F">To:        </font><font size="2">Graham Yiu <gyiu@ca.ibm.com></font><br><font size="2" color="#5F5F5F">Cc:        </font><font size="2">llvm-dev <llvm-dev@lists.llvm.org></font><br><font size="2" color="#5F5F5F">Date:        </font><font size="2">08/15/2017 05:36 PM</font><br><font size="2" color="#5F5F5F">Subject:        </font><font size="2">Re: [llvm-dev] [RFC] Enhance Partial Inliner by using a general outlining scheme for cold blocks</font><br><hr width="100%" size="2" align="left" noshade style="color:#8091A5; "><br><br><br>Hi Graham, Making partial inlining more general is something worth doing.  Regarding your implementation plan, I have some suggestions here:<br><br>*) Function outlining introduces additional runtime cost: passing of live in values, returning of live out values (via memory), glue code in the caller to handle regions without a single exit block etc.  The cost analysis needs to factor in those carefully <br>*) Remove the limitation that there is only *one* outlined routine. Instead, the algorithm can compute multiple single-entry/single exit or single entry/multiple exit regions (cold ones) in the routine, and outline each region into its own function. The benefit include<br>   1) simplify the design and implementation and most of the existing code can be reused;<br>   2) provide more flexibility to allow most effective outlining;<br>   3) reduced runtime overhead of making calls to the outline functions.<br><br>thanks,<br><br>David<br><br>On Tue, Aug 15, 2017 at 11:22 AM, Graham Yiu via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org" target="_blank"><u><font color="#0000FF">llvm-dev@lists.llvm.org</font></u></a>> wrote:
<ul><font size="2" face="Arial">Hello,</font><br><font size="2" face="Arial"><br>My team and I are looking to do some enhancements in the partial inliner in opt. Would appreciate any feedback that folks might have.</font><br><font size="2" face="Arial"><br># Partial Inlining in LLVM opt<br><br>## Summary<br><br>### Background<br><br>Currently, the partial inliner searches the first few blocks of the callee and looks for a branch to the return block (ie. early return). If found, it attempts to outline the rest of the slow (or heavy) code so the inliner will be able to inline the fast (or light) code. If no early returns are found, the partial inliner will give up. As far as I can tell, BlockFrequency and BranchProbability information is only used when attempting to inline the early return code, and not used to determine whether to outline the slow code.<br><br>### Proposed changes<br><br>In addition to looking for early returns, we should utilize profile information to outline blocks that are considered cold. If we can sufficiently reduce the size of the original function via this type of outlining, inlining should be able to inline the rest of the hot code. <br><br>## Details<br><br>With the presence of profile information, we have a view of what code is infrequently executed and make better decisions on what to outline. Early return blocks that are infrequently executed should still be included as candidates for outlining, but will be treated just like any other cold blocks. Without profiling information, however, we should remain conservative and only partial inline in the presence of an early return in the first few blocks of a function (ie. peel the early return out of the function).<br><br>To find cold regions to outline, we will traverse the CFG to find edges deemed 'cold' and look at the blocks dominated by the successor node. If, for some reason, that block has more than one predecessor, then we will skip this candidate as there should be a node that dominates this successor that has a single entry point. The last node in the dominance vector should also have a single successor. If it does not, then further investigation of the CFG is necessary to see when/how this situation occurs.<br><br>We will need several heuristics to make sure we only outline in cases where we are confident it will result in a performance gain. Things such as threshold on when a branch is considered cold, the minimum number of times the predecessor node has to be executed in order for an edge to be considered (confidence factor), and the minimum size of the region to be outlined (can use inlining cost analysis like we currently do) will require some level of tuning.<br><br>Similar to the current implementation, we will attempt to inline the leftover (hot) parts of the code, and if for some reason we cannot then we discard the modified function and its outlined code.<br><br>### Code changes<br><br>The current Partial Inlining code first clones the function of interest and looks for a single set of blocks to outline. It then creates a function with the set the blocks, and saves the outlined function and outline callsite information as part of the function cloning container. In order to outline multiple regions of the function, we will need to change these containers to keep track of a list of regions to outline. We will also need to update the cost analysis to take into account multiple outlined functions. <br><br>When a ProfileSummary is available, then we should skip the code that looks for early returns and go into new code that looks for cold regions to outline. When ProfileSummary is not available, then we can fall back to the existing code and look for early returns only.<br><br>### Tuning<br><br>- The outlining heuristics will need to determine if a set of cold blocks is large enough to warrant the overhead of a function call. We also don't want the inliner to attempt to inline the outlined code later.<br>- The threshold for determining whether a block is cold will also need to be tuned. In the case that profiling information is not accurate, we will pay the price of the additional call overhead for executing cold code.<br>- The confidence factor, which can be viewed as the minimum number of times the predecessor has to be executed in order for an edge to be considered cold, should also be taken into account to avoid outlining code paths we have little information on.</font><br><font size="2"><br>Graham Yiu<br>LLVM Compiler Development<br>IBM Toronto Software Lab<br>Office: </font><a href="tel:(905)%20413-4077" target="_blank"><u><font size="2" color="#0000FF">(905) 413-4077</font></u></a><font size="2"> C2-407/8200/Markham<br>Email: </font><a href="mailto:gyiu@ca.ibm.com" target="_blank"><u><font size="2" color="#0000FF">gyiu@ca.ibm.com</font></u></a><br><br>_______________________________________________<br>LLVM Developers mailing list<u><font color="#0000FF"><br></font></u><a href="mailto:llvm-dev@lists.llvm.org"><u><font color="#0000FF">llvm-dev@lists.llvm.org</font></u></a><u><font color="#0000FF"><br></font></u><a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" target="_blank"><u><font color="#0000FF">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</font></u></a><br></ul><br><br><br><BR>
</body></html>