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

_______________________________________________
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits

Reply via email to