From da74a2ccd7c84f472874895cbf490a8701eb390b Mon Sep 17 00:00:00 2001 From: Andy Ayers Date: Tue, 28 Jun 2016 15:07:01 -0700 Subject: [PATCH] Inliner: make ModelPolicy available in release builds Make the ModelPolicy available in release builds of the jit. Enable this policy by setting: COMPLUS_JitInlinePolicyModel=1 This works for either jitting or prejitting. Update the ModelPolicy so callee never inline decisions are always propagated back to the runtime. Commit migrated from https://github.com/dotnet/coreclr/commit/73ec3f5e0a240d3c9bd56f4159c94ca06d3c5392 --- src/coreclr/src/jit/inlinepolicy.cpp | 36 +++++++++++++++++++++++------------ src/coreclr/src/jit/inlinepolicy.h | 21 ++++++++++++++++---- src/coreclr/src/jit/jitconfigvalues.h | 3 ++- 3 files changed, 43 insertions(+), 17 deletions(-) diff --git a/src/coreclr/src/jit/inlinepolicy.cpp b/src/coreclr/src/jit/inlinepolicy.cpp index 209a18a..30ec8f5 100644 --- a/src/coreclr/src/jit/inlinepolicy.cpp +++ b/src/coreclr/src/jit/inlinepolicy.cpp @@ -67,14 +67,6 @@ InlinePolicy* InlinePolicy::GetPolicy(Compiler* compiler, bool isPrejitRoot) return new (compiler, CMK_Inlining) FullPolicy(compiler, isPrejitRoot); } - // Optionally install the ModelPolicy. - bool useModelPolicy = JitConfig.JitInlinePolicyModel() != 0; - - if (useModelPolicy) - { - return new (compiler, CMK_Inlining) ModelPolicy(compiler, isPrejitRoot); - } - // Optionally install the DiscretionaryPolicy. bool useDiscretionaryPolicy = JitConfig.JitInlinePolicyDiscretionary() != 0; @@ -85,8 +77,19 @@ InlinePolicy* InlinePolicy::GetPolicy(Compiler* compiler, bool isPrejitRoot) #endif // defined(DEBUG) || defined(INLINE_DATA) - // Use the legacy policy - InlinePolicy* policy = new (compiler, CMK_Inlining) LegacyPolicy(compiler, isPrejitRoot); + InlinePolicy* policy = nullptr; + bool useModelPolicy = JitConfig.JitInlinePolicyModel() != 0; + + if (useModelPolicy) + { + // Optionally install the ModelPolicy. + policy = new (compiler, CMK_Inlining) ModelPolicy(compiler, isPrejitRoot); + } + else + { + // Use the legacy policy + policy = new (compiler, CMK_Inlining) LegacyPolicy(compiler, isPrejitRoot); + } return policy; } @@ -1087,8 +1090,6 @@ void RandomPolicy::DetermineProfitability(CORINFO_METHOD_INFO* methodInfo) #endif // DEBUG -#if defined(DEBUG) || defined(INLINE_DATA) - #ifdef _MSC_VER // Disable warning about new array member initialization behavior #pragma warning( disable : 4351 ) @@ -1521,6 +1522,9 @@ bool DiscretionaryPolicy::PropagateNeverToRuntime() const void DiscretionaryPolicy::DetermineProfitability(CORINFO_METHOD_INFO* methodInfo) { + +#if defined(DEBUG) + // Punt if we're inlining and we've reached the acceptance limit. int limit = JitConfig.JitInlineLimit(); unsigned current = m_RootCompiler->m_inlineStrategy->GetInlineCount(); @@ -1533,6 +1537,8 @@ void DiscretionaryPolicy::DetermineProfitability(CORINFO_METHOD_INFO* methodInfo return; } +#endif // defined(DEBUG) + // Make additional observations based on the method info MethodInfoObservations(methodInfo); @@ -1740,6 +1746,8 @@ int DiscretionaryPolicy::CodeSizeEstimate() return m_ModelCodeSizeEstimate; } +#if defined(DEBUG) || defined(INLINE_DATA) + //------------------------------------------------------------------------ // DumpSchema: dump names for all the supporting data for the // inline decision in CSV format. @@ -1890,6 +1898,8 @@ void DiscretionaryPolicy::DumpData(FILE* file) const fprintf(file, ",%d", m_PerCallInstructionEstimate); } +#endif // defined(DEBUG) || defined(INLINE_DATA) + //------------------------------------------------------------------------/ // ModelPolicy: construct a new ModelPolicy // @@ -2025,6 +2035,8 @@ void ModelPolicy::DetermineProfitability(CORINFO_METHOD_INFO* methodInfo) } } +#if defined(DEBUG) || defined(INLINE_DATA) + //------------------------------------------------------------------------/ // FullPolicy: construct a new FullPolicy // diff --git a/src/coreclr/src/jit/inlinepolicy.h b/src/coreclr/src/jit/inlinepolicy.h index 0f58149..f834577 100644 --- a/src/coreclr/src/jit/inlinepolicy.h +++ b/src/coreclr/src/jit/inlinepolicy.h @@ -11,13 +11,13 @@ // // LegalPolicy - partial class providing common legality checks // LegacyPolicy - policy that provides legacy inline behavior +// DiscretionaryPolicy - legacy variant with uniform size policy +// ModelPolicy - policy based on statistical modelling // // These experimental policies are available only in // DEBUG or release+INLINE_DATA builds of the jit. // // RandomPolicy - randomized inlining -// DiscretionaryPolicy - legacy variant with uniform size policy -// ModelPolicy - policy based on statistical modelling // FullPolicy - inlines everything up to size and depth limits // SizePolicy - tries not to increase method sizes @@ -198,8 +198,6 @@ private: #endif // DEBUG -#if defined(DEBUG) || defined(INLINE_DATA) - // DiscretionaryPolicy is a variant of the legacy policy. It differs // in that there is no ALWAYS_INLINE class, there is no IL size limit, // and in prejit mode, discretionary failures do not set the "NEVER" @@ -227,6 +225,8 @@ public: // Policy estimates int CodeSizeEstimate() override; +#if defined(DEBUG) || defined(INLINE_DATA) + // Externalize data void DumpData(FILE* file) const override; void DumpSchema(FILE* file) const override; @@ -234,6 +234,9 @@ public: // Miscellaneous const char* GetName() const override { return "DiscretionaryPolicy"; } +#endif // defined(DEBUG) || defined(INLINE_DATA) + + protected: void ComputeOpcodeBin(OPCODE opcode); @@ -297,10 +300,20 @@ public: // Policy determinations void DetermineProfitability(CORINFO_METHOD_INFO* methodInfo) override; + // Policy policies + bool PropagateNeverToRuntime() const override { return true; } + +#if defined(DEBUG) || defined(INLINE_DATA) + // Miscellaneous const char* GetName() const override { return "ModelPolicy"; } + +#endif // defined(DEBUG) || defined(INLINE_DATA) + }; +#if defined(DEBUG) || defined(INLINE_DATA) + // FullPolicy is an experimental policy that will always inline if // possible, subject to externally settable depth and size limits. // diff --git a/src/coreclr/src/jit/jitconfigvalues.h b/src/coreclr/src/jit/jitconfigvalues.h index c156684..0aa0b9a 100644 --- a/src/coreclr/src/jit/jitconfigvalues.h +++ b/src/coreclr/src/jit/jitconfigvalues.h @@ -195,7 +195,6 @@ CONFIG_INTEGER(JitInlineDumpData, W("JitInlineDumpData"), 0) CONFIG_INTEGER(JitInlineDumpXml, W("JitInlineDumpXml"), 0) // 1 = full xml (all methods), 2 = minimal xml (only method with inlines) CONFIG_INTEGER(JitInlineLimit, W("JitInlineLimit"), -1) CONFIG_INTEGER(JitInlinePolicyDiscretionary, W("JitInlinePolicyDiscretionary"), 0) -CONFIG_INTEGER(JitInlinePolicyModel, W("JitInlinePolicyModel"), 0) CONFIG_INTEGER(JitInlinePolicyFull, W("JitInlinePolicyFull"), 0) CONFIG_INTEGER(JitInlinePolicySize, W("JitInlinePolicySize"), 0) CONFIG_INTEGER(JitInlinePolicyReplay, W("JitInlinePolicyReplay"), 0) @@ -203,6 +202,8 @@ CONFIG_STRING(JitNoInlineRange, W("JitNoInlineRange")) CONFIG_STRING(JitInlineReplayFile, W("JitInlineReplayFile")) #endif // defined(DEBUG) || defined(INLINE_DATA) +CONFIG_INTEGER(JitInlinePolicyModel, W("JitInlinePolicyModel"), 0) + #undef CONFIG_INTEGER #undef CONFIG_STRING #undef CONFIG_METHODSET -- 2.7.4