From: Egor Bogatov Date: Fri, 11 Oct 2019 19:09:08 +0000 (+0300) Subject: Enable more hw intrinsics for AOT (mono/mono#17160) X-Git-Tag: submit/tizen/20210909.063632~10331^2~5^2~368 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=f361cb631c240f59a5ca329d84b2b2f70921ab51;p=platform%2Fupstream%2Fdotnet%2Fruntime.git Enable more hw intrinsics for AOT (mono/mono#17160) * Enable more hw intrinsics for AOT * Address feedback * does it fix the failure? * fix loadedllvm * Address feedback * fix copy-paste * forgot MONO_LLVM_INTERNAL Commit migrated from https://github.com/mono/mono/commit/9cc5ea3862894a10d87a51e302893b0165e4850c --- diff --git a/src/mono/mono/mini/aot-compiler.c b/src/mono/mono/mini/aot-compiler.c index 54ccdce..3a8ce48 100644 --- a/src/mono/mono/mini/aot-compiler.c +++ b/src/mono/mono/mini/aot-compiler.c @@ -8018,7 +8018,7 @@ parse_cpu_features (const gchar *attr) // TODO: neon, sha1, sha2, asimd, etc... #endif - if (!enabled) + if (enabled) mono_cpu_features_enabled = (MonoCPUFeatures) (mono_cpu_features_enabled | feature); else mono_cpu_features_disabled = (MonoCPUFeatures) (mono_cpu_features_disabled | feature); diff --git a/src/mono/mono/mini/intrinsics.c b/src/mono/mono/mini/intrinsics.c index a10fa51..f9b5eb3 100644 --- a/src/mono/mono/mini/intrinsics.c +++ b/src/mono/mono/mini/intrinsics.c @@ -135,7 +135,7 @@ llvm_emit_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign opcode = OP_TRUNCF; } #if defined(TARGET_X86) || defined(TARGET_AMD64) - else if (!strcmp (cmethod->name, "Round") && !cfg->compile_aot && (mono_arch_cpu_enumerate_simd_versions () & SIMD_VERSION_SSE41)) { + else if (!strcmp (cmethod->name, "Round") && (mini_get_cpu_features (cfg) & MONO_CPU_X86_SSE41) != 0) { // special case: emit vroundps for MathF.Round directly instead of what llvm.round.f32 emits // to align with CoreCLR behavior int xreg = alloc_xreg (cfg); diff --git a/src/mono/mono/mini/mini-amd64.c b/src/mono/mono/mini/mini-amd64.c index 28cac2a..cd3621c 100644 --- a/src/mono/mono/mini/mini-amd64.c +++ b/src/mono/mono/mini/mini-amd64.c @@ -8737,7 +8737,7 @@ mono_arch_emit_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMetho } #endif - if (!cfg->compile_aot && (mono_arch_cpu_enumerate_simd_versions () & SIMD_VERSION_SSE41) && fsig->param_count == 1 && fsig->params [0]->type == MONO_TYPE_R8) { + if ((mini_get_cpu_features (cfg) & MONO_CPU_X86_SSE41) != 0 && fsig->param_count == 1 && fsig->params [0]->type == MONO_TYPE_R8) { int mode = -1; if (!strcmp (cmethod->name, "Round")) mode = 0; diff --git a/src/mono/mono/mini/mini-llvm-loaded.c b/src/mono/mono/mini/mini-llvm-loaded.c index df15283..6b0e0df 100644 --- a/src/mono/mono/mini/mini-llvm-loaded.c +++ b/src/mono/mono/mini/mini-llvm-loaded.c @@ -22,6 +22,7 @@ typedef struct { void (*emit_aot_data)(const char *symbol, guint8 *data, int data_len); void (*free_domain_info)(MonoDomain *domain); void (*create_vars)(MonoCompile *cfg); + MonoCPUFeatures (*get_cpu_features)(void); } LoadedBackend; static LoadedBackend backend; @@ -136,6 +137,8 @@ mono_llvm_load (const char* bpath) if (err) goto symbol_error; err = mono_dl_symbol (llvm_lib, "mono_llvm_create_vars", (void**)&backend.create_vars); if (err) goto symbol_error; + err = mono_dl_symbol (llvm_lib, "mono_llvm_get_cpu_features", (void**)&backend.get_cpu_features); + if (err) goto symbol_error; return TRUE; symbol_error: g_warning ("llvm symbol load failed: %s\n", err); @@ -143,6 +146,11 @@ symbol_error: return FALSE; } +MonoCPUFeatures mono_llvm_get_cpu_features (void) +{ + return backend.get_cpu_features (); +} + #else int diff --git a/src/mono/mono/mini/mini-llvm.h b/src/mono/mono/mini/mini-llvm.h index 6198167..e7df081 100644 --- a/src/mono/mono/mini/mini-llvm.h +++ b/src/mono/mono/mini/mini-llvm.h @@ -35,6 +35,6 @@ void mono_llvm_create_vars (MonoCompile *cfg) MONO_LLVM_INTERNAL; void mono_llvm_fixup_aot_module (void) MONO_LLVM_INTERNAL; gboolean mini_llvm_init (void); -MonoCPUFeatures mono_llvm_get_cpu_features (void); +MonoCPUFeatures mono_llvm_get_cpu_features (void) MONO_LLVM_INTERNAL; #endif diff --git a/src/mono/mono/mini/mini.c b/src/mono/mono/mini/mini.c index 4d6cef6..5a8d9eb 100644 --- a/src/mono/mono/mini/mini.c +++ b/src/mono/mono/mini/mini.c @@ -4301,3 +4301,25 @@ mono_target_pagesize (void) */ return 4 * 1024; } + +MonoCPUFeatures +mini_get_cpu_features (MonoCompile* cfg) +{ + MonoCPUFeatures features = (MonoCPUFeatures)0; +#if !defined(MONO_CROSS_COMPILE) + if (!cfg->compile_aot || cfg->use_current_cpu) { + // detect current CPU features if we are in JIT mode or AOT with use_current_cpu flag. +#if defined(ENABLE_LLVM) && !defined(MONO_LLVM_LOADED) + features = mono_llvm_get_cpu_features (); // llvm has a nice built-in API to detect features +#elif defined(TARGET_AMD64) + features = mono_arch_get_cpu_features (); +#endif + } +#endif + MonoCPUFeatures features_ = features; + + // apply parameters passed via -mattr + features = (MonoCPUFeatures) (features | mono_cpu_features_enabled); + features = (MonoCPUFeatures) (features & ~mono_cpu_features_disabled); + return features; +} diff --git a/src/mono/mono/mini/mini.h b/src/mono/mono/mini/mini.h index 8a77924..7305a8b 100644 --- a/src/mono/mono/mini/mini.h +++ b/src/mono/mono/mini/mini.h @@ -2846,6 +2846,8 @@ typedef enum { #endif } MonoCPUFeatures; +MonoCPUFeatures mini_get_cpu_features (MonoCompile* cfg); + enum { SIMD_COMP_EQ, SIMD_COMP_LT, diff --git a/src/mono/mono/mini/simd-intrinsics-netcore.c b/src/mono/mono/mini/simd-intrinsics-netcore.c index b474e77..072d3c5 100644 --- a/src/mono/mono/mini/simd-intrinsics-netcore.c +++ b/src/mono/mono/mini/simd-intrinsics-netcore.c @@ -55,33 +55,12 @@ enum { static int register_size; -static MonoCPUFeatures -get_cpu_features (MonoCompile* cfg) -{ - MonoCPUFeatures features = (MonoCPUFeatures)0; -#if !defined(MONO_CROSS_COMPILE) - if (!cfg->compile_aot || cfg->use_current_cpu) { - // detect current CPU features if we are in JIT mode or AOT with use_current_cpu flag. -#if defined(ENABLE_LLVM) - features = mono_llvm_get_cpu_features (); // llvm has a nice built-in API to detect features -#elif defined(TARGET_AMD64) - features = mono_arch_get_cpu_features (); -#endif - } -#endif - - // apply parameters passed via -mattr - features = (MonoCPUFeatures) (features | mono_cpu_features_enabled); - features = (MonoCPUFeatures) (features & ~mono_cpu_features_disabled); - return features; -} - void mono_simd_intrinsics_init (void) { register_size = 16; #if FALSE - if ((get_cpu_features () & MONO_CPU_X86_AVX) != 0) + if ((mini_get_cpu_features () & MONO_CPU_X86_AVX) != 0) register_size = 32; #endif /* Tell the class init code the size of the System.Numerics.Register type */ @@ -596,7 +575,7 @@ emit_x86_intrinsics (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature if (id == -1) return NULL; - supported = (get_cpu_features (cfg) & MONO_CPU_X86_POPCNT) != 0; + supported = (mini_get_cpu_features (cfg) & MONO_CPU_X86_POPCNT) != 0; is_64bit = !strcmp (class_name, "X64"); switch (id) { @@ -622,7 +601,7 @@ emit_x86_intrinsics (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature if (id == -1) return NULL; - supported = (get_cpu_features (cfg) & MONO_CPU_X86_LZCNT) != 0; + supported = (mini_get_cpu_features (cfg) & MONO_CPU_X86_LZCNT) != 0; is_64bit = !strcmp (class_name, "X64"); switch (id) { @@ -649,7 +628,7 @@ emit_x86_intrinsics (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature id = lookup_intrins (bmi1_methods, sizeof (bmi1_methods), cmethod); g_assert (id != -1); - supported = (get_cpu_features (cfg) & MONO_CPU_X86_BMI1) != 0; + supported = (mini_get_cpu_features (cfg) & MONO_CPU_X86_BMI1) != 0; is_64bit = !strcmp (class_name, "X64"); switch (id) { @@ -722,7 +701,7 @@ emit_x86_intrinsics (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature return NULL; id = lookup_intrins (bmi2_methods, sizeof (bmi2_methods), cmethod); g_assert (id != -1); - supported = (get_cpu_features (cfg) & MONO_CPU_X86_BMI2) != 0; + supported = (mini_get_cpu_features (cfg) & MONO_CPU_X86_BMI2) != 0; is_64bit = !strcmp (class_name, "X64"); switch (id) { @@ -886,36 +865,26 @@ mono_emit_simd_intrinsics (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign class_ns = m_class_get_name_space (cmethod->klass); class_name = m_class_get_name (cmethod->klass); -#ifdef TARGET_AMD64 // TODO: test and enable for x86 too if (cmethod->klass->nested_in) class_ns = m_class_get_name_space (cmethod->klass->nested_in), class_name, cmethod->klass->nested_in; + +#ifdef TARGET_AMD64 // TODO: test and enable for x86 too if (!strcmp (class_ns, "System.Runtime.Intrinsics.X86")) return emit_x86_intrinsics (cfg ,cmethod, fsig, args); #endif if (!strcmp (class_ns, "System.Runtime.Intrinsics")) { if (!strcmp (class_name, "Vector128`1")) - return emit_vector128_t (cfg ,cmethod, fsig, args); + return emit_vector128_t (cfg, cmethod, fsig, args); if (!strcmp (class_name, "Vector256`1")) - return emit_vector256_t (cfg ,cmethod, fsig, args); + return emit_vector256_t (cfg, cmethod, fsig, args); } - // FIXME: Make sure get_cpu_features is used where needed - if (cfg->compile_aot) - return NULL; - if (!strcmp (class_ns, "System.Numerics") && !strcmp (class_name, "Vector")) { - MonoInst *ins = emit_sys_numerics_vector (cfg, cmethod, fsig, args); - if (!ins) { - //printf ("M: %s %s\n", mono_method_get_full_name (cfg->method), mono_method_get_full_name (cmethod)); - } - return ins; - } - if (!strcmp (class_ns, "System.Numerics") && !strcmp (class_name, "Vector`1")) { - MonoInst *ins = emit_sys_numerics_vector_t (cfg, cmethod, fsig, args); - if (!ins) { - //printf ("M: %s %s\n", mono_method_get_full_name (cfg->method), mono_method_get_full_name (cmethod)); - } - return ins; + if (!strcmp (class_ns, "System.Numerics")) { + if (!strcmp (class_name, "Vector")) + return emit_sys_numerics_vector (cfg, cmethod, fsig, args); + if (!strcmp (class_name, "Vector`1")) + return emit_sys_numerics_vector_t (cfg, cmethod, fsig, args); } return NULL;