diff --git a/src/coreclr/inc/clrconfigvalues.h b/src/coreclr/inc/clrconfigvalues.h index 7b356b0744399..4dc8f2650858a 100644 --- a/src/coreclr/inc/clrconfigvalues.h +++ b/src/coreclr/inc/clrconfigvalues.h @@ -314,6 +314,7 @@ CONFIG_DWORD_INFO(INTERNAL_JitGCStress, W("JitGCStress"), 0, "GC stress mode for CONFIG_DWORD_INFO(INTERNAL_JitHeartbeat, W("JitHeartbeat"), 0, "") CONFIG_DWORD_INFO(INTERNAL_JitHelperLogging, W("JitHelperLogging"), 0, "") RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_JITMinOpts, W("JITMinOpts"), 0, "Forces MinOpts") +RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_JITFullOptsForCctors, W("JitFullOptsForCctors"), 0, "Use FullOpts for cctors") // *Some* relocs are just opportunistic optimizations and can be non-deterministic - it might produce // noise for jit-diff like tools. diff --git a/src/coreclr/jit/compiler.cpp b/src/coreclr/jit/compiler.cpp index 4b5079ea4bfa1..18a75eb9d54f4 100644 --- a/src/coreclr/jit/compiler.cpp +++ b/src/coreclr/jit/compiler.cpp @@ -2434,9 +2434,9 @@ void Compiler::compInitOptions(JitFlags* jitFlags) { opts.compFlags = CLFLG_MINOPT; } - // Don't optimize .cctors (except prejit) or if we're an inlinee + // Don't optimize .cctors (except prejit and JitFullOptsForCctors) or if we're an inlinee else if (!jitFlags->IsSet(JitFlags::JIT_FLAG_PREJIT) && ((info.compFlags & FLG_CCTOR) == FLG_CCTOR) && - !compIsForInlining()) + !compIsForInlining() && !JitConfig.JitFullOptsForCctors()) { opts.compFlags = CLFLG_MINOPT; } diff --git a/src/coreclr/jit/jitconfigvalues.h b/src/coreclr/jit/jitconfigvalues.h index ae01210a3934c..03c9fa1784b86 100644 --- a/src/coreclr/jit/jitconfigvalues.h +++ b/src/coreclr/jit/jitconfigvalues.h @@ -108,6 +108,7 @@ CONFIG_INTEGER(JitInlineDepth, W("JITInlineDepth"), DEFAULT_MAX_INLINE_DEPTH) CONFIG_INTEGER(JitForceInlineDepth, W("JITForceInlineDepth"), DEFAULT_MAX_FORCE_INLINE_DEPTH) CONFIG_INTEGER(JitLongAddress, W("JitLongAddress"), 0) // Force using the large pseudo instruction form for long address CONFIG_INTEGER(JitMaxUncheckedOffset, W("JitMaxUncheckedOffset"), 8) +CONFIG_INTEGER(JitFullOptsForCctors, W("JitFullOptsForCctors"), 0) // Use FullOpts for cctors CONFIG_INTEGER(JitMinOpts, W("JITMinOpts"), 0) // Forces MinOpts CONFIG_INTEGER(JitMinOptsBbCount, W("JITMinOptsBbCount"), DEFAULT_MIN_OPTS_BB_COUNT) // Internal jit control of MinOpts CONFIG_INTEGER(JitMinOptsCodeSize, W("JITMinOptsCodeSize"), DEFAULT_MIN_OPTS_CODE_SIZE) // Internal jit control of diff --git a/src/coreclr/vm/eeconfig.cpp b/src/coreclr/vm/eeconfig.cpp index 566a0c17ad4aa..1b63023f5cfa5 100644 --- a/src/coreclr/vm/eeconfig.cpp +++ b/src/coreclr/vm/eeconfig.cpp @@ -544,6 +544,7 @@ HRESULT EEConfig::sync() fJitFramed = (CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_JitFramed) != 0); fJitMinOpts = (CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_JITMinOpts) == 1); + fJitFullOptsForCctors = (CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_JITFullOptsForCctors) == 1); fJitEnableOptionalRelocs = (CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_JitEnableOptionalRelocs) == 1); iJitOptimizeType = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_JitOptimizeType); if (iJitOptimizeType > OPT_RANDOM) iJitOptimizeType = OPT_DEFAULT; diff --git a/src/coreclr/vm/eeconfig.h b/src/coreclr/vm/eeconfig.h index 6394f1b998c0f..3ee4c01968cd3 100644 --- a/src/coreclr/vm/eeconfig.h +++ b/src/coreclr/vm/eeconfig.h @@ -76,6 +76,7 @@ class EEConfig unsigned int GenOptimizeType(void) const {LIMITED_METHOD_CONTRACT; return iJitOptimizeType; } bool JitFramed(void) const {LIMITED_METHOD_CONTRACT; return fJitFramed; } bool JitMinOpts(void) const {LIMITED_METHOD_CONTRACT; return fJitMinOpts; } + bool JitFullOptsForCctors(void) const {LIMITED_METHOD_CONTRACT; return fJitFullOptsForCctors; } bool JitEnableOptionalRelocs(void) const {LIMITED_METHOD_CONTRACT; return fJitEnableOptionalRelocs; } // Tiered Compilation config @@ -479,6 +480,7 @@ class EEConfig bool fTrackDynamicMethodDebugInfo; // Enable/Disable tracking dynamic method debug info bool fJitFramed; // Enable/Disable EBP based frames bool fJitMinOpts; // Enable MinOpts for all jitted methods + bool fJitFullOptsForCctors; // Enable FullOpts for cctors bool fJitEnableOptionalRelocs; // Allow optional relocs unsigned iJitOptimizeType; // 0=Blended,1=SmallCode,2=FastCode, default is 0=Blended diff --git a/src/coreclr/vm/tieredcompilation.cpp b/src/coreclr/vm/tieredcompilation.cpp index ac068b067fde7..de02066a22d6a 100644 --- a/src/coreclr/vm/tieredcompilation.cpp +++ b/src/coreclr/vm/tieredcompilation.cpp @@ -91,6 +91,11 @@ NativeCodeVersion::OptimizationTier TieredCompilationManager::GetInitialOptimiza WRAPPER_NO_CONTRACT; _ASSERTE(pMethodDesc != NULL); + if (pMethodDesc->IsClassConstructor() && g_pConfig->JitFullOptsForCctors()) + { + return NativeCodeVersion::OptimizationTierOptimized; + } + #ifdef FEATURE_TIERED_COMPILATION if (!pMethodDesc->IsEligibleForTieredCompilation()) { @@ -1066,6 +1071,12 @@ CORJIT_FLAGS TieredCompilationManager::GetJitFlags(PrepareCodeConfig *config) if (nativeCodeVersion.IsDefaultVersion() && !config->WasTieringDisabledBeforeJitting()) { MethodDesc *methodDesc = nativeCodeVersion.GetMethodDesc(); + + if (methodDesc->IsClassConstructor() && g_pConfig->JitFullOptsForCctors()) + { + return flags; + } + if (!methodDesc->IsEligibleForTieredCompilation()) { _ASSERTE(nativeCodeVersion.GetOptimizationTier() == NativeCodeVersion::OptimizationTierOptimized);