Speed up crossgen2 by a couple percent (#63234)
authorMichal Strehovský <MichalStrehovsky@users.noreply.github.com>
Fri, 31 Dec 2021 21:21:42 +0000 (06:21 +0900)
committerGitHub <noreply@github.com>
Fri, 31 Dec 2021 21:21:42 +0000 (06:21 +0900)
I ran crossgen2 compiling a Release CoreLib under a profiler and this stood out quite a bit. The JIT-based CoreLib doesn't have the `Array<T>` type so `GetType` was walking all types in CoreLib.

I split this logic out to an ILC-specific file. I don't remember this showing up in the profiles for ILC, but I added a cache nevertheless.

src/coreclr/tools/Common/Compiler/TypeExtensions.cs
src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/CompilerTypeSystemContext.Aot.cs
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCompilerContext.cs

index 8042359..df3282e 100644 (file)
@@ -28,22 +28,7 @@ namespace ILCompiler
         /// </summary>
         public static DefType GetClosestDefType(this TypeDesc type)
         {
-            if (type.IsArray)
-            {
-                if (!type.IsArrayTypeWithoutGenericInterfaces())
-                {
-                    MetadataType arrayShadowType = type.Context.SystemModule.GetType("System", "Array`1", throwIfNotFound: false);
-                    if (arrayShadowType != null)
-                    {
-                        return arrayShadowType.MakeInstantiatedType(((ArrayType)type).ElementType);
-                    }
-                }
-
-                return type.Context.GetWellKnownType(WellKnownType.Array);
-            }
-
-            Debug.Assert(type is DefType);
-            return (DefType)type;
+            return ((CompilerTypeSystemContext)type.Context).GetClosestDefType(type);
         }
 
         /// <summary>
index 24c0767..33305d2 100644 (file)
@@ -27,6 +27,7 @@ namespace ILCompiler
 
         private TypeDesc[] _arrayOfTInterfaces;
         private ArrayOfTRuntimeInterfacesAlgorithm _arrayOfTRuntimeInterfacesAlgorithm;
+        private MetadataType _arrayOfTType;
 
         public CompilerTypeSystemContext(TargetDetails details, SharedGenericsMode genericsMode, DelegateFeature delegateFeatures)
             : base(details)
@@ -169,6 +170,23 @@ namespace ILCompiler
             return new DelegateInfo(delegateType, _delegateFeatures);
         }
 
+        internal DefType GetClosestDefType(TypeDesc type)
+        {
+            if (type.IsArray)
+            {
+                if (!type.IsArrayTypeWithoutGenericInterfaces())
+                {
+                    MetadataType arrayShadowType = _arrayOfTType ?? (_arrayOfTType = SystemModule.GetType("System", "Array`1"));
+                    return arrayShadowType.MakeInstantiatedType(((ArrayType)type).ElementType);
+                }
+
+                return GetWellKnownType(WellKnownType.Array);
+            }
+
+            Debug.Assert(type is DefType);
+            return (DefType)type;
+        }
+
         private readonly LazyGenericsSupport.GenericCycleDetector _genericCycleDetector = new LazyGenericsSupport.GenericCycleDetector();
 
         public void DetectGenericCycles(TypeSystemEntity owner, TypeSystemEntity referent)
index 44bddc1..fdb6fab 100644 (file)
@@ -17,6 +17,17 @@ namespace ILCompiler
         {
             _genericsMode = genericsMode;
         }
+
+        internal DefType GetClosestDefType(TypeDesc type)
+        {
+            if (type.IsArray)
+            {
+                return GetWellKnownType(WellKnownType.Array);
+            }
+
+            Debug.Assert(type is DefType);
+            return (DefType)type;
+        }
     }
 
     public partial class ReadyToRunCompilerContext : CompilerTypeSystemContext