From: Andy Ayers Date: Sat, 12 Nov 2016 03:52:24 +0000 (-0800) Subject: Inliner: updates to random inlining (dotnet/coreclr#8088) X-Git-Tag: submit/tizen/20210909.063632~11030^2~8908 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c94e4572388c2516f090aa1b05b381c76a8bf2d0;p=platform%2Fupstream%2Fdotnet%2Fruntime.git Inliner: updates to random inlining (dotnet/coreclr#8088) Cache the random state on the InlineStrategy instead of on the compiler instance so that the state is reinitialized and private to each jit request. That way the random policy evaluations made compiling one method won't alter the evaluations for subsequent methods. This should make it somewhat easier to do A/B comparisons under jit stress when changing the jit. Make it possible to enable the RandomPolicy outside of stress. This may prove useful in various randomized inline performance studies or as a simple stress mode on its own. Random state seed is built from an external seed value (via JitStress or JitInlinePolicyRandom) and an internal seed value (method hash), so that random sequences potentially differ for each method but are deterministic across runs and changes to the jit. Commit migrated from https://github.com/dotnet/coreclr/commit/7697dec7db3e34239ffa33d8867de12f7176e415 --- diff --git a/src/coreclr/src/jit/compiler.cpp b/src/coreclr/src/jit/compiler.cpp index c5f8016..8c7e14d 100644 --- a/src/coreclr/src/jit/compiler.cpp +++ b/src/coreclr/src/jit/compiler.cpp @@ -1913,10 +1913,6 @@ void Compiler::compInit(ArenaAllocator* pAlloc, InlineInfo* inlineInfo) SIMDVectorHandle = nullptr; #endif -#ifdef DEBUG - inlRNG = nullptr; -#endif - compUsesThrowHelper = false; } diff --git a/src/coreclr/src/jit/compiler.h b/src/coreclr/src/jit/compiler.h index cd5da25..60a92ce 100644 --- a/src/coreclr/src/jit/compiler.h +++ b/src/coreclr/src/jit/compiler.h @@ -7820,10 +7820,6 @@ public: #endif } -#ifdef DEBUG - CLRRandom* inlRNG; -#endif - //--------------------- Info about the procedure -------------------------- struct Info diff --git a/src/coreclr/src/jit/inline.cpp b/src/coreclr/src/jit/inline.cpp index aa1b55d..ced8380 100644 --- a/src/coreclr/src/jit/inline.cpp +++ b/src/coreclr/src/jit/inline.cpp @@ -747,6 +747,7 @@ InlineStrategy::InlineStrategy(Compiler* compiler) , m_HasForceViaDiscretionary(false) #if defined(DEBUG) || defined(INLINE_DATA) , m_MethodXmlFilePosition(0) + , m_Random(nullptr) #endif // defined(DEBUG) || defined(INLINE_DATA) { @@ -1596,6 +1597,47 @@ void InlineStrategy::FinalizeXml(FILE* file) ReplayPolicy::FinalizeXml(); } +//------------------------------------------------------------------------ +// GetRandom: setup or access random state +// +// Return Value: +// New or pre-existing random state. +// +// Notes: +// Random state is kept per jit compilation request. Seed is partially +// specified externally (via stress or policy setting) and partially +// specified internally via method hash. + +CLRRandom* InlineStrategy::GetRandom() +{ + if (m_Random == nullptr) + { + int externalSeed = 0; + if (m_Compiler->compRandomInlineStress()) + { + externalSeed = getJitStressLevel(); + } + + int randomPolicyFlag = JitConfig.JitInlinePolicyRandom(); + if (randomPolicyFlag != 0) + { + externalSeed = randomPolicyFlag; + } + + int internalSeed = m_Compiler->info.compMethodHash(); + + assert(externalSeed != 0); + assert(internalSeed != 0); + + int seed = externalSeed ^ internalSeed; + + m_Random = new (m_Compiler, CMK_Inlining) CLRRandom(); + m_Random->Init(seed); + } + + return m_Random; +} + #endif // defined(DEBUG) || defined(INLINE_DATA) //------------------------------------------------------------------------ diff --git a/src/coreclr/src/jit/inline.h b/src/coreclr/src/jit/inline.h index 2bc483c..3de62e6 100644 --- a/src/coreclr/src/jit/inline.h +++ b/src/coreclr/src/jit/inline.h @@ -820,6 +820,9 @@ public: m_MethodXmlFilePosition = val; } + // Set up or access random state (for use by RandomPolicy) + CLRRandom* GetRandom(); + #endif // defined(DEBUG) || defined(INLINE_DATA) // Some inline limit values @@ -884,7 +887,8 @@ private: bool m_HasForceViaDiscretionary; #if defined(DEBUG) || defined(INLINE_DATA) - long m_MethodXmlFilePosition; + long m_MethodXmlFilePosition; + CLRRandom* m_Random; #endif // defined(DEBUG) || defined(INLINE_DATA) }; diff --git a/src/coreclr/src/jit/inlinepolicy.cpp b/src/coreclr/src/jit/inlinepolicy.cpp index c67b32c..a909845 100644 --- a/src/coreclr/src/jit/inlinepolicy.cpp +++ b/src/coreclr/src/jit/inlinepolicy.cpp @@ -30,13 +30,12 @@ InlinePolicy* InlinePolicy::GetPolicy(Compiler* compiler, bool isPrejitRoot) #ifdef DEBUG // Optionally install the RandomPolicy. - bool useRandomPolicy = compiler->compRandomInlineStress(); + const bool useRandomPolicyForStress = compiler->compRandomInlineStress(); + const bool useRandomPolicy = (JitConfig.JitInlinePolicyRandom() != 0); - if (useRandomPolicy) + if (useRandomPolicyForStress || useRandomPolicy) { - unsigned seed = getJitStressLevel(); - assert(seed != 0); - return new (compiler, CMK_Inlining) RandomPolicy(compiler, isPrejitRoot, seed); + return new (compiler, CMK_Inlining) RandomPolicy(compiler, isPrejitRoot); } #endif // DEBUG @@ -974,7 +973,7 @@ bool EnhancedLegacyPolicy::PropagateNeverToRuntime() const return propagate; } -#ifdef DEBUG +#if defined(DEBUG) || defined(INLINE_DATA) //------------------------------------------------------------------------ // RandomPolicy: construct a new RandomPolicy @@ -982,9 +981,8 @@ bool EnhancedLegacyPolicy::PropagateNeverToRuntime() const // Arguments: // compiler -- compiler instance doing the inlining (root compiler) // isPrejitRoot -- true if this compiler is prejitting the root method -// seed -- seed value for the random number generator -RandomPolicy::RandomPolicy(Compiler* compiler, bool isPrejitRoot, unsigned seed) +RandomPolicy::RandomPolicy(Compiler* compiler, bool isPrejitRoot) : LegalPolicy(isPrejitRoot) , m_RootCompiler(compiler) , m_Random(nullptr) @@ -992,19 +990,7 @@ RandomPolicy::RandomPolicy(Compiler* compiler, bool isPrejitRoot, unsigned seed) , m_IsForceInline(false) , m_IsForceInlineKnown(false) { - // If necessary, setup and seed the random state. - if (compiler->inlRNG == nullptr) - { - compiler->inlRNG = new (compiler, CMK_Inlining) CLRRandom(); - - unsigned hash = m_RootCompiler->info.compMethodHash(); - assert(hash != 0); - assert(seed != 0); - int hashSeed = static_cast(hash ^ seed); - compiler->inlRNG->Init(hashSeed); - } - - m_Random = compiler->inlRNG; + m_Random = compiler->m_inlineStrategy->GetRandom(); } //------------------------------------------------------------------------ @@ -1211,7 +1197,7 @@ void RandomPolicy::DetermineProfitability(CORINFO_METHOD_INFO* methodInfo) } } -#endif // DEBUG +#endif // defined(DEBUG) || defined(INLINE_DATA) #ifdef _MSC_VER // Disable warning about new array member initialization behavior diff --git a/src/coreclr/src/jit/inlinepolicy.h b/src/coreclr/src/jit/inlinepolicy.h index 4b1e55e..c010a98 100644 --- a/src/coreclr/src/jit/inlinepolicy.h +++ b/src/coreclr/src/jit/inlinepolicy.h @@ -198,7 +198,7 @@ protected: bool m_IsNoReturnKnown : 1; }; -#ifdef DEBUG +#if defined(DEBUG) || defined(INLINE_DATA) // RandomPolicy implements a policy that inlines at random. // It is mostly useful for stress testing. @@ -207,7 +207,7 @@ class RandomPolicy : public LegalPolicy { public: // Construct a RandomPolicy - RandomPolicy(Compiler* compiler, bool isPrejitRoot, unsigned seed); + RandomPolicy(Compiler* compiler, bool isPrejitRoot); // Policy observations void NoteSuccess() override; @@ -247,7 +247,7 @@ private: bool m_IsForceInlineKnown : 1; }; -#endif // DEBUG +#endif // defined(DEBUG) || defined(INLINE_DATA) // DiscretionaryPolicy is a variant of the enhanced legacy policy. It // differs in that there is no ALWAYS_INLINE class, there is no IL diff --git a/src/coreclr/src/jit/jitconfigvalues.h b/src/coreclr/src/jit/jitconfigvalues.h index f53de13..7f6b421 100644 --- a/src/coreclr/src/jit/jitconfigvalues.h +++ b/src/coreclr/src/jit/jitconfigvalues.h @@ -256,6 +256,8 @@ CONFIG_INTEGER(JitInlineLimit, W("JitInlineLimit"), -1) CONFIG_INTEGER(JitInlinePolicyDiscretionary, W("JitInlinePolicyDiscretionary"), 0) CONFIG_INTEGER(JitInlinePolicyFull, W("JitInlinePolicyFull"), 0) CONFIG_INTEGER(JitInlinePolicySize, W("JitInlinePolicySize"), 0) +CONFIG_INTEGER(JitInlinePolicyRandom, W("JitInlinePolicyRandom"), 0) // nozero enables; value is the external random + // seed CONFIG_INTEGER(JitInlinePolicyReplay, W("JitInlinePolicyReplay"), 0) CONFIG_STRING(JitNoInlineRange, W("JitNoInlineRange")) CONFIG_STRING(JitInlineReplayFile, W("JitInlineReplayFile"))