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