-
Notifications
You must be signed in to change notification settings - Fork 4.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Generic virtual method devirtualization does not happen #32129
Comments
Interface calls to generic methods are handled via When devirtualizing interface calls we must have an exact class or a sealed class; sealing the method is not sufficient. |
Exact class would mean, Rereading this refreshed my memory on class vs method sealing
This is a shame, anything that can be done here? |
Yes.
Aside from sealing classes, you mean? This behavior of interfaces is deeply ingrained in the spec. Down the road, we may start to make speculative bets during codegen -- either guarded or unguarded -- and then have appropriate recovery mechanisms kick in when the bets are wrong. So if at jit time a method has no possible overriders, we could speculatively devirtualize. |
Yes as sealed classes aren't the default many opportunities are missed. Is this the type confusion w.r.t. sealed methods and explicit implementations you were talking about? Or isn't it expressible in C#? public interface IFoo
{
void M();
}
public class A
{
public virtual void M() { }
}
public class B : A {
public sealed override void M() { }
}
public class C : B, IFoo
{
void IFoo.M() { }
} I've been trying to parse some of your comments like the one shared earlier but also
And I guess I just can't see what the minimal repro of this is. |
Yes, that's the minimal repro; I had this wrong originally and fixed it in dotnet/coreclr#10371, which introduced this similar test case: runtime/src/coreclr/tests/src/JIT/opt/Devirtualization/generic.cs Lines 46 to 55 in fff8f5a
Even with AOT we can guardedly speculate; C++ compilers do this all the time. |
That must work out less well if you don't also do PGO, agreed that technically there's no limitation, it just requires more work to pay off for AOT.
Neat, looking at both examples in IL I do see quite a few ways to discern whether this (sealed + overriding G) is the case. Some of the discriminators as I see them:
Using one, or a combination of these, should allow relaxing the requirements to devirtualize. I wouldn't mind trying my hand at this if you think it's possible. |
I do not think it is possible in general. Say the "best type" we have at jit time is a non-final, inexact The only way to future proof this is to either know For virtual calls, the override patterns are more constrained, and final methods are usually sufficient (but even this has its subtleties, see #10809). |
Right! Now I'm on the same page, I got tripped up by interface Ix
{
int F();
}
public class A : Ix
{
int Ix.F() => 1;
}
public class B: A, Ix
{
int Ix.F() => 2;
} Overrides on the same method yet A was already final, writing I was blissfully unaware that interfaces were this deeply virtual, but then again I often use interfaces more like constraints than actual types. Viewing them as types I can understand why having them be virtual this way makes a bit more sense. Thinking deeply about this in the context of #10809 after learning some of the subtleties of Thank you for indulging me! |
We now have guarded devirtualization that bridges this gap, so I am going to close this issue. Feel free to reopen if you think there are more opportunities or that I missed something. |
Consider the following benchmark example:
Results show the JIT can succesfully devirtualize
IFooViaImpl
by observing the concrete type before the cast. Yet it fails to do so forIFooGenericViaImpl
while those - extremely slow calls - would benefit most from this working correctly./cc @AndyAyersMS
EDIT: I have added a direct generic call for scale
What I also noticed is that the class itself needs to be
sealed
as well forIFooViaImpl
to devirtualize, yet that method is alreadyfinal
in IL, this seems like a rather small fix.category:cq
theme:devirtualization
skill-level:expert
cost:large
The text was updated successfully, but these errors were encountered: