[RFC] Migrate pointers to members to the middle end
Michael Matz
matz@suse.de
Thu Aug 9 01:21:00 GMT 2007
Hi,
On Thu, 8 Aug 2007, Ian Lance Taylor wrote:
>> those whose runtime type can be any derived one) can not. E.g. I
>> wouldn't try to model the inheritance relationship.
>
> There is some advantage to knowing class heirarchy relationships in LTO.
> Some C++ programs implement different virtual subclasses in different
> files. LTO can put those together. When the compiler can then
> determine that a variable definitely has a particular subclass, it can
> devirtualize the virtual calls, turning an indirect function call into a
> direct function calls, also exposing inlining opportunities.
Yes, devirtualization. But I wonder if you really need class hierarchies
for this (actually I'm fairly sure you don't). In effect you only need to
determine where this virtual call, when you know the definite runtime type
of the object pointer, points to, i.e. to which function decl. For that
you don't need the class hierarchy (i.e. the edges in the inheritance
graph, or in fact any information about what base classes might or might
exist or about other classes), but simply a list of all slot-number ->
function-decls mappings for that type, i.e. the vtable (but let's call it
different to not confuse it with the C++-ABI thingy which actually is
written to the .o file). As the middle end should have all thunks already
also 'this' pointer adjusting virtual calls should be taken care of (i.e.
the slot->function mapping should already have the thunks referenced).
Then you just need a way to get from a definite type to that
slot->function mapping. As the LTO frontend needs to emit something
similar anyway somewhere (as it needs to express all C++ types in some
lowered form appropriate for the LTO reader), it will be available
somehow, presumably hanging off the RECORD_TYPE. If you have the definite
runtime type of the pointer, you also have that RECORD_TYPE, hence the
slot->function mapping, the slot number from the virtual call itself, and
ergo the finally called function_decl. No need for hierarchies.
There were also other patches already floating around which (tried to)
implement devirtualization (via profile feedback testing at runtime if a
pointer was of certain type), which didn't need real inheritance
hierarchies in the middle-end, so it can be done.
We also need to make sure to not munge together too many of these not
entirely trivial topics. We have pointer to members (IMHO just fancy
offsets) and virtual function calls (for devirtualization) up to now.
They only relate via pointer to virtual member functions, which still are
only fancy offsets (referring to a slot number, not a byte offset). So
IMHO the C++ frontend should lower all these constructs as much as
possible and try to express them in basic types and expressions, instead
of pulling the whole hair into the middle end. If something is right now
not possible in the middle-end, then we should try to carefully add the
necessary information (and only that) to enable whatever we want. For
devirtualization I think I pointed out one possibility. I'm not sure what
else we want. Surely I've seen nothing which would make me think "hell,
yes, let's pull pointer to members into the middle end, and as we are at
it, let's add virtual functions right away too" ;-)
Ciao,
Michael.
PS: From time to time I'm forced to dive into either of these areas of
cp/*.[ch] and it has some very complex code. Most of it really front-end
related I know, but intertwined with the code generation and layouting
code. I'm fairly certain that this all should stay in cp/ .
More information about the Gcc
mailing list