Crossgen method bodies having ARM64 intrinsic (#38060)
authorKunal Pathak <Kunal.Pathak@microsoft.com>
Sat, 20 Jun 2020 00:30:23 +0000 (17:30 -0700)
committerGitHub <noreply@github.com>
Sat, 20 Jun 2020 00:30:23 +0000 (17:30 -0700)
* enable methods containing arm64 intrinsic to crossgen

* Unconditionally set ArmBase/AdvSimd

* added a comment

* added the missing #endif

* Move ArmBase/AdvSimd setting inside host_arm64

* review comments

src/coreclr/src/pal/src/misc/jitsupport.cpp
src/coreclr/src/vm/methodtablebuilder.cpp
src/coreclr/src/zap/zapinfo.cpp

index db9b4e2..b21a1ed 100644 (file)
@@ -22,6 +22,14 @@ PAL_GetJitCpuCapabilityFlags(CORJIT_FLAGS *flags)
     _ASSERTE(flags);
 
     CORJIT_FLAGS &CPUCompileFlags = *flags;
+
+#if defined(TARGET_ARM64)
+    // Enable ARM64 based flags by default so we always crossgen
+    // ARM64 intrinsics for Linux
+    CPUCompileFlags.Set(InstructionSet_ArmBase);
+    CPUCompileFlags.Set(InstructionSet_AdvSimd);
+#endif // defined(TARGET_ARM64)
+
 #if defined(HOST_ARM64)
 #if HAVE_AUXV_HWCAP_H
     unsigned long hwCap = getauxval(AT_HWCAP);
@@ -32,7 +40,6 @@ PAL_GetJitCpuCapabilityFlags(CORJIT_FLAGS *flags)
 // From a single binary distribution perspective, compiling with latest kernel asm/hwcap.h should
 // include all published flags.  Given flags are merged to kernel and published before silicon is
 // available, using the latest kernel for release should be sufficient.
-    CPUCompileFlags.Set(InstructionSet_ArmBase);
 #ifdef HWCAP_AES
     if (hwCap & HWCAP_AES)
         CPUCompileFlags.Set(InstructionSet_Aes);
@@ -94,8 +101,11 @@ PAL_GetJitCpuCapabilityFlags(CORJIT_FLAGS *flags)
 //        CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_SHA3);
 #endif
 #ifdef HWCAP_ASIMD
-    if (hwCap & HWCAP_ASIMD)
-        CPUCompileFlags.Set(InstructionSet_AdvSimd);
+    if ((hwCap & HWCAP_ASIMD) == 0)
+    {
+        fprintf(stderr, "AdvSimd is not supported on the processor.\n");
+        abort();
+    }
 #endif
 #ifdef HWCAP_ASIMDRDM
 //    if (hwCap & HWCAP_ASIMDRDM)
@@ -117,13 +127,6 @@ PAL_GetJitCpuCapabilityFlags(CORJIT_FLAGS *flags)
 //    if (hwCap & HWCAP_SVE)
 //        CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_SVE);
 #endif
-#else // !HAVE_AUXV_HWCAP_H
-    // CoreCLR SIMD and FP support is included in ARM64 baseline
-    // On exceptional basis platforms may leave out support, but CoreCLR does not
-    // yet support such platforms
-    // Set baseline flags if OS has not exposed mechanism for us to determine CPU capabilities
-    CPUCompileFlags.Set(InstructionSet_AdvSimd);
-//    CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_FP);
 #endif // HAVE_AUXV_HWCAP_H
 #endif // defined(HOST_ARM64)
     CPUCompileFlags.Set64BitInstructionSetVariants();
index 9c10e58..db0e802 100644 (file)
@@ -1481,10 +1481,10 @@ MethodTableBuilder::BuildMethodTableThrowing(
 #endif
         {
 #if defined(CROSSGEN_COMPILE)
-#if defined(TARGET_X86) || defined(TARGET_AMD64)
+#if defined(TARGET_X86) || defined(TARGET_AMD64) || defined(TARGET_ARM64)
             if ((!IsNgenPDBCompilationProcess()
                 && GetAppDomain()->ToCompilationDomain()->GetTargetModule() != g_pObjectClass->GetModule()))
-#endif // defined(TARGET_X86) || defined(TARGET_AMD64)
+#endif // defined(TARGET_X86) || defined(TARGET_AMD64) || defined(TARGET_ARM64)
             {
                 // Disable AOT compiling for managed implementation of hardware intrinsics.
                 // We specially treat them here to ensure correct ISA features are set during compilation
index e413b9a..be24061 100644 (file)
@@ -2147,10 +2147,16 @@ DWORD FilterNamedIntrinsicMethodAttribs(ZapInfo* pZapInfo, DWORD attribs, CORINF
         // is because they often change the code they emit based on what ISAs are supported by the compiler,
         // but we don't know what the target machine will support.
         //
-        // Additionally, we make sure none of the hardware intrinsic method bodies get pregenerated in crossgen
+        // Additionally, we make sure none of the hardware intrinsic method bodies (except ARM64) get pregenerated in crossgen
         // (see ZapInfo::CompileMethod) but get JITted instead. The JITted method will have the correct
         // answer for the CPU the code is running on.
-        fTreatAsRegularMethodCall = (fIsGetIsSupportedMethod && fIsPlatformHWIntrinsic) || (!fIsPlatformHWIntrinsic && fIsHWIntrinsic);
+
+        // For Arm64, AdvSimd/ArmBase is the baseline that is suported and hence we do pregenerate the method bodies
+        // of ARM64 harware intrinsic.
+        fTreatAsRegularMethodCall = (fIsGetIsSupportedMethod && fIsPlatformHWIntrinsic);
+#if !defined(TARGET_ARM64)
+        fTreatAsRegularMethodCall |= (!fIsPlatformHWIntrinsic && fIsHWIntrinsic);
+#endif 
 
         if (fIsPlatformHWIntrinsic)
         {