-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
NativeAOT: Guarded devirtualization #64497
Conversation
Tagging subscribers to this area: @JulieLeeMSFT Issue DetailsThis PR introduces Current implementation only handles single-impl/subclasses/class case, will be extended to multiple with #59604 Example: public interface IFoo
{
void SayHello();
}
public class FooImpl : IFoo
{
public void SayHello() => Console.WriteLine("Hello!");
}
class Test
{
static void Main()
{
Test(new FooImpl());
Console.ReadKey();
}
[MethodImpl(MethodImplOptions.NoInlining)]
static void Test(IFoo f) => f.SayHello();
} Codegen for ; Method MyType:Test(IFoo)
G_M19269_IG01:
sub rsp, 40
G_M19269_IG02:
cmp dword ptr [rcx], ecx
mov rcx, 0xD1FFAB1E ; "Hello!"
mov rcx, gword ptr [rcx]
call System.Console:WriteLine(System.String) ; <-- SayHello was devirtualized & inlined
nop ; <-- no fallbacks as with PGO on CoreCLR
G_M19269_IG03:
add rsp, 40
ret
; Total bytes of code: 30
(I was using JIT for demo,
|
Spicy pull request!
Here's a blueprint of what should work:
We'll have to be a little careful about generic classes/interfaces because new instantiations of those can happen at runtime (e.g. if we compiled/saw |
…iveaot # Conflicts: # src/coreclr/inc/jiteeversionguid.h # src/coreclr/tools/Common/JitInterface/CorInfoBase.cs # src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs # src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h # src/coreclr/vm/jitinterface.cpp
Ping myself |
@EgorBo friendly ping. |
Is the remaining work on the guarded devirtualization on the VM side or jit side? I could help pick up the VM side. This would be a very cool thing to have |
@MichalStrehovsky @kant2002 ah, completely forgot about this one - I'll finish it tomorrow 🙂 |
# Conflicts: # src/coreclr/inc/jiteeversionguid.h # src/coreclr/jit/importer.cpp # src/coreclr/tools/Common/JitInterface/CorInfoBase.cs # src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs # src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ILScanner.cs
@MichalStrehovsky could you please help me to figure out how to incorporate changes from #73218 (I fixed the merge conflict with "using mine") |
Another conflict is incoming in #73839 and that one is a fix for a blocking bug. We can try after |
/azp run runtime-extra-platforms |
Azure Pipelines successfully started running 1 pipeline(s). |
The NativeAOT runs look good. The failures exist in the baseline, but if I don't baseline them apparently nobody else will... (I'm looking into baselining them) |
src/coreclr/jit/lclvars.cpp
Outdated
@@ -3174,6 +3174,16 @@ void Compiler::lvaSetClass(unsigned varNum, CORINFO_CLASS_HANDLE clsHnd, bool is | |||
return; | |||
} | |||
|
|||
if (clsHnd != NO_CLASS_HANDLE && !isExact && IsTargetAbi(CORINFO_NATIVEAOT_ABI)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a meaningful perf saving from skipping getExactClasses call outside NATIVEAOT_ABI? I assume it would just be a no-op. Not doing this outside NativeAOT is a policy decision and JIT generally tries to leave those to the EE side.
Could we instead key this off of JitEnableDevirtualization (or maybe a new config switch specifically for this)? Just so we have some way to see the impact of this or disable it if it misbehaves. On ilc side we have --noscan
that would disable this, but it also disables a bunch of other things because it's for the whole program analysis in general.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, are there any concerns about a JIT-EE GUID change this close to the snap if we take it?
I personally don't see any Merging now, CI is green (except the spmi jobs which fail due to jit-ee guid update) |
Any further "last minute" .NET 7 PRs will fail SPMI jobs until the collection happens, which will complete after the fork. |
Right, which is why merging this last minute is fine, new PRs which will be rebased won't make it to green anyway (20 minutes left) - am I right? |
Snap is at 4pm PDT, so there are 4+ hours left.... |
Oops, I thought it's noon 🙁 |
@EgorBo I think this change is causing SuperPMI collection to fail even on a simple "hello world" app - |
Contributes to #64242
This PR introduces
getExactClasses
JIT-EE API, VM may give JIT a hint that a specific virtual call will always be of one of the specific classes and no other class can be loaded/added so we can skip "fallback" path.Current implementation only handles single-impl/subclass/struct case, will be extended to multiple with #59604
Example:
Codegen for
Test
:(I was using JIT for demo,
getExactClasses
is not implemented on VM side yet, @MichalStrehovsky any pointers how to get all possible implementations/subclasses for a specific type? (see https://github.com/dotnet/runtime/pull/64497/files#diff-132a77bcd3f74cf0e0b04fbccda246c97c91e40562d78cb01fff61cf69403573R2930)TODO: