-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Optimize GetType with known type #87579
Conversation
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch Issue DetailsShould help with the codegen in this simple method with ; Assembly listing for method Program:A(C):System.Type
; Emitting BLENDED_CODE for X64 CPU with AVX - Windows
; optimized code
; rsp based frame
; partially interruptible
; No PGO data
; 0 inlinees with PGO data; 1 single block inlinees; 0 inlinees without PGO data
G_M000_IG01: ;; offset=0000H
sub rsp, 40
G_M000_IG02: ;; offset=0004H
call System.Object:GetType():System.Type:this
nop
G_M000_IG03: ;; offset=000AH
add rsp, 40
ret
; Total bytes of code 15
|
How is this different from #87101 except doing the work earlier? |
I missed that change when I originally opened this PR (I only checked if the latest preview did this optimization and it didn't) and when @SingleAccretion told me about it, I've decided to let the jobs run to see if SPMI shows any meaningful diffs cause of running earlier which allows folding of stuff like IsKnownConstant and since this also handles |
That can be handled in VN in my change by adding a nullref exceptionset I guess, I just didn't bother because the diffs were not too promising |
@MichalPetryka my guess is that the NativeAOT failures are because this brings into existence types that shouldn't exist. We have an optimization that optimizes MethodTables for things that shouldn't exist into a smaller data structure. Is it possible that for this code: Console.WriteLine(Holder.TheX.GetType());
sealed class X { }
sealed class Holder
{
public static X TheX = null;
} Codegen will replace this with this? Console.WriteLine(typeof(X)); The problem is that when we're doing optimized code generation, we need to compute the full set of types that had a MethodTable in the whole program. For the above program, we would not include MT for X because it was not needed. The failure you're hitting looks like a situation where we didn't expect the MT to be needed so we generated a gimped "MT" that doesn't actually have much in it (and we can't construct a System.Type for it, among other things). This should also be asserting the compiler. Related: dotnet/runtimelab#1128 |
It'd actually be like this: Nullcheck(Holder.TheX);
Console.WriteLine(typeof(X)); Which would prevent the code from getting to the typeof (and if possible I'd assume the compiler would fold the nullcheck to always true since it knows it can remove the metadata). new MyType().GetType().ToString(); Could the unused new removal cause NAOT to omit metadata after the transformation? |
Got a local repro. The codegen for: public string GenericFooFunc3<M>() { return this.GetType() + "::GenericFooFunc3 called on " + typeof(T) + "::" + typeof(M); } Is:
Notice we're grabbing the |
I've accidentally removed the shared generic check, readded it now, the issue is that we're getting invalid handled even with that. |
I'm still seeing the same bad codegen with your latest commit. |
Yeah that's the issue here, |
Unifies (Equality)Comparer.Default logic so that it matches between CoreCLR, NativeAOT, Mono in runtime and intrinsic implementations. Fixes devirt behaviour around Nullable types. Also enables devirt for non final types in CoreCLR and NativeAOT. Required for #87579. Fixes #87391. Co-authored-by: Jan Kotas <jkotas@microsoft.com>
Co-authored-by: Jan Kotas <jkotas@microsoft.com>
@MihuBot -dependsOn 88163 |
Diffs seem to mostly be regressions, closing this then. |
Should help with the codegen in this simple method with
C
being a sealed type: