<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div><blockquote type="cite" class=""><div class="">On Mar 22, 2017, at 1:31 PM, Reid Kleckner <<a href="mailto:rnk@google.com" class="">rnk@google.com</a>> wrote:</div><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote">On Tue, Mar 21, 2017 at 9:01 PM, John McCall via cfe-dev <span dir="ltr" class=""><<a href="mailto:cfe-dev@lists.llvm.org" target="_blank" class="">cfe-dev@lists.llvm.org</a>></span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">3. We know exactly when the inner function will be called and it can be fit into the outer function's CFG.  This is true of some OpenMP features and some very specific Swift features.<br class="">
<br class="">
We can still do normal data-flow and control-flow analyses between the outer and inner functions; the only constraint is that we (probably) have to treat the beginning and end of the inner function as opaque barriers.  So the unlowered function looks something like:</blockquote><div class=""><br class=""></div><div class="">I'd also throw in that our implementation of MSVC EH is a good example of this type of inner function outlining in LLVM. The token-producing block leader and terminator instructions create single-entry single-exit regions that we can outline into funclets as part of CodeGen.</div></div></div></div></div></blockquote><div><br class=""></div>Very good point.</div><div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><div class="">By keeping the funclets in the normal CFG of the parent function, we are able to SROA aggregates with destructors and do things like heap-to-stack conversion of std::unique_ptr.</div><div class=""><br class=""></div><div class=""><div class="">#include <memory></div><div class="">void may_throw(int);</div><div class="">void foo() {</div><div class="">  std::unique_ptr<int> p(new int(42));</div><div class="">  may_throw(*p);</div><div class="">}</div></div><div class=""><br class=""></div><div class="">Getting back to Hal's original question, I think that these kinds of optimizations are impossible for C++ lambdas. They frequently appear in headers and it's really easy to leak the class type with decltype and auto, and that class definition better be the same across all TUs.</div></div></div></div>
</div></blockquote><br class=""></div><div>It's okay for optimizations to only apply to "special cases", especially when those special cases are likely to be dominant in practice.  Optimizing lambdas would absolutely be worthwhile even if we had to not apply the optimizations to lambdas in inline functions.</div><div><br class=""></div><div>John.</div></body></html>