Sync shared crossgen2 files (#35504)
authorMichal Strehovský <MichalStrehovsky@users.noreply.github.com>
Mon, 27 Apr 2020 14:23:43 +0000 (16:23 +0200)
committerGitHub <noreply@github.com>
Mon, 27 Apr 2020 14:23:43 +0000 (07:23 -0700)
src/coreclr/src/tools/Common/Compiler/HardwareIntrinsicHelpers.cs
src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.cs
src/coreclr/src/tools/Common/JitInterface/CorInfoInstructionSet.cs
src/coreclr/src/tools/Common/JitInterface/ThunkGenerator/InstructionSetGenerator.cs
src/coreclr/src/tools/Common/JitInterface/UnboxingMethodDesc.cs
src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj
src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs
src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/JitInterface/UnboxingMethodDescFactory.cs [new file with mode: 0644]

index 8ec5a77..fbf7b61 100644 (file)
@@ -20,156 +20,5 @@ namespace ILCompiler
         {
             return !string.IsNullOrEmpty(InstructionSetSupport.GetHardwareIntrinsicId(method.Context.Target.Architecture, method.OwningType));
         }
-
-#if !READYTORUN
-        public static bool IsIsSupportedMethod(MethodDesc method)
-        {
-            return method.Name == "get_IsSupported";
-        }
-
-        public static MethodIL GetUnsupportedImplementationIL(MethodDesc method)
-        {
-            // The implementation of IsSupported for codegen backends that don't support hardware intrinsics
-            // at all is to return 0.
-            if (IsIsSupportedMethod(method))
-            {
-                return new ILStubMethodIL(method,
-                    new byte[] {
-                        (byte)ILOpcode.ldc_i4_0,
-                        (byte)ILOpcode.ret
-                    },
-                    Array.Empty<LocalVariableDefinition>(), null);
-            }
-
-            // Other methods throw PlatformNotSupportedException
-            MethodDesc throwPnse = method.Context.GetHelperEntryPoint("ThrowHelpers", "ThrowPlatformNotSupportedException");
-
-            return new ILStubMethodIL(method,
-                    new byte[] {
-                        (byte)ILOpcode.call, 1, 0, 0, 0,
-                        (byte)ILOpcode.br_s, unchecked((byte)-7),
-                    },
-                    Array.Empty<LocalVariableDefinition>(),
-                    new object[] { throwPnse });
-        }
-
-        /// <summary>
-        /// Generates IL for the IsSupported property that reads this information from a field initialized by the runtime
-        /// at startup. Returns null for hardware intrinsics whose support level is known at compile time
-        /// (i.e. they're known to be always supported or always unsupported).
-        /// </summary>
-        public static MethodIL EmitIsSupportedIL(MethodDesc method, FieldDesc isSupportedField)
-        {
-            Debug.Assert(IsIsSupportedMethod(method));
-            Debug.Assert(isSupportedField.IsStatic && isSupportedField.FieldType.IsWellKnownType(WellKnownType.Int32));
-
-            TargetDetails target = method.Context.Target;
-            MetadataType owningType = (MetadataType)method.OwningType;
-
-            // Check for case of nested "X64" types
-            if (owningType.Name == "X64")
-            {
-                if (target.Architecture != TargetArchitecture.X64)
-                    return null;
-
-                // Un-nest the type so that we can do a name match
-                owningType = (MetadataType)owningType.ContainingType;
-            }
-
-            int flag;
-            if ((target.Architecture == TargetArchitecture.X64 || target.Architecture == TargetArchitecture.X86)
-                && owningType.Namespace == "System.Runtime.Intrinsics.X86")
-            {
-                switch (owningType.Name)
-                {
-                    case "Aes":
-                        flag = XArchIntrinsicConstants.Aes;
-                        break;
-                    case "Pclmulqdq":
-                        flag = XArchIntrinsicConstants.Pclmulqdq;
-                        break;
-                    case "Sse3":
-                        flag = XArchIntrinsicConstants.Sse3;
-                        break;
-                    case "Ssse3":
-                        flag = XArchIntrinsicConstants.Ssse3;
-                        break;
-                    case "Lzcnt":
-                        flag = XArchIntrinsicConstants.Lzcnt;
-                        break;
-                    // NOTE: this switch is complemented by IsKnownSupportedIntrinsicAtCompileTime
-                    // in the method below.
-                    default:
-                        return null;
-                }
-            }
-            else
-            {
-                return null;
-            }
-
-            var emit = new ILEmitter();
-            ILCodeStream codeStream = emit.NewCodeStream();
-
-            codeStream.Emit(ILOpcode.ldsfld, emit.NewToken(isSupportedField));
-            codeStream.EmitLdc(flag);
-            codeStream.Emit(ILOpcode.and);
-            codeStream.EmitLdc(0);
-            codeStream.Emit(ILOpcode.cgt_un);
-            codeStream.Emit(ILOpcode.ret);
-
-            return emit.Link(method);
-        }
-
-        /// <summary>
-        /// Gets a value indicating whether the support for a given intrinsic is known at compile time.
-        /// </summary>
-        public static bool IsKnownSupportedIntrinsicAtCompileTime(MethodDesc method)
-        {
-            TargetDetails target = method.Context.Target;
-
-            if (target.Architecture == TargetArchitecture.X64
-                || target.Architecture == TargetArchitecture.X86)
-            {
-                var owningType = (MetadataType)method.OwningType;
-                if (owningType.Name == "X64")
-                {
-                    if (target.Architecture != TargetArchitecture.X64)
-                        return true;
-                    owningType = (MetadataType)owningType.ContainingType;
-                }
-
-                if (owningType.Namespace != "System.Runtime.Intrinsics.X86")
-                    return true;
-
-                // Sse and Sse2 are baseline required intrinsics.
-                // RyuJIT also uses Sse41/Sse42 with the general purpose Vector APIs.
-                // RyuJIT only respects Popcnt if Sse41/Sse42 is also enabled.
-                // Avx/Avx2/Bmi1/Bmi2 require VEX encoding and RyuJIT currently can't enable them
-                // without enabling VEX encoding everywhere. We don't support them.
-                // This list complements EmitIsSupportedIL above.
-                return owningType.Name == "Sse" || owningType.Name == "Sse2"
-                    || owningType.Name == "Sse41" || owningType.Name == "Sse42"
-                    || owningType.Name == "Popcnt"
-                    || owningType.Name == "Bmi1" || owningType.Name == "Bmi2"
-                    || owningType.Name == "Avx" || owningType.Name == "Avx2";
-            }
-
-            return false;
-        }
-
-        // Keep this enumeration in sync with startup.cpp in the native runtime.
-        private static class XArchIntrinsicConstants
-        {
-            public const int Aes = 0x0001;
-            public const int Pclmulqdq = 0x0002;
-            public const int Sse3 = 0x0004;
-            public const int Ssse3 = 0x0008;
-            public const int Sse41 = 0x0010;
-            public const int Sse42 = 0x0020;
-            public const int Popcnt = 0x0040;
-            public const int Lzcnt = 0x0080;
-        }
-#endif // !READYTORUN
     }
 }
