Allow jit to examine type of initonly static ref typed fields by AndyAyersMS · Pull Request #20886 · dotnet/coreclr (original) (raw)

@jkotas, @erozenfeld PTAL
cc @dotnet/jit-contrib @davidwrighton

Impact of this on codegen is a bit tricky to evaluate, but here's one take.

Jit-diffs (in the new --ccrtors mode) shows:

Total bytes of diff: 41126 (0.11% of base)
    diff is a regression.

Total byte diff includes 42793 bytes from reconciling methods
        Base had    0 unique methods,        0 unique bytes
        Diff had  155 unique methods,    42793 unique bytes

Top file regressions by size (bytes):
       45139 : System.Private.CoreLib.dasm (1.45% of base)
        1051 : Microsoft.CodeAnalysis.dasm (0.07% of base)
          70 : System.Private.DataContractSerialization.dasm (0.01% of base)

Top file improvements by size (bytes):
       -3646 : System.Private.Xml.dasm (-0.10% of base)
        -226 : Microsoft.CodeAnalysis.VisualBasic.dasm (0.00% of base)
        -158 : System.Data.Common.dasm (-0.01% of base)
        -148 : System.Net.Http.dasm (-0.03% of base)
        -134 : Newtonsoft.Json.dasm (-0.02% of base)

47 total files with size differences (44 improved, 3 regressed), 82 unchanged.

Top method regressions by size (bytes):
        2304 (     8 of base) : System.Private.CoreLib.dasm - System.Reflection.CustomAttribute:GetCustomAttributes(ref,int,int,ref,bool,byref):ref (0 base, 1 diff methods)
        1453 (     8 of base) : System.Private.CoreLib.dasm - System.AppDomain:Setup(ref):ref (0 base, 1 diff methods)
        1301 (     8 of base) : System.Private.CoreLib.dasm - System.RuntimeType:GetMethodBase(ref,long):ref (0 base, 1 diff methods)
        1173 (     8 of base) : System.Private.CoreLib.dasm - System.Reflection.CustomAttribute:FilterCustomAttributeRecord(struct,struct,byref,ref,struct,ref,bool,ref,byref,byref,byref,byref,byref):bool (0 base, 1 diff methods)
        1157 (     8 of base) : System.Private.CoreLib.dasm - System.MulticastDelegate:CombineImpl(ref):ref:this (0 base, 1 diff methods)

Top method improvements by size (bytes):
        -505 (-6.88% of base) : System.Private.Xml.dasm - XmlUntypedConverter:ChangeType(ref,ref,ref):ref:this (2 methods)
        -298 (-10.40% of base) : System.Private.Xml.dasm - XmlNumeric10Converter:ChangeType(ref,ref,ref):ref:this (2 methods)
        -273 (-16.99% of base) : System.Private.Xml.dasm - XmlListConverter:ChangeListType(ref,ref,ref):ref:this
        -224 (-5.77% of base) : System.Private.Xml.dasm - XmlAnyConverter:ChangeType(ref,ref,ref):ref:this (2 methods)
        -209 (-39.51% of base) : System.Private.Xml.dasm - XmlUntypedConverter:SupportsType(ref):bool:this

Top method regressions by size (percentage):
         232 (     8 of base) : System.Private.CoreLib.dasm - System.AppDomain:SetupDomain(bool,ref,ref,ref,ref):this
         197 (     8 of base) : System.Private.CoreLib.dasm - System.AppDomain:SetupFusionStore(ref,ref):this (0 base, 1 diff methods)
         330 (     8 of base) : System.Private.CoreLib.dasm - System.AppDomainSetup:SetupDefaults(ref,bool):this (0 base, 1 diff methods)
          26 (     8 of base) : System.Private.CoreLib.dasm - System.String:LastIndexOfAny(ref):int:this (0 base, 1 diff methods)
         391 (     8 of base) : System.Private.CoreLib.dasm - System.String:LastIndexOfAny(ref,int,int):int:this (0 base, 1 diff methods)

Top method improvements by size (percentage):
         -25 (-50.00% of base) : Microsoft.CodeAnalysis.dasm - <>c__DisplayClass13_0:<ClearAnalysisScopeState>b__0(ref):bool:this
        -209 (-39.51% of base) : System.Private.Xml.dasm - XmlUntypedConverter:SupportsType(ref):bool:this
         -53 (-37.59% of base) : System.Private.Xml.dasm - XmlListConverter:IsListType(ref):bool:this
         -54 (-35.53% of base) : System.Private.Xml.dasm - XmlMiscConverter:ChangeTypeWildcardSource(ref,ref,ref):ref:this
         -54 (-35.53% of base) : System.Private.Xml.dasm - XmlAnyConverter:ChangeTypeWildcardSource(ref,ref,ref):ref:this

603 total methods with size differences (403 improved, 200 regressed), 190032 unchanged.

Most of the regressions here are "reconciliation" issues in corelib, where we see different methods get jitted. Almost certainly a testing artifact, though something I need to look at more closely.

Improvements are seen for fields like current culture and text encoder, some specialized type comparisons, and number of cases where we already were devirtualizing but can now also omit a null check.

Also makes some headway into the patterns for the test case in #17273 that we don't optimize very well; eg in Common() we now can do a late devirtualization.

;; before mov rax, qword ptr [rcx] mov rax, qword ptr [rax+64] call qword ptr [rax+32]EqualityComparer`1:Equals(ref,ref):bool:this

;; after call GenericEqualityComparer`1:Equals(ref,ref):bool:this