http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55913
Martin Jambor <jamborm at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC|mjambor at suse dot cz |jamborm at gcc dot gnu.org --- Comment #1 from Martin Jambor <jamborm at gcc dot gnu.org> 2013-01-09 23:47:51 UTC --- Uh oh, but it is a very special context, in fact a combination of two contexts: In the call from wxBufferedPaintDC::wxBufferedPaintDC to wxBufferedDC::InitCommon, parameter this is always KNOWN-TYPE, because it is a call passing this pointer (or its artificial component) from constructor and thus dynamic type change detection kicks in and in this case even discovers the new type as wxBufferedPaintDC. The resulting jump function is KNOWN-TYPE and its evaluation is not dependent on actual value of the parameter of wxBufferedPaintDC::wxBufferedPaintDC. However, the dc parameter is a different story. The resultant jump function is ANCESTOR because that is most descriptive. As it happens, evaluation of that function requires that we know the actual value or type of the parameter of wxBufferedPaintDC::wxBufferedPaintDC. And that is the problem, IPA-CP currently thinks that call sequence OnPaint->wxBufferedPaintDC->InitCommon leads to a known type of dc whereas SomethingElse->wxBufferedPaintDC->InitCommon leads to unknown type. That is why it only uses parameter this to devirtualize (if the caller was not a constructor, we'd need the context in both cases and it would not look weird). Type of dc is probably also always known because it is generated as an address of a non-artificial component which is something that always has a known type (provided that is a good enough guarantee in gimple when there are no memory accesses but it probably is, and that we can avoid all potential dynamic type changes). If we extended PASS-THROUGH and ANCESTOR jump functions with a flag and the ability to carry all information that the KNOWN-TYPE jump functions have, then we could detect we do not need caller context in these situations. But that is a fairly big change, certainly not doable for 4.8. Devirtualization done by tracking vtable pointers in aggregate jump functions could also help. If we did not mind we would end up with two copies of InitCommon, we could sort the values according to increasing number of edges they depend on when evaluating them.