[llvm-dev] RFC: virtual-like methods via LLVM-style RTTI

David Zarzycki via llvm-dev llvm-dev at lists.llvm.org
Fri May 4 03:49:00 PDT 2018



> On May 4, 2018, at 4:34 AM, David Chisnall <David.Chisnall at cl.cam.ac.uk> wrote:
> 
> On 3 May 2018, at 22:09, David Zarzycki via llvm-dev <llvm-dev at lists.llvm.org> wrote:
>> 
>> Hello,
>> 
>> In an effort to help LLVM-style projects save memory, I’ve been toying with some macros that provide an alternative to C++ vtables that use LLVM-style RTTI design patterns instead. Is this something that LLVM or sub-projects think is worth pursuing? Or are the macros below too ugly/problematic? Feedback would be appreciated.
> 
> It would help to have a little bit of information about how you expect this to work.  LLVM-style RTTI works by adding a method to the vtable that returns the kind of the instance and can be used with templates to allow casting.  If you retain this, then every object still needs the vtable pointer, which appears to be what you are trying to avoid.  If you don’t have this, then how do you expect to be able to differentiate instance types?
> 
> From your code, it looks as if you’re implementing an inverted vtable structure, where there is a per-method vtable with per-subclass entries, rather than a traditional vtable where you have one per class and per-method entries.  Your total vtable space goes from being NxM to being MxN, which doesn’t sound like an improvement.  This kind of approach is generally popular in late-bound dynamic languages with duck typing where you have a lot of methods with few overrides and it’s worth having a slightly more expensive lookup to have a sparser structure than the full NxM matrix.  It doesn’t seem appropriate here.

Hi David,

The motivating example was/is clang’s Decl type hierarchy. It uses both C++ vtables and LLVM-style getKind()/classof() (which are non-virtual and don’t need to be virtual). In practice, this represents two RTTI systems: one for virtual dispatch and one for casting. This patch is about using the LLVM-style getKind() logic to implement virtual dispatch, thus saving sizeof(void*) per allocated Decl node, which can add up very, very quickly.

The other motivating reason for this patch is that C++ vtables prevent certain kinds of object layout optimizations. For example, I could make clang about one to two percent faster by storing the DeclContext at fixed negative offset rather than a per-class positive offset. This negative-offset DeclContext optimization is precedented too (see the Swift compiler DeclContext).

Dave


More information about the llvm-dev mailing list