[PATCH] D108741: [IR][GlobalDCE] Add ability to mark vtable methods as eligible for VFE and avoid eliminating non-eligible vfunc in VFE in GlobalDCE

Kuba (Brecka) Mracek via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 11 17:46:36 PDT 2021


kubamracek added a comment.

Thank you for the detailed response, @rjmccall ! Let me try to explain my ultimate motivation here :)

I want to implement Virtual Function Elimination (VFE) on methods in classes and subclasses in Swift code, and given that LLVM and Clang already support VFE for C++ and that there's a lot of existing infrastructure for that in LLVM, it seems like an reasonable strategy to reuse all the LLVM IR parts for recognizing vtables and vcall sites and for proving that vtable slots are unused, etc. We "just" need to change the Swift language frontend to mark vtables and vcall sites in the right way so that the existing LLVM VFE logic does the right thing.

This *almost* works, expect for the fact that the Swift frontend embeds pointers to vfunctions inside large data structures, namely nominal type descriptors and full type metadata structs -- i.e. there is no standalone vtable symbol per class (and changing the layout of this in not feasible because it's ABI). Instead, a part of a larger struct is used as a vtable, and the larger struct does actually contain function pointers that are irrelevant to VFE (they're not a vtable slot). But the existing implementation of VFE happily "proves" (incorrectly) that this non-vptr function pointer is unused and removes it.

What I'm concluding from that is that the problem I need to solve is that somehow I need to be able to express in LLVM IR that only the "vtable portion" of the struct should actually participate in VFE, and these vptr-irrelevant references should just not be touched at all when doing VFE. What would be your recommended approach to achieve that? So far, I think these were on the table:

- Reuse !type -- not correct, breaks VFE in C++, as @pcc pointed out.
- Have a new attribute on the global that changes the semantics of !type. I am not sure if this is (a variation of) what you've suggested?
- Use vfe_eligible constants to mark individual entries in the global. Then "not marked" references will not be touched by VFE. Current implementation in this diff.

Or do you think I'm solving the wrong problem? Note that I'm not trying to change anything about how VFE is done today for C++ code.


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

https://reviews.llvm.org/D108741



More information about the llvm-commits mailing list