[all-commits] [llvm/llvm-project] d291bd: [WPD] Allow virtual calls to be analyzed with mult...

Teresa Johnson via All-commits all-commits at lists.llvm.org
Wed Jun 24 10:52:03 PDT 2020


  Branch: refs/heads/master
  Home:   https://github.com/llvm/llvm-project
  Commit: d291bd510e6a4e62594186cb8f3ddc18acf2ee1a
      https://github.com/llvm/llvm-project/commit/d291bd510e6a4e62594186cb8f3ddc18acf2ee1a
  Author: Teresa Johnson <tejohnson at google.com>
  Date:   2020-06-24 (Wed, 24 Jun 2020)

  Changed paths:
    M llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp
    A llvm/test/ThinLTO/X86/devirt_multiple_type_test.ll

  Log Message:
  -----------
  [WPD] Allow virtual calls to be analyzed with multiple type tests

Summary:
In 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.

Reviewers: pcc, vitalybuka, evgeny777

Subscribers: Prazek, hiraditya, steven_wu, dexonsmith, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D79235




More information about the All-commits mailing list