[PATCH] D16821: Add whole-program vtable optimization feature to Clang.

Pete Cooper via cfe-commits cfe-commits at lists.llvm.org
Mon Feb 22 13:38:27 PST 2016


> On Feb 22, 2016, at 1:30 PM, Peter Collingbourne <peter at pcc.me.uk> wrote:
> 
> One thing that I'd like to do (and this would help CFI as well) is to specifically recognize cases like this:
> 
> ```
> struct B {
>  virtual void vf();
> };
> 
> struct D1 {
> };
I assume you meant D1 : B here?
> 
> struct D2 : B {
>  virtual void vf();
> };
> 
> void f(D1 *d) {
>  d->vf();
> }
> ```
> 
> In this case I'd like to devirtualize the virtual call in `f()` to `B::vf()`. But because the implicit cast to `B` in `f()` removes the information that `d` cannot be of type `D2`, we cannot eliminate `D2::vf()` as a candidate target (see also `test/cfi/sibling.cpp` in the CFI test suite).
> 
> Although this could possibly be emitted and pattern matched at the IR level, it seems simpler (and would probably catch enough cases) to have Clang look through the implicit cast when IR gen'ing for the call.
So my devirtualizer dealt with this by marking each call site with the most specific class we know of in the hierarchy.  

In this case, then class hierarchy would contain the pairs: (B, B), (D1, B), (D2, B).

The call site in f() would be tagged with (D1, B) not (B, B).  Then, when we are in the pass, we look at the subclasses from (D1, B), see that there are none (or that none override vf), and devirtualize to B::vf().

If that isn’t possible in the current solution (I didn’t check), then it should be easy enough to add.  I certainly don’t think any of the current implementation would be hard to adapt to support this use case.

Cheers,
Pete



-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160222/778c7746/attachment.html>


More information about the cfe-commits mailing list