I've been experimenting with devirtualizing method calls, and
sometimes a construct like this can pay dividends:

  /* Fetch vtable entry into D.914, then...  */
  if (D.914 != bar)
    {
      /* Make virtual call.  */
      D.915 = D.914 (this.7, p.6);
      iftmp.8 = D.915;
    }
  else
    {
      /* Make direct call.  */
      D.916 = bar (this.7, p.6);
      iftmp.8 = D.916;
    }

but this is only useful if the call to bar() gets inlined.

On its own this optimization isn't very interesting, but it exposes
more optimization opportunities.

So, I suppose that what I need to do is make a pass over the trees
after inlining to convert this back into a simple virtual call.
However, once I do this the CFG is no longer correct, because there's
no longer an edge to bar().

Another possibility is to have the inliner convert virtual calls into
something like the above.  Maybe the real solution to all of is is to
have a representation for virtual calls in the IL, but...

So, what I'm thinking of doing is writing a post-inlining pass that
rewrites the trees and then tidies up the CFG.  Is this the right
approach?

Thanks,
Andrew.

Reply via email to