diff options
author | Andy Ayers <andya@microsoft.com> | 2016-03-16 16:02:54 -0700 |
---|---|---|
committer | Andy Ayers <andya@microsoft.com> | 2016-03-16 17:55:02 -0700 |
commit | 548582b31d9e627dcb252bce2914002bdd5ebe6c (patch) | |
tree | a147f22ede21d6a9a55004ff2b6612f48b621ce1 /src | |
parent | 8258a31961abbf37a157c6374f4e0ebd59f0c686 (diff) | |
download | coreclr-548582b31d9e627dcb252bce2914002bdd5ebe6c.tar.gz coreclr-548582b31d9e627dcb252bce2914002bdd5ebe6c.tar.bz2 coreclr-548582b31d9e627dcb252bce2914002bdd5ebe6c.zip |
Inliner: create DiscretionaryPolicy
The `DiscretionaryPolicy` is similar to the `LegacyPolicy`, but does not
use size limits. So there is no "always" inline class and no "too big to
inline" class. Also, discretionary failures do not trigger noinline
stamping.
It is installed if `JitInlinePolicyDiscretionary` is set nonzero.
See #3775 for some background on where this new policy will be used.
This is a first cut and further refinement is likely.
Also removed the unused `NoteDouble` methods since the double-valued
observations now are kept internally within `LegacyPolicy` and it's
not very likely we'll introduce new cases where doubles are needed.
Diffstat (limited to 'src')
-rw-r--r-- | src/jit/inline.cpp | 1 | ||||
-rw-r--r-- | src/jit/inline.h | 7 | ||||
-rw-r--r-- | src/jit/inlinepolicy.cpp | 118 | ||||
-rw-r--r-- | src/jit/inlinepolicy.h | 29 | ||||
-rw-r--r-- | src/jit/jitconfigvalues.h | 1 |
5 files changed, 114 insertions, 42 deletions
diff --git a/src/jit/inline.cpp b/src/jit/inline.cpp index c59ec78439..743aae3237 100644 --- a/src/jit/inline.cpp +++ b/src/jit/inline.cpp @@ -678,7 +678,6 @@ void InlineResult::Report() } } - if (IsDecided()) { const char* format = "INLINER: during '%s' result '%s' reason '%s'\n"; diff --git a/src/jit/inline.h b/src/jit/inline.h index 92bd5bf359..1a248ae96c 100644 --- a/src/jit/inline.h +++ b/src/jit/inline.h @@ -238,7 +238,6 @@ public: virtual void NoteBool(InlineObservation obs, bool value) = 0; virtual void NoteFatal(InlineObservation obs) = 0; virtual void NoteInt(InlineObservation obs, int value) = 0; - virtual void NoteDouble(InlineObservation obs, double value) = 0; // Policy determinations virtual void DetermineProfitability(CORINFO_METHOD_INFO* methodInfo) = 0; @@ -375,12 +374,6 @@ public: m_Policy->NoteInt(obs, value); } - // Make an observation with a double value - void NoteDouble(InlineObservation obs, double value) - { - m_Policy->NoteDouble(obs, value); - } - // Determine if this inline is profitable void DetermineProfitability(CORINFO_METHOD_INFO* methodInfo) { diff --git a/src/jit/inlinepolicy.cpp b/src/jit/inlinepolicy.cpp index bfe5aeefe8..ee576da4eb 100644 --- a/src/jit/inlinepolicy.cpp +++ b/src/jit/inlinepolicy.cpp @@ -39,6 +39,14 @@ InlinePolicy* InlinePolicy::GetPolicy(Compiler* compiler, bool isPrejitRoot) return new (compiler, CMK_Inlining) RandomPolicy(compiler, isPrejitRoot, seed); } + // Optionally install the DiscretionaryPolicy. + bool useDiscretionaryPolicy = JitConfig.JitInlinePolicyDiscretionary() != 0; + + if (useDiscretionaryPolicy) + { + return new (compiler, CMK_Inlining) DiscretionaryPolicy(compiler, isPrejitRoot); + } + #endif // DEBUG // Use the legacy policy @@ -167,7 +175,7 @@ void LegacyPolicy::NoteFatal(InlineObservation obs) } //------------------------------------------------------------------------ -// noteInt: handle an observed integer value +// NoteInt: handle an observed integer value // // Arguments: // obs - the current obsevation @@ -277,20 +285,6 @@ void LegacyPolicy::NoteInt(InlineObservation obs, int value) } //------------------------------------------------------------------------ -// NoteDouble: handle an observed double value -// -// Arguments: -// obs - the current obsevation -// value - the value being observed - -void LegacyPolicy::NoteDouble(InlineObservation obs, double value) -{ - // Ignore for now... - (void) value; - (void) obs; -} - -//------------------------------------------------------------------------ // NoteInternal: helper for handling an observation // // Arguments: @@ -677,7 +671,12 @@ void LegacyPolicy::DetermineProfitability(CORINFO_METHOD_INFO* methodInfo) #ifdef DEBUG -//----------------------- +//------------------------------------------------------------------------ +// RandomPolicy: construct a new RandomPolicy +// +// Arguments: +// compiler -- compiler instance doing the inlining (root compiler) +// isPrejitRoot -- true if this compiler is prejitting the root method RandomPolicy::RandomPolicy(Compiler* compiler, bool isPrejitRoot, unsigned seed) : InlinePolicy(isPrejitRoot) @@ -777,7 +776,7 @@ void RandomPolicy::NoteFatal(InlineObservation obs) } //------------------------------------------------------------------------ -// noteInt: handle an observed integer value +// NoteInt: handle an observed integer value // // Arguments: // obs - the current obsevation @@ -815,20 +814,6 @@ void RandomPolicy::NoteInt(InlineObservation obs, int value) } //------------------------------------------------------------------------ -// NoteDouble: handle an observed double value -// -// Arguments: -// obs - the current obsevation -// value - the value being observed - -void RandomPolicy::NoteDouble(InlineObservation obs, double value) -{ - // Ignore for now... - (void) value; - (void) obs; -} - -//------------------------------------------------------------------------ // NoteInternal: helper for handling an observation // // Arguments: @@ -1033,4 +1018,75 @@ void RandomPolicy::DetermineProfitability(CORINFO_METHOD_INFO* methodInfo) } } +//------------------------------------------------------------------------ +// DiscretionaryPolicy: construct a new DiscretionaryPolicy +// +// Arguments: +// compiler -- compiler instance doing the inlining (root compiler) +// isPrejitRoot -- true if this compiler is prejitting the root method + +DiscretionaryPolicy::DiscretionaryPolicy(Compiler* compiler, bool isPrejitRoot) + : LegacyPolicy(compiler, isPrejitRoot) +{ + // Empty +} + +//------------------------------------------------------------------------ +// NoteInt: handle an observed integer value +// +// Arguments: +// obs - the current obsevation +// value - the value being observed + +void DiscretionaryPolicy::NoteInt(InlineObservation obs, int value) +{ + switch (obs) + { + + case InlineObservation::CALLEE_IL_CODE_SIZE: + // Override how code size is handled + { + assert(m_IsForceInlineKnown); + assert(value != 0); + m_CodeSize = static_cast<unsigned>(value); + + if (m_IsForceInline) + { + // Candidate based on force inline + SetCandidate(InlineObservation::CALLEE_IS_FORCE_INLINE); + } + else + { + // Candidate, pending profitability evaluation + SetCandidate(InlineObservation::CALLEE_IS_DISCRETIONARY_INLINE); + } + + break; + } + + case InlineObservation::CALLEE_MAXSTACK: + case InlineObservation::CALLEE_NUMBER_OF_BASIC_BLOCKS: + // Ignore these + break; + + default: + // Delegate remainder to the LegacyPolicy. + LegacyPolicy::NoteInt(obs, value); + break; + } +} + +//------------------------------------------------------------------------ +// PropagateNeverToRuntime: determine if a never result should cause the +// method to be marked as un-inlinable. + +bool DiscretionaryPolicy::PropagateNeverToRuntime() const +{ + // Propagate most failures, but don't propagate when the inline + // was viable but unprofitable. + bool propagate = (m_Observation != InlineObservation::CALLEE_NOT_PROFITABLE_INLINE); + + return propagate; +} + #endif // DEBUG diff --git a/src/jit/inlinepolicy.h b/src/jit/inlinepolicy.h index cf26b3f084..8d3472202c 100644 --- a/src/jit/inlinepolicy.h +++ b/src/jit/inlinepolicy.h @@ -10,6 +10,8 @@ // -- CLASSES -- // // LegacyPolicy - policy to provide legacy inline behavior +// RandomPolicy - randomized inlining +// DiscretionaryPolicy - legacy variant with uniform size policy #ifndef _INLINE_POLICY_H_ #define _INLINE_POLICY_H_ @@ -63,7 +65,6 @@ public: void NoteBool(InlineObservation obs, bool value) override; void NoteFatal(InlineObservation obs) override; void NoteInt(InlineObservation obs, int value) override; - void NoteDouble(InlineObservation obs, double value) override; // Policy determinations void DetermineProfitability(CORINFO_METHOD_INFO* methodInfo) override; @@ -75,7 +76,7 @@ public: const char* GetName() const override { return "LegacyPolicy"; } #endif -private: +protected: // Helper methods void NoteInternal(InlineObservation obs); @@ -123,7 +124,6 @@ public: void NoteBool(InlineObservation obs, bool value) override; void NoteFatal(InlineObservation obs) override; void NoteInt(InlineObservation obs, int value) override; - void NoteDouble(InlineObservation obs, double value) override; // Policy determinations void DetermineProfitability(CORINFO_METHOD_INFO* methodInfo) override; @@ -149,6 +149,29 @@ private: bool m_IsForceInlineKnown :1; }; +// 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" +// inline bit. +// +// It is useful for gathering data about inline costs. + +class DiscretionaryPolicy : public LegacyPolicy +{ +public: + + // Construct a DiscretionaryPolicy + DiscretionaryPolicy(Compiler* compiler, bool isPrejitRoot); + + // Policy observations + void NoteInt(InlineObservation obs, int value) override; + + // Policy policies + bool PropagateNeverToRuntime() const override; + + const char* GetName() const override { return "DiscretionaryPolicy"; } +}; + #endif // DEBUG #endif // _INLINE_POLICY_H_ diff --git a/src/jit/jitconfigvalues.h b/src/jit/jitconfigvalues.h index 75be95ec36..a029ef7cfa 100644 --- a/src/jit/jitconfigvalues.h +++ b/src/jit/jitconfigvalues.h @@ -55,6 +55,7 @@ CONFIG_INTEGER(JitHashDump, W("JitHashDump"), -1) // Same as JitDump, but for a CONFIG_INTEGER(JitHashDumpIR, W("JitHashDumpIR"), -1) // Same as JitDumpIR, but for a method hash CONFIG_INTEGER(JitHashHalt, W("JitHashHalt"), -1) // Same as JitHalt, but for a method hash CONFIG_INTEGER(JitInlineAdditionalMultiplier, W("JitInlineAdditionalMultiplier"), 0) +CONFIG_INTEGER(JitInlinePolicyDiscretionary, W("JitInlinePolicyDiscretionary"), 0) CONFIG_INTEGER(JitInlinePrintStats, W("JitInlinePrintStats"), 0) CONFIG_INTEGER(JitInlineSize, W("JITInlineSize"), DEFAULT_MAX_INLINE_SIZE) CONFIG_INTEGER(JitLargeBranches, W("JitLargeBranches"), 0) // Force using the largest conditional branch format |