[llvm-commits] Deleting the Value vtable

Gordon Henriksen gordonhenriksen at mac.com
Sun Dec 9 15:36:48 PST 2007


On Dec 9, 2007, at 17:50, Gordon Henriksen wrote:

> On Dec 3, 2007, at 17:59, pawel kunio wrote:
>
>> Whoah, pretty strange I get neither of those. I'm using compiler  
>> from vs 2008 beta2 'orcas'. What compiler should I use to be more  
>> in sync with the one used by You for verification? btw, I had a  
>> deeper look into the Value class hierarchy and it seems that to  
>> remove all vtables there will be a need to flatten Instruction  
>> hierarchy with regard to the clone virtual method as well as  
>> Constant destroyConstant,isNullValue,replaceUsesOfWithOnConstant  
>> methods) and GlobalValue (isDeclaration method). Those as well as  
>> print and dump methods will probably be blocking the Value  
>> destructor from being de-virtualized.
>>
>> Anyway, please find the patch attached with the Value destructor  
>> virtualized temporarily and with added 'class' clause to friend  
>> Value declarations.
>
> Thanks Pawel! I've applied your patch as rev 44747 here:
>
> http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20071203/056105.html


Since there are some other methods to devirtualize deeper in the class  
hierarchy, I wonder if it might make sense to write the dispatch once  
instead of repeating it several times. Here are some ideas off the top  
of my head…

// Dispatch to static methods.
#define NONVIRTUAL_DISPATCH1(V, F) \
        if (Foo *W = dyn_cast<Foo>(V)) W->F(); \
   else if (Bar *W = dyn_cast<Bar>(V)) W->F(); \
   else if (Baz *W = dyn_cast<Baz>(V)) W->F();


// Dispatch to static methods.
#define NONVIRTUAL_DISPATCH2(V, F) \
        if (Foo *W = dyn_cast<Foo>(V)) Foo::F(W); \
   else if (Bar *W = dyn_cast<Bar>(V)) Bar::F(W); \
   else if (Baz *W = dyn_cast<Baz>(V)) Baz::F(W);


// Dispatch to operator() overloads on a template operand.
template <typename Algo>
void NonvirtualDispatch3(Value *V) {
   Algo A;
   NonvirtualDispatch3(V, A);
};

template <typename Algo>
void NonvirtualDispatch3(Value *V, Algo &A) {
        if (Foo *W = dyn_cast<Foo>(V)) A(W);
   else if (Bar *W = dyn_cast<Bar>(V)) A(W);
   else if (Baz *W = dyn_cast<Baz>(V)) A(W);
};

I don't like promoting methods to classes, so NovirtualDispatch3 is  
initially unattractive to me. However, there are practical benefits.

It allows separate compilation by defining the operator()(Foo*)  
overload in Foo.c. The declarations must be visible for an algorithm  
invoked from Value, though.
It can dispatch algorithms that take arguments by passing an Algo  
instance using the second overload.
Overloads on the V parameter could dispatch over subtypes.
These properties make it applicable for users of Value, not just its  
implementation.

All of these techniques can follow the class hierarchy automatically.  
In the first two cases, a base class will provide a default  
implementation. In the lattermost case, undefined overloads will fall  
back to the base class.

— Gordon

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20071209/7d838792/attachment.html>


More information about the llvm-commits mailing list