[Crossgen2] Improve compilation throughput for types with many fields (#43195)
authorSimon Nattress <nattress@gmail.com>
Mon, 12 Oct 2020 19:05:47 +0000 (12:05 -0700)
committerGitHub <noreply@github.com>
Mon, 12 Oct 2020 19:05:47 +0000 (12:05 -0700)
`IsLayoutFixedInCurrentVersionBubble` is a fairly expensive algorithm and can be called very frequently for the same type during JIT compilation. Store the computed result so future lookups are fast.

Fixes https://github.com/dotnet/runtime/issues/38259

src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilation.cs
src/tests/issues.targets

index 628b356..8fceca0 100644 (file)
@@ -2,6 +2,7 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 
 using System;
+using System.Collections.Concurrent;
 using System.Collections.Generic;
 using System.Diagnostics;
 using System.IO;
@@ -236,6 +237,11 @@ namespace ILCompiler
         public ReadyToRunSymbolNodeFactory SymbolNodeFactory { get; }
         public ReadyToRunCompilationModuleGroupBase CompilationModuleGroup { get; }
         private readonly int? _customPESectionAlignment;
+        /// <summary>
+        /// Determining whether a type's layout is fixed is a little expensive and the question can be asked many times
+        /// for the same type during compilation so preserve the computed value.
+        /// </summary>
+        private ConcurrentDictionary<TypeDesc, bool> _computedFixedLayoutTypes = new ConcurrentDictionary<TypeDesc, bool>();
 
         internal ReadyToRunCodegenCompilation(
             DependencyAnalyzerBase<NodeFactory> dependencyGraph,
@@ -375,7 +381,7 @@ namespace ILCompiler
             }
         }
 
-        public bool IsLayoutFixedInCurrentVersionBubble(TypeDesc type)
+        private bool IsLayoutFixedInCurrentVersionBubbleInternal(TypeDesc type)
         {
             // Primitive types and enums have fixed layout
             if (type.IsPrimitive || type.IsEnum)
@@ -423,6 +429,9 @@ namespace ILCompiler
             return true;
         }
 
+        public bool IsLayoutFixedInCurrentVersionBubble(TypeDesc type) =>
+            _computedFixedLayoutTypes.GetOrAdd(type, (t) => IsLayoutFixedInCurrentVersionBubbleInternal(t));
+
         public bool IsInheritanceChainLayoutFixedInCurrentVersionBubble(TypeDesc type)
         {
             // This method is not expected to be called for value types
index befba6a..92403ca 100644 (file)
         <ExcludeList Include="$(XunitTestBinBase)/JIT/Regression/clr-x64-JIT/v4.0/devdiv374539/DevDiv_374539/*">
             <Issue>https://github.com/dotnet/runtime/issues/32732</Issue>
         </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/JIT/Regression/CLR-x86-JIT/V2.0-Beta2/b399444/**/*">
-            <Issue>https://github.com/dotnet/runtime/issues/38259</Issue>
-        </ExcludeList>
         <ExcludeList Include="$(XunitTestBinBase)/JIT/Regression/CLR-x86-JIT/v2.1/DDB/B168384/LdfldaHack/*">
             <Issue>https://github.com/dotnet/runtime/issues/615</Issue>
         </ExcludeList>