diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs index 5ac150b37ec474..c635b416708be2 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs @@ -1117,9 +1117,9 @@ private uint getMethodAttribsInternal(MethodDesc method) // TODO: Cache inlining hits // Check for an inlining directive. - if (method.IsNoInlining) + if (method.IsNoInlining || method.IsNoOptimization) { - /* Function marked as not inlineable */ + // NoOptimization implies NoInlining. result |= CorInfoFlag.CORINFO_FLG_DONT_INLINE; } else if (method.IsAggressiveInlining) diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/SubstitutedILProvider.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/SubstitutedILProvider.cs index fd2442c4b6b41c..4450c53ed99584 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/SubstitutedILProvider.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/SubstitutedILProvider.cs @@ -672,6 +672,7 @@ private bool TryGetMethodConstantValue(MethodDesc method, out int constant, int if (returnType is < TypeFlags.Boolean or > TypeFlags.UInt32 || method.IsIntrinsic || method.IsNoInlining + || method.IsNoOptimization || _nestedILProvider.GetMethodIL(method) is not MethodIL methodIL) { constant = 0; diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilation.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilation.cs index 66c7767dab8a81..e1803a3f5d7931 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilation.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilation.cs @@ -82,8 +82,9 @@ public bool CanInline(MethodDesc caller, MethodDesc callee) return false; } - if (callee.IsNoInlining) + if (callee.IsNoInlining || callee.IsNoOptimization) { + // NoOptimization implies NoInlining return false; } diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs index 500863a90d9347..7cc3343a56d416 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs @@ -1299,10 +1299,12 @@ private bool canTailCall(CORINFO_METHOD_STRUCT_* callerHnd, CORINFO_METHOD_STRUC return false; } - // Do not tailcall from methods that are marked as noinline (people often use no-inline + // Do not tailcall from methods that are marked as NoInlining (people often use no-inline // to mean "I want to always see this method in stacktrace") if (caller.IsNoInlining) { + // NOTE: we don't have to handle NoOptimization here, because JIT is not expected + // to emit fast tail calls if optimizations are disabled. return false; } diff --git a/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs b/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs index fab907801e723b..b4933c28b25afc 100644 --- a/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs +++ b/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs @@ -833,8 +833,11 @@ private bool canTailCall(CORINFO_METHOD_STRUCT_* callerHnd, CORINFO_METHOD_STRUC if (caller.IsNoInlining) { - // Do not tailcall from methods that are marked as noinline (people often use no-inline + // Do not tailcall from methods that are marked as NoInlining (people often use no-inline // to mean "I want to always see this method in stacktrace") + // + // NOTE: we don't have to handle NoOptimization here, because JIT is not expected + // to emit fast tail calls if optimizations are disabled. result = false; } } diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 0a5e03371994dc..3354a7ec0f2ab4 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -8200,7 +8200,7 @@ bool CEEInfo::canTailCall (CORINFO_METHOD_HANDLE hCaller, if (!pCaller->IsNoMetadata()) { - // Do not tailcall from methods that are marked as noinline (people often use no-inline + // Do not tailcall from methods that are marked as NoInlining (people often use no-inline // to mean "I want to always see this method in stacktrace") DWORD dwImplFlags = 0; IfFailThrow(pCaller->GetMDImport()->GetMethodImplProps(callerToken, NULL, &dwImplFlags)); @@ -8208,9 +8208,12 @@ bool CEEInfo::canTailCall (CORINFO_METHOD_HANDLE hCaller, if (IsMiNoInlining(dwImplFlags)) { result = false; - szFailReason = "Caller is marked as no inline"; + szFailReason = "Caller is marked as NoInlining"; goto exit; } + + // NOTE: we don't have to handle NoOptimization here, because JIT is not expected + // to emit fast tail calls if optimizations are disabled. } // Methods with StackCrawlMark depend on finding their caller on the stack. @@ -12613,8 +12616,8 @@ CorJitResult invokeCompileMethod(EEJitManager *jitMgr, flags.Set(CORJIT_FLAGS::CORJIT_FLAG_MIN_OPT); } - // Always emit frames for methods marked no-inline (see #define ETW_EBP_FRAMED in the JIT) - if (IsMiNoInlining(dwImplFlags)) + // Always emit frames for methods marked NoInlining or NoOptimization (see #define ETW_EBP_FRAMED in the JIT) + if (IsMiNoInlining(dwImplFlags) || IsMiNoOptimization(dwImplFlags)) { flags.Set(CORJIT_FLAGS::CORJIT_FLAG_FRAMED); } diff --git a/src/coreclr/vm/methodtablebuilder.cpp b/src/coreclr/vm/methodtablebuilder.cpp index 69d5aa64d34ec1..60110263e4a274 100644 --- a/src/coreclr/vm/methodtablebuilder.cpp +++ b/src/coreclr/vm/methodtablebuilder.cpp @@ -5219,9 +5219,8 @@ MethodTableBuilder::InitNewMethodDesc( } } - // Turn off inlining for any calls - // that are marked in the metadata as not being inlineable. - if(IsMiNoInlining(pMethod->GetImplAttrs())) + // Turn off inlining for any calls that are marked in the metadata as NoInlining or NoOptimization. + if (IsMiNoInlining(pMethod->GetImplAttrs()) || IsMiNoOptimization(pMethod->GetImplAttrs())) { pNewMD->SetNotInline(true); }