index 3901cd3..292f42d 100644 (file)
@@ -109,8 +109,6 @@ namespace Internal.JitInterface
         [DllImport(JitSupportLibrary)]
         private extern static char* GetExceptionMessage(IntPtr obj);
 
-        private static readonly UnboxingMethodDescFactory _unboxingThunkFactory = new UnboxingMethodDescFactory();
-
         public static void Startup()
         {
             jitStartup(GetJitHost(JitConfigProvider.Instance.UnmanagedInstance));
@@ -874,7 +872,7 @@ namespace Internal.JitInterface
             {
                 if (impl.OwningType.IsValueType)
                 {
-                    impl = _unboxingThunkFactory.GetUnboxingMethod(impl);
+                    impl = getUnboxingThunk(impl);
                 }
 
                 return ObjectToHandle(impl);
index 92e987f..256fd8d 100644 (file)
@@ -396,12 +396,14 @@ namespace Internal.JitInterface
         public struct InstructionSetInfo
         {
             public readonly string Name;
+            public readonly string ManagedName;
             public readonly InstructionSet InstructionSet;
             public readonly bool Specifiable;
 
-            public InstructionSetInfo(string name, InstructionSet instructionSet, bool specifiable)
+            public InstructionSetInfo(string name, string managedName, InstructionSet instructionSet, bool specifiable)
             {
                 Name = name;
+                ManagedName = managedName;
                 InstructionSet = instructionSet;
                 Specifiable = specifiable;
             }
@@ -413,55 +415,55 @@ namespace Internal.JitInterface
             {
 
                 case TargetArchitecture.ARM64:
-                    yield return new InstructionSetInfo("base", InstructionSet.ARM64_ArmBase, true);
-                    yield return new InstructionSetInfo("neon", InstructionSet.ARM64_AdvSimd, true);
-                    yield return new InstructionSetInfo("aes", InstructionSet.ARM64_Aes, true);
-                    yield return new InstructionSetInfo("crc", InstructionSet.ARM64_Crc32, true);
-                    yield return new InstructionSetInfo("sha1", InstructionSet.ARM64_Sha1, true);
-                    yield return new InstructionSetInfo("sha2", InstructionSet.ARM64_Sha256, true);
-                    yield return new InstructionSetInfo("lse", InstructionSet.ARM64_Atomics, true);
-                    yield return new InstructionSetInfo("Vector64", InstructionSet.ARM64_Vector64, false);
-                    yield return new InstructionSetInfo("Vector128", InstructionSet.ARM64_Vector128, false);
+                    yield return new InstructionSetInfo("base", "ArmBase", InstructionSet.ARM64_ArmBase, true);
+                    yield return new InstructionSetInfo("neon", "AdvSimd", InstructionSet.ARM64_AdvSimd, true);
+                    yield return new InstructionSetInfo("aes", "Aes", InstructionSet.ARM64_Aes, true);
+                    yield return new InstructionSetInfo("crc", "Crc32", InstructionSet.ARM64_Crc32, true);
+                    yield return new InstructionSetInfo("sha1", "Sha1", InstructionSet.ARM64_Sha1, true);
+                    yield return new InstructionSetInfo("sha2", "Sha256", InstructionSet.ARM64_Sha256, true);
+                    yield return new InstructionSetInfo("lse", "", InstructionSet.ARM64_Atomics, true);
+                    yield return new InstructionSetInfo("Vector64", "", InstructionSet.ARM64_Vector64, false);
+                    yield return new InstructionSetInfo("Vector128", "", InstructionSet.ARM64_Vector128, false);
                     break;
 
                 case TargetArchitecture.X64:
-                    yield return new InstructionSetInfo("sse", InstructionSet.X64_SSE, true);
-                    yield return new InstructionSetInfo("sse2", InstructionSet.X64_SSE2, true);
-                    yield return new InstructionSetInfo("sse3", InstructionSet.X64_SSE3, true);
-                    yield return new InstructionSetInfo("ssse3", InstructionSet.X64_SSSE3, true);
-                    yield return new InstructionSetInfo("sse4.1", InstructionSet.X64_SSE41, true);
-                    yield return new InstructionSetInfo("sse4.2", InstructionSet.X64_SSE42, true);
-                    yield return new InstructionSetInfo("avx", InstructionSet.X64_AVX, true);
-                    yield return new InstructionSetInfo("avx2", InstructionSet.X64_AVX2, true);
-                    yield return new InstructionSetInfo("aes", InstructionSet.X64_AES, true);
-                    yield return new InstructionSetInfo("bmi", InstructionSet.X64_BMI1, true);
-                    yield return new InstructionSetInfo("bmi2", InstructionSet.X64_BMI2, true);
-                    yield return new InstructionSetInfo("fma", InstructionSet.X64_FMA, true);
-                    yield return new InstructionSetInfo("lzcnt", InstructionSet.X64_LZCNT, true);
-                    yield return new InstructionSetInfo("pclmul", InstructionSet.X64_PCLMULQDQ, true);
-                    yield return new InstructionSetInfo("popcnt", InstructionSet.X64_POPCNT, true);
-                    yield return new InstructionSetInfo("Vector128", InstructionSet.X64_Vector128, false);
-                    yield return new InstructionSetInfo("Vector256", InstructionSet.X64_Vector256, false);
+                    yield return new InstructionSetInfo("sse", "Sse", InstructionSet.X64_SSE, true);
+                    yield return new InstructionSetInfo("sse2", "Sse2", InstructionSet.X64_SSE2, true);
+                    yield return new InstructionSetInfo("sse3", "Sse3", InstructionSet.X64_SSE3, true);
+                    yield return new InstructionSetInfo("ssse3", "Ssse3", InstructionSet.X64_SSSE3, true);
+                    yield return new InstructionSetInfo("sse4.1", "Sse41", InstructionSet.X64_SSE41, true);
+                    yield return new InstructionSetInfo("sse4.2", "Sse42", InstructionSet.X64_SSE42, true);
+                    yield return new InstructionSetInfo("avx", "Avx", InstructionSet.X64_AVX, true);
+                    yield return new InstructionSetInfo("avx2", "Avx2", InstructionSet.X64_AVX2, true);
+                    yield return new InstructionSetInfo("aes", "Aes", InstructionSet.X64_AES, true);
+                    yield return new InstructionSetInfo("bmi", "Bmi1", InstructionSet.X64_BMI1, true);
+                    yield return new InstructionSetInfo("bmi2", "Bmi2", InstructionSet.X64_BMI2, true);
+                    yield return new InstructionSetInfo("fma", "Fma", InstructionSet.X64_FMA, true);
+                    yield return new InstructionSetInfo("lzcnt", "Lzcnt", InstructionSet.X64_LZCNT, true);
+                    yield return new InstructionSetInfo("pclmul", "Pclmulqdq", InstructionSet.X64_PCLMULQDQ, true);
+                    yield return new InstructionSetInfo("popcnt", "Popcnt", InstructionSet.X64_POPCNT, true);
+                    yield return new InstructionSetInfo("Vector128", "", InstructionSet.X64_Vector128, false);
+                    yield return new InstructionSetInfo("Vector256", "", InstructionSet.X64_Vector256, false);
                     break;
 
                 case TargetArchitecture.X86:
-                    yield return new InstructionSetInfo("sse", InstructionSet.X86_SSE, true);
-                    yield return new InstructionSetInfo("sse2", InstructionSet.X86_SSE2, true);
-                    yield return new InstructionSetInfo("sse3", InstructionSet.X86_SSE3, true);
-                    yield return new InstructionSetInfo("ssse3", InstructionSet.X86_SSSE3, true);
-                    yield return new InstructionSetInfo("sse4.1", InstructionSet.X86_SSE41, true);
-                    yield return new InstructionSetInfo("sse4.2", InstructionSet.X86_SSE42, true);
-                    yield return new InstructionSetInfo("avx", InstructionSet.X86_AVX, true);
-                    yield return new InstructionSetInfo("avx2", InstructionSet.X86_AVX2, true);
-                    yield return new InstructionSetInfo("aes", InstructionSet.X86_AES, true);
-                    yield return new InstructionSetInfo("bmi", InstructionSet.X86_BMI1, true);
-                    yield return new InstructionSetInfo("bmi2", InstructionSet.X86_BMI2, true);
-                    yield return new InstructionSetInfo("fma", InstructionSet.X86_FMA, true);
-                    yield return new InstructionSetInfo("lzcnt", InstructionSet.X86_LZCNT, true);
-                    yield return new InstructionSetInfo("pclmul", InstructionSet.X86_PCLMULQDQ, true);
-                    yield return new InstructionSetInfo("popcnt", InstructionSet.X86_POPCNT, true);
-                    yield return new InstructionSetInfo("Vector128", InstructionSet.X86_Vector128, false);
-                    yield return new InstructionSetInfo("Vector256", InstructionSet.X86_Vector256, false);
+                    yield return new InstructionSetInfo("sse", "Sse", InstructionSet.X86_SSE, true);
+                    yield return new InstructionSetInfo("sse2", "Sse2", InstructionSet.X86_SSE2, true);
+                    yield return new InstructionSetInfo("sse3", "Sse3", InstructionSet.X86_SSE3, true);
+                    yield return new InstructionSetInfo("ssse3", "Ssse3", InstructionSet.X86_SSSE3, true);
+                    yield return new InstructionSetInfo("sse4.1", "Sse41", InstructionSet.X86_SSE41, true);
+                    yield return new InstructionSetInfo("sse4.2", "Sse42", InstructionSet.X86_SSE42, true);
+                    yield return new InstructionSetInfo("avx", "Avx", InstructionSet.X86_AVX, true);
+                    yield return new InstructionSetInfo("avx2", "Avx2", InstructionSet.X86_AVX2, true);
+                    yield return new InstructionSetInfo("aes", "Aes", InstructionSet.X86_AES, true);
+                    yield return new InstructionSetInfo("bmi", "Bmi1", InstructionSet.X86_BMI1, true);
+                    yield return new InstructionSetInfo("bmi2", "Bmi2", InstructionSet.X86_BMI2, true);
+                    yield return new InstructionSetInfo("fma", "Fma", InstructionSet.X86_FMA, true);
+                    yield return new InstructionSetInfo("lzcnt", "Lzcnt", InstructionSet.X86_LZCNT, true);
+                    yield return new InstructionSetInfo("pclmul", "Pclmulqdq", InstructionSet.X86_PCLMULQDQ, true);
+                    yield return new InstructionSetInfo("popcnt", "Popcnt", InstructionSet.X86_POPCNT, true);
+                    yield return new InstructionSetInfo("Vector128", "", InstructionSet.X86_Vector128, false);
+                    yield return new InstructionSetInfo("Vector256", "", InstructionSet.X86_Vector256, false);
                     break;
 
             }
index ea4268f..ad5a210 100644 (file)
@@ -522,12 +522,14 @@ namespace Internal.JitInterface
         public struct InstructionSetInfo
         {
             public readonly string Name;
+            public readonly string ManagedName;
             public readonly InstructionSet InstructionSet;
             public readonly bool Specifiable;
 
-            public InstructionSetInfo(string name, InstructionSet instructionSet, bool specifiable)
+            public InstructionSetInfo(string name, string managedName, InstructionSet instructionSet, bool specifiable)
             {
                 Name = name;
+                ManagedName = managedName;
                 InstructionSet = instructionSet;
                 Specifiable = specifiable;
             }
@@ -548,9 +550,10 @@ namespace Internal.JitInterface
                     if (instructionSet.Architecture != architecture) continue;
                     bool instructionSetIsSpecifiable = !String.IsNullOrEmpty(instructionSet.CommandLineName);
                     string name = instructionSet.PublicName;
+                    string managedName = instructionSet.ManagedName;
                     string specifiable = instructionSetIsSpecifiable ? "true" : "false";
                     string instructionSetString = $"InstructionSet.{architecture}_{instructionSet.JitName}";
-                    tr.WriteLine($"                    yield return new InstructionSetInfo(\"{name}\", {instructionSetString}, {specifiable});");
+                    tr.WriteLine($"                    yield return new InstructionSetInfo(\"{name}\", \"{managedName}\", {instructionSetString}, {specifiable});");
                 }
                 tr.WriteLine("                    break;");
             }
index b21a721..817e6f3 100644 (file)
@@ -3,7 +3,6 @@
 // See the LICENSE file in the project root for more information.
 
 using System;
-using System.Collections.Concurrent;
 using System.Collections.Generic;
 using System.Diagnostics;
 using Internal.TypeSystem;
@@ -80,25 +79,6 @@ namespace Internal.JitInterface
 #endif
     }
 
-    internal class UnboxingMethodDescFactory : ConcurrentDictionary<MethodDesc, UnboxingMethodDesc>
-    {
-        private Func<MethodDesc, UnboxingMethodDesc> _factoryDelegate;
-        private UnboxingMethodDesc CreateUnboxingMethod(MethodDesc method)
-        {
-            return new UnboxingMethodDesc(method, this);
-        }
-
-        public UnboxingMethodDescFactory()
-        {
-            _factoryDelegate = CreateUnboxingMethod;
-        }
-
-        public UnboxingMethodDesc GetUnboxingMethod(MethodDesc method)
-        {
-            return GetOrAdd(method, _factoryDelegate);
-        }
-    }
-
     internal static class UnboxingMethodDescExtensions
     {
         public static bool IsUnboxingThunk(this MethodDesc method)
index f36eb5f..2374f68 100644 (file)
     <Compile Include="Compiler\SystemObjectFieldLayoutAlgorithm.cs" />
     <Compile Include="IL\ReadyToRunILProvider.cs" />
     <Compile Include="JitInterface\CorInfoImpl.ReadyToRun.cs" />
+    <Compile Include="JitInterface\UnboxingMethodDescFactory.cs" />
     <Compile Include="ObjectWriter\SectionBuilder.cs" />
     <Compile Include="ObjectWriter\R2RPEBuilder.cs" />
     <Compile Include="ObjectWriter\RelocationHelper.cs" />
index 433b69a..5c59632 100644 (file)
@@ -141,6 +141,8 @@ namespace Internal.JitInterface
         private NativeVarInfo[] _debugVarInfos;
         private ArrayBuilder<MethodDesc> _inlinedMethods;
 
+        private static readonly UnboxingMethodDescFactory s_unboxingThunkFactory = new UnboxingMethodDescFactory();
+
         public CorInfoImpl(ReadyToRunCodegenCompilation compilation)
             : this()
         {
@@ -1884,7 +1886,7 @@ namespace Internal.JitInterface
 
                             if ((td.IsValueType) && !md.Signature.IsStatic)
                             {
-                                md = _unboxingThunkFactory.GetUnboxingMethod(md);
+                                md = getUnboxingThunk(md);
                             }
 
                             symbolNode = _compilation.SymbolNodeFactory.CreateReadyToRunHelper(
@@ -1907,6 +1909,11 @@ namespace Internal.JitInterface
             }
         }
 
+        private MethodDesc getUnboxingThunk(MethodDesc method)
+        {
+            return s_unboxingThunkFactory.GetUnboxingMethod(method);
+        }
+
         private CORINFO_METHOD_STRUCT_* embedMethodHandle(CORINFO_METHOD_STRUCT_* handle, ref void* ppIndirection)
         {
             // TODO: READYTORUN FUTURE: Handle this case correctly
diff --git a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/JitInterface/UnboxingMethodDescFactory.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/JitInterface/UnboxingMethodDescFactory.cs
new file mode 100644 (file)
index 0000000..9763e88
--- /dev/null
@@ -0,0 +1,31 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Diagnostics;
+using Internal.TypeSystem;
+
+namespace Internal.JitInterface
+{
+    internal class UnboxingMethodDescFactory : ConcurrentDictionary<MethodDesc, UnboxingMethodDesc>
+    {
+        private Func<MethodDesc, UnboxingMethodDesc> _factoryDelegate;
+        private UnboxingMethodDesc CreateUnboxingMethod(MethodDesc method)
+        {
+            return new UnboxingMethodDesc(method, this);
+        }
+
+        public UnboxingMethodDescFactory()
+        {
+            _factoryDelegate = CreateUnboxingMethod;
+        }
+
+        public UnboxingMethodDesc GetUnboxingMethod(MethodDesc method)
+        {
+            return GetOrAdd(method, _factoryDelegate);
+        }
+    }
+}
\ No newline at end of file