<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Hi Hans<div class=""><br class=""></div><div class="">The prototype Mehdi and I worked on (which I hope we can contribute on its own, or as patches to Peter’s implementation), is able to handle your use case.</div><div class=""><br class=""></div><div class="">I’d be interested if Peter’s is able to handle this too, but i confess I don’t yet know how his code is implemented.</div><div class=""><br class=""></div><div class="">Our code uses metadata to encode what is the most derived class you could be at a point in time.  Paired with complete class hierarchy in metadata, this allows us to work out which classes we could possibly be at a given call site.</div><div class=""><br class=""></div><div class="">For example, and I hope this is similar to what you are describing:</div><div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class="">class Base {</div><div class="">  virtual void foo();</div><div class="">}</div><div class=""><br class=""></div><div class="">class A : public Base {</div><div class="">  void foo override();</div><div class="">}</div><div class=""><br class=""></div><div class="">class B : public A {</div><div class="">  // no override of foo()</div><div class="">}</div><div class=""><br class=""></div><div class="">A *p;</div><div class="">...</div><div class="">p->foo();</div></blockquote><div class=""><br class=""></div><div class="">The call to foo here is known to be an ‘A’ or any class derived from it.  As we have the full hierarchy, we know it can only be [A, B].</div><div class=""><br class=""></div><div class="">Now we can look at the vtable entries on A and B, and see that both contain the same &foo in the slot we are reading from, and so devirtualize as only a single foo could possibly be called from here (otherwise UB).</div><div class=""><br class=""></div><div class="">We are also able to look at the users of the vtable globals themselves and see which ones are ever used.  If one isn’t used, then no-one can be one of those classes, and we can remove it from the hierarchy.  This could reduce the set of possible classes (or possible called functions at a given site) to 1, and we can devirtualize.  That sounds like it might be the case for the WebScrolBar you mention where the only possible implementation in the hierarchy is a single derived class.</div><div class=""><br class=""></div><div class="">Peter, i’d be interested in discussing this further, but i don’t want to digress the conversation any further from what you are trying to discuss here.  FWIW, I really like the proposal you have here and think we should get it in tree.</div><div class=""><br class=""></div><div class="">Cheers,</div><div class="">Pete<br class=""><div><blockquote type="cite" class=""><div class="">On Jan 28, 2016, at 8:47 AM, Hans Wennborg via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org" class="">llvm-dev@lists.llvm.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="">On Wed, Jan 27, 2016 at 7:57 PM, Peter Collingbourne <<a href="mailto:peter@pcc.me.uk" class="">peter@pcc.me.uk</a>> wrote:<br class=""><blockquote type="cite" class="">The pass that applies this transformation will be placed early in the LTO<br class="">pipeline, before most of the regular optimization passes. The pass could later<br class="">be extended to do general devirtualization based on the bitset information:<br class=""><br class=""> - The pass can implement single-deriver (i.e. only one derived class with a<br class="">   non-pure virtual function definition) and single-implementation<br class="">   (i.e. multiple derived classes all sharing a virtual function definition<br class="">   from a base class) devirtualization by checking that each of the possible<br class="">   values loaded from the vtables in the bitset are either identical or<br class="">   __cxa_pure_virtual (calls to pure virtuals are UB, so we’d be fine<br class="">   disregarding them), and propagating the identical address into the<br class="">   function callee.<br class=""></blockquote><br class="">In addition to the constant value propagation, which looks fantastic,<br class="">I'm also very interested in this aspect.<br class=""><br class="">For example, Blink/WebKit public interface is full of classes like<br class="">[0], which have a single implementation (sometimes there's also a mock<br class="">implementation used in tests). In many classes (like [1]), the methods<br class="">are not pure-virtual but have dummy implementations, but we should be<br class="">able to figure out that the base class constructor is never called<br class="">except when constructing the single implementation class.<br class=""><br class="">Most of this interface might not be very hot, but optimizing the<br class="">virtual barrier away seems looks like a juicy opportunity for binary<br class="">size and inlining (and start-up time if we can drop the vtables and<br class="">void the dynamic relocations).<br class=""><br class="">Cheers,<br class="">Hans<br class=""><br class="">[0]. <a href="https://code.google.com/p/chromium/codesearch#chromium/src/third_party/WebKit/public/platform/WebScrollbar.h" class="">https://code.google.com/p/chromium/codesearch#chromium/src/third_party/WebKit/public/platform/WebScrollbar.h</a><br class="">[1]. <a href="https://code.google.com/p/chromium/codesearch#chromium/src/third_party/WebKit/public/platform/WebScrollbarBehavior.h" class="">https://code.google.com/p/chromium/codesearch#chromium/src/third_party/WebKit/public/platform/WebScrollbarBehavior.h</a><br class="">_______________________________________________<br class="">LLVM Developers mailing list<br class=""><a href="mailto:llvm-dev@lists.llvm.org" class="">llvm-dev@lists.llvm.org</a><br class="">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev<br class=""></div></div></blockquote></div><br class=""></div></body></html>