[PATCH] D108741: [GlobalDCE] Handle non-vfunc entries in vtables during VFE

Kuba (Brecka) Mracek via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 27 17:42:25 PDT 2021


kubamracek added a comment.

> Sorry, I think I managed to confuse myself when I was trying to figure out what VFE actually relies on. It seems that VFE doesn't rely on what I thought it did. Although VFE relies on type metadata, it only relies on it to determine the locations of the address points, and not the locations of the VFE-eligible function slots.

@pcc, I apologize I think I got confused the same way. I think I had the wrong understanding that if any slot in a vtable does not have a matching !type annotation (on the vtable global) with the right offset, it's basically trivially removable by VFE, but apparently, as you're pointing out, that's not the case -- it could still be used by a non-zero offset load via llvm.type.checked.load. In such a case, the slot at (vcall offset + vtable annotation offset) is actually being matched. So even if a vtable slot at offset X is never mentioned in any !type annotation, it could still be matched by any preceding !type type id with a non-zero offset at the call site.

Could you confirm that this understanding I just mentioned is actually correct now? Thanks :)

> Here's one alternative proposal: can we make it so that any vtable slots that are eligible for VFE are represented using a new type of Constant (similar to dso_local_equivalent)? This also has the advantage that frontends could also use it for global variables as well as functions.

Just to make sure I understand this proposal, would we *require* frontends to mark all VFE eligible slots with this? I assume the only existing (publicly known) user of VFE is Clang, so as part of the change we'd fix Clang too? And the way this would look on a simple example would be something like the following?

  @vtable = internal unnamed_addr constant ... {[
    i8* bitcast (void ()* vfe_eligible @vfunc1 to i8*),
    i8* bitcast (void ()* vfe_eligible @vfunc2 to i8*),
    i8* bitcast (void ()* @non_eligible to i8*)
  ]}, align 8, !type ...

And in the case of "relative pointers" that Swift uses in its data structures, the Constant would be present at the inner-most reference, like this?

  @vtable = internal unnamed_addr constant { [2 x i32] } { [2 x i32] [
    i32 trunc (i64 sub (i64 ptrtoint (void ()* vfe_eligible @vfunc1 to i64), i64 ptrtoint ({ [2 x i32] }* @vtable to i64)) to i32),
    i32 trunc (i64 sub (i64 ptrtoint (void ()* vfe_eligible @vfunc2 to i64), i64 ptrtoint ({ [2 x i32] }* @vtable to i64)) to i32)
  ]}, align 8, !type ...


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D108741/new/

https://reviews.llvm.org/D108741



More information about the llvm-commits mailing list