[clang] [IRPGO][ValueProfile] Instrument virtual table address that could be used to do virtual table address comparision for indirect-call-promotion. (PR #66825)

Mingming Liu via cfe-commits cfe-commits at lists.llvm.org
Mon Oct 2 16:56:56 PDT 2023


================
@@ -90,9 +90,33 @@ public:
   }
 };
 
+///------------------------ VirtualTableValueProfilingPlugin ------------------------
+class VTableProfilingPlugin {
+  Function &F;
+
+public:
+  static constexpr InstrProfValueKind Kind = IPVK_VTableTarget;
+
+  VTableProfilingPlugin(Function &Fn, TargetLibraryInfo &TLI) : F(Fn) {}
----------------
minglotus-6 wrote:

I added a FIXME to do more efficient vtable instrumentation. To fix this, need to make sure one instrumented value profile gets used at more than one virtual callsite (correctly).

To elaborate, take https://gcc.godbolt.org/z/K7a37546E as an example

C++ source 

```
class Base1 {
    public:
    virtual int func1(int a, int b) ;
    virtual int func2();
};

class Derived : public Base1 {
    public:
    Derived(int c) : v(c) {}
  
    private:
    int v;
};

Derived* createType(int c);

int func(int a, int b, int c) {
    Derived* d = createType(c);
    
    return d->func2() + d->func1(b, a);
}
```

and IR 

```
define dso_local i32 @func(int, int, int)(i32 %a, i32 %b, i32 %c) local_unnamed_addr #0 {
entry:
  %call = tail call ptr @createType(int)(i32 %c)
  %vtable = load ptr, ptr %call, align 8, !tbaa !7
  %vfn = getelementptr inbounds ptr, ptr %vtable, i64 1
  # %0 is one virtual func, loaded from %vtable
  %0 = load ptr, ptr %vfn, align 8
  %call1 = tail call i32 %0(ptr nonnull align 8 dereferenceable(8) %call)
  %vtable2 = load ptr, ptr %call, align 8, !tbaa !7
  # %1 is another virtual func, loaded from %vtable2
  %1 = load ptr, ptr %vtable2, align 8
  %call4 = tail call i32 %1(ptr nonnull align 8 dereferenceable(8) %call, i32 %b, i32 %a)
  %add = add nsw i32 %call4, %call1
  ret i32 %add
}
```

Without `-fstrict-vtable-pointers`, `func1` and `func2` are load different vtable SSA variable. Instrument the first vtable but not the second gives more efficient instrumentation; yet at profile-use time, it would require analysis and value profile propagation (first prove load invariance, and then copy `vtable` value profie to `vtable2`) to associate value profiles of `vtable` (the 1st vtable) with `%1` (the 2nd virtual call), since the 2nd virtual call loads from `vtable2`.

https://github.com/llvm/llvm-project/pull/66825


More information about the cfe-commits mailing list