[PATCH] D79235: [WPD] Allow virtual calls to be analyzed with multiple type tests

Teresa Johnson via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri May 1 17:13:34 PDT 2020


tejohnson created this revision.
tejohnson added reviewers: pcc, vitalybuka, evgeny777.
Herald added subscribers: dexonsmith, steven_wu, hiraditya, Prazek.
Herald added a project: LLVM.
tejohnson updated this revision to Diff 261509.
tejohnson added a comment.

Rebase


In D52514 <https://reviews.llvm.org/D52514> I had fixed a bug with WPD after indirect call promotion, by
checking that a type test being analyzed dominates potential virtual
calls. With that fix I included a small effiency enhancement to avoid
processing a devirt candidate multiple times (when there are multiple
type tests). This latter change wasn't in response to any measured
efficiency issues, it was merely theoretical. Unfortuantely, it turns
out to limit optimization opportunities after inlining.

Specifically, consider code that looks like:

class A {

  virtual void foo();

};
class B : public A {

  void foo();

}
void callee(A *a) {

  a->foo(); // Call 1

}
void caller(B *b) {

  b->foo(); // Call 2
  callee(b);

}

After inlining callee into caller, because of the existing call to
b->foo() in caller there will be 2 type tests in caller for the vtable
pointer of b: the original type test against B from Call 2, and the
inlined type test against A from Call 1. If the code was compiled with
-fstrict-vtable-pointers, then after optimization WPD will see that
both type tests are associated with the inlined virtual Call 1.
With my earlier change to only process a virtual call against one type
test, we may only consider virtual Call 1 against the base class A type
test, which can't be devirtualized. With my change here to remove this
restriction, it also gets considered for the type test against the
derived class B type test, where it can be devirtualized.

Note that if caller didn't include it's own earlier virtual call
b->foo() we will not be able to devirtualize after inlining callee even
after this fix, since there would not be a type test against B in the
IR. As a future enhancement we can consider inserting type tests at call
sites that pass pointers to classes with virtual calls, to enable
context-sensitive devirtualization after inlining.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D79235

Files:
  llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp
  llvm/test/ThinLTO/X86/devirt_multiple_type_test.ll

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D79235.261509.patch
Type: text/x-patch
Size: 5040 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200502/bdb9d75e/attachment.bin>


More information about the llvm-commits mailing list