summaryrefslogtreecommitdiff
path: root/src/jit
diff options
context:
space:
mode:
authorAndy Ayers <andya@microsoft.com>2016-03-09 16:04:11 -0800
committerAndy Ayers <andya@microsoft.com>2016-03-09 18:20:38 -0800
commit9cbd25871b360647686a79be6d9021bbefd84313 (patch)
tree06bc910f599177f77f7ce817dc3e38c0c66155e0 /src/jit
parent587e7c08ef1edc53d2ce6bf90da0c63ba70aa00b (diff)
downloadcoreclr-9cbd25871b360647686a79be6d9021bbefd84313.tar.gz
coreclr-9cbd25871b360647686a79be6d9021bbefd84313.tar.bz2
coreclr-9cbd25871b360647686a79be6d9021bbefd84313.zip
Inline refactoring: move profitability assessment to LegacyPolicy
LegacyPolicy now encapsulates all the computations needed to evaluate whether an inline is profitable or not. This completes the main objective of the refactoring effort, which was to preserve and encapsulate the current inliner's behavior.
Diffstat (limited to 'src/jit')
-rw-r--r--src/jit/compiler.cpp37
-rw-r--r--src/jit/compiler.h10
-rw-r--r--src/jit/flowgraph.cpp58
-rw-r--r--src/jit/importer.cpp69
-rw-r--r--src/jit/inline.def10
-rw-r--r--src/jit/inline.h32
-rw-r--r--src/jit/inlinepolicy.cpp97
-rw-r--r--src/jit/inlinepolicy.h9
8 files changed, 153 insertions, 169 deletions
diff --git a/src/jit/compiler.cpp b/src/jit/compiler.cpp
index a9fdc7713e..d32bf28571 100644
--- a/src/jit/compiler.cpp
+++ b/src/jit/compiler.cpp
@@ -1407,8 +1407,6 @@ void Compiler::compInit(ArenaAllocator * pAlloc, InlineInfo * inl
compMaxUncheckedOffsetForNullObject = MAX_UNCHECKED_OFFSET_FOR_NULL_OBJECT;
- compNativeSizeEstimate = NATIVE_SIZE_INVALID;
-
for (unsigned i = 0; i < MAX_LOOP_NUM; i++)
{
AllVarSetOps::AssignNoCopy(this, optLoopTable[i].lpAsgVars, AllVarSetOps::UninitVal());
@@ -4843,46 +4841,25 @@ int Compiler::compCompileHelper (CORINFO_MODULE_HANDLE clas
// the code in fgFindJumpTargets references that data
// member extensively.
assert(compInlineResult == nullptr);
+ assert(impInlineInfo == nullptr);
compInlineResult = &prejitResult;
// Find the basic blocks. We must do this regardless of
// inlineability, since we are prejitting this method.
//
- // Among other things, this will set compNativeSizeEstimate
- // for the subset of methods we check below.
+ // This will also update the status of this method as
+ // an inline candidate.
fgFindBasicBlocks();
// Undo the temporary setup.
assert(compInlineResult == &prejitResult);
compInlineResult = nullptr;
- // If this method is still a viable inline candidate,
- // do the profitability screening.
- if (prejitResult.IsCandidate())
- {
- // Only needed if the inline is discretionary.
- InlineObservation obs = prejitResult.GetObservation();
- if (obs == InlineObservation::CALLEE_IS_DISCRETIONARY_INLINE)
- {
- // We should have run the CodeSeq state machine
- // and got the native size estimate.
- assert(compNativeSizeEstimate != NATIVE_SIZE_INVALID);
-
- // Estimate the call site impact
- int callsiteNativeSizeEstimate =
- prejitResult.DetermineCallsiteNativeSizeEstimate(methodInfo);
-
- // See if we're willing to pay for inlining this method
- impCanInlineNative(callsiteNativeSizeEstimate,
- compNativeSizeEstimate,
- nullptr, // Calculate static inlining hint.
- &prejitResult);
- }
- }
- else
+ // If still a viable, discretionary inline, assess
+ // profitability.
+ if (prejitResult.IsDiscretionaryCandidate())
{
- // If it's not a candidate, it should be a failure.
- assert(prejitResult.IsFailure());
+ prejitResult.DetermineProfitability(methodInfo);
}
// Handle the results of the inline analysis.
diff --git a/src/jit/compiler.h b/src/jit/compiler.h
index 125cba0a01..c7b97b0441 100644
--- a/src/jit/compiler.h
+++ b/src/jit/compiler.h
@@ -3108,10 +3108,8 @@ private:
static BOOL impIsAddressInLocal(GenTreePtr tree, GenTreePtr * lclVarTreeOut);
- void impCanInlineNative(int callsiteNativeEstimate,
- int calleeNativeSizeEstimate,
- InlineInfo* pInlineInfo,
- InlineResult* inlineResult);
+ void impMakeDiscretionaryInlineObservations(InlineInfo* pInlineInfo,
+ InlineResult* inlineResult);
// STATIC inlining decision based on the IL code.
void impCanInlineIL(CORINFO_METHOD_HANDLE fncHandle,
@@ -8569,10 +8567,6 @@ public:
// This can be overwritten by setting complus_JITInlineSize env variable.
#define IMPLEMENTATION_MAX_INLINE_SIZE _UI16_MAX // Maximum method size supported by this implementation
-#define NATIVE_SIZE_INVALID (-10000)
-
- int compNativeSizeEstimate; // The estimated native size of this method.
-
private:
#ifdef FEATURE_JIT_METHOD_PERF
JitTimer* pCompJitTimer; // Timer data structure (by phases) for current compilation.
diff --git a/src/jit/flowgraph.cpp b/src/jit/flowgraph.cpp
index 5e7e7131c2..32686dd811 100644
--- a/src/jit/flowgraph.cpp
+++ b/src/jit/flowgraph.cpp
@@ -4182,6 +4182,7 @@ private:
unsigned slot1;
unsigned depth;
};
+
//------------------------------------------------------------------------
// fgFindJumpTargets: walk the IL stream, determining jump target offsets
//
@@ -4782,46 +4783,39 @@ TOO_FAR:
{
compInlineResult->Note(InlineObservation::CALLEE_END_OPCODE_SCAN);
- // If the inline is viable and discretionary, we need to get
- // an estimate for the callee native code size.
- if (compInlineResult->IsCandidate()
- && (compInlineResult->GetObservation() == InlineObservation::CALLEE_IS_DISCRETIONARY_INLINE))
+ // If the inline is viable and discretionary, do the
+ // profitability screening.
+ if (compInlineResult->IsDiscretionaryCandidate())
{
- compNativeSizeEstimate = compInlineResult->DetermineNativeSizeEstimate();
- noway_assert(compNativeSizeEstimate != NATIVE_SIZE_INVALID);
- JITDUMP("\n\ncompNativeSizeEstimate=%d\n", compNativeSizeEstimate);
+ // Make some callsite specific observations that will feed
+ // into the profitability model.
+ impMakeDiscretionaryInlineObservations(impInlineInfo, compInlineResult);
+
+ // None of those observations should have changed the
+ // inline's viability.
+ assert(compInlineResult->IsCandidate());
- // If we're inlining, use the size estimate to do further
- // screening.
- //
- // If we're in the prejit-root case we do something
- // similar as part of the prejit screen over in
- // compCompileHelper.
if (compIsForInlining())
{
- // Make an inlining decision based on the estimated native size.
- int callsiteNativeSizeEstimate =
- compInlineResult->DetermineCallsiteNativeSizeEstimate(
- &impInlineInfo->inlineCandidateInfo->methInfo);
-
- impCanInlineNative(callsiteNativeSizeEstimate,
- compNativeSizeEstimate,
- impInlineInfo,
- compInlineResult);
-
+ // Assess profitability...
+ CORINFO_METHOD_INFO* methodInfo = &impInlineInfo->inlineCandidateInfo->methInfo;
+ compInlineResult->DetermineProfitability(methodInfo);
+
if (compInlineResult->IsFailure())
{
-#ifdef DEBUG
- if (verbose)
- {
- printf("\n\nInline expansion aborted because of impCanInlineNative: %s %s\n",
- compInlineResult->ResultString(),
- compInlineResult->ReasonString());
- }
-#endif
-
+ JITDUMP("\n\nInline expansion aborted, inline not profitable\n");
return;
}
+ else
+ {
+ // The inline is still viable.
+ assert(compInlineResult->IsCandidate());
+ }
+ }
+ else
+ {
+ // Prejit root case. Profitability assessment for this
+ // is done over in compCompileHelper.
}
}
}
diff --git a/src/jit/importer.cpp b/src/jit/importer.cpp
index 56b0477ac5..10d783f6f4 100644
--- a/src/jit/importer.cpp
+++ b/src/jit/importer.cpp
@@ -15467,13 +15467,21 @@ BOOL Compiler::impIsAddressInLocal(GenTreePtr tree, GenTreePtr * lclVarTreeO
}
}
-/*****************************************************************************
- */
+//------------------------------------------------------------------------
+// impMakeDiscretionaryInlineObservations: make observations that help
+// determine the profitability of a discretionary inline
+//
+// Arguments:
+// pInlineInfo -- InlineInfo for the inline, or null for the prejit root
+// inlineResult -- InlineResult accumulating information about this inline
+//
+// Notes:
+// If inlining or prejitting the root, this method also makes
+// various observations about the method that factor into inline
+// decisions. It sets `compNativeSizeEstimate` as a side effect.
-void Compiler::impCanInlineNative(int callsiteNativeEstimate,
- int calleeNativeSizeEstimate,
- InlineInfo* pInlineInfo, // NULL for static inlining hint for ngen.
- InlineResult* inlineResult)
+void Compiler::impMakeDiscretionaryInlineObservations(InlineInfo* pInlineInfo,
+ InlineResult* inlineResult)
{
assert(pInlineInfo != NULL && compIsForInlining() || // Perform the actual inlining.
pInlineInfo == NULL && !compIsForInlining() // Calculate the static inlining hint for ngen.
@@ -15487,8 +15495,6 @@ void Compiler::impCanInlineNative(int callsiteNativeEstima
// shouldn't be relying on the result of this method.
assert(inlineResult->GetObservation() == InlineObservation::CALLEE_IS_DISCRETIONARY_INLINE);
- JITDUMP("\ncalleeNativeSizeEstimate=%d, callsiteNativeEstimate=%d.\n", calleeNativeSizeEstimate, callsiteNativeEstimate);
-
// Note if this method is an instance constructor
if ((info.compFlags & CORINFO_FLG_CONSTRUCTOR) != 0 &&
(info.compFlags & CORINFO_FLG_STATIC) == 0)
@@ -15549,53 +15555,6 @@ void Compiler::impCanInlineNative(int callsiteNativeEstima
}
inlineResult->NoteInt(InlineObservation::CALLSITE_FREQUENCY, static_cast<int>(frequency));
-
- // Determine multiplier given the various observations.
- double multiplier = inlineResult->DetermineMultiplier();
-
- // Note the various estimates we've obtained.
- inlineResult->NoteInt(InlineObservation::CALLEE_NATIVE_SIZE_ESTIMATE, calleeNativeSizeEstimate);
- inlineResult->NoteInt(InlineObservation::CALLSITE_NATIVE_SIZE_ESTIMATE, callsiteNativeEstimate);
- inlineResult->NoteDouble(InlineObservation::CALLSITE_BENEFIT_MULTIPLIER, multiplier);
-
- int threshold = (int)(callsiteNativeEstimate * multiplier);
-
- JITDUMP("\ncalleeNativeSizeEstimate=%d, threshold=%d.\n", calleeNativeSizeEstimate, threshold);
-
-#define NATIVE_CALL_SIZE_MULTIPLIER (10.0)
- if (calleeNativeSizeEstimate > threshold)
- {
-#ifdef DEBUG
- char * message = (char *)compAllocator->allocateMemory(128);
- sprintf(message, "Native estimate for function size exceeds threshold %g > %g (multiplier = %g).",
- calleeNativeSizeEstimate / NATIVE_CALL_SIZE_MULTIPLIER,
- threshold / NATIVE_CALL_SIZE_MULTIPLIER, multiplier);
- //pInlineInfo is null when we're determining the static hint for inlining.
-#else
- const char * message = "Native estimate for function size exceeds threshold.";
-#endif
-
- if (pInlineInfo != nullptr)
- {
- inlineResult->NoteFatal(InlineObservation::CALLSITE_EXCEEDS_THRESHOLD);
- }
- else
- {
- // Static hint case.... here the "callee" is the function being assessed.
- inlineResult->NoteFatal(InlineObservation::CALLEE_EXCEEDS_THRESHOLD);
- }
- }
- else
- {
- JITLOG((LL_INFO100000, "Native estimate for function size is within threshold for inlining %g <= %g (multiplier = %g)\n",
- calleeNativeSizeEstimate / NATIVE_CALL_SIZE_MULTIPLIER,
- threshold / NATIVE_CALL_SIZE_MULTIPLIER, multiplier));
-
- // Candidate has passed the profitability screen, update candidacy.
- inlineResult->Note(InlineObservation::CALLSITE_NATIVE_SIZE_ESTIMATE_OK);
- }
-
-#undef NATIVE_CALL_SIZE_MULTIPLIER
}
diff --git a/src/jit/inline.def b/src/jit/inline.def
index c2e6082189..554b60a640 100644
--- a/src/jit/inline.def
+++ b/src/jit/inline.def
@@ -35,7 +35,7 @@ INLINE_OBSERVATION(HAS_DELEGATE_INVOKE, bool, "delegate invoke",
INLINE_OBSERVATION(HAS_EH, bool, "has exception handling", FATAL, CALLEE)
INLINE_OBSERVATION(HAS_ENDFILTER, bool, "has endfilter", FATAL, CALLEE)
INLINE_OBSERVATION(HAS_ENDFINALLY, bool, "has endfinally", FATAL, CALLEE)
-INLINE_OBSERVATION(HAS_LEAVE, bool, "has leave" , FATAL, CALLEE)
+INLINE_OBSERVATION(HAS_LEAVE, bool, "has leave", FATAL, CALLEE)
INLINE_OBSERVATION(HAS_MANAGED_VARARGS, bool, "managed varargs", FATAL, CALLEE)
INLINE_OBSERVATION(HAS_NATIVE_VARARGS, bool, "native varargs", FATAL, CALLEE)
INLINE_OBSERVATION(HAS_NO_BODY, bool, "has no body", FATAL, CALLEE)
@@ -54,6 +54,7 @@ INLINE_OBSERVATION(MARKED_AS_SKIPPED, bool, "skipped by complus reques
INLINE_OBSERVATION(MAXSTACK_TOO_BIG, bool, "maxstack too big" , FATAL, CALLEE)
INLINE_OBSERVATION(NEEDS_SECURITY_CHECK, bool, "needs security check", FATAL, CALLEE)
INLINE_OBSERVATION(NO_METHOD_INFO, bool, "cannot get method info", FATAL, CALLEE)
+INLINE_OBSERVATION(NOT_PROFITABLE_INLINE, bool, "unprofitable inline", FATAL, CALLEE)
INLINE_OBSERVATION(RETURN_TYPE_IS_COMPOSITE, bool, "has composite return type", FATAL, CALLEE)
INLINE_OBSERVATION(STACK_CRAWL_MARK, bool, "uses stack crawl mark", FATAL, CALLEE)
INLINE_OBSERVATION(STFLD_NEEDS_HELPER, bool, "stfld needs helper", FATAL, CALLEE)
@@ -84,9 +85,9 @@ INLINE_OBSERVATION(IS_DISCRETIONARY_INLINE, bool, "can inline, check heurist
INLINE_OBSERVATION(IS_FORCE_INLINE, bool, "aggressive inline attribute", INFORMATION, CALLEE)
INLINE_OBSERVATION(IS_INSTANCE_CTOR, bool, "instance constructor", INFORMATION, CALLEE)
INLINE_OBSERVATION(IS_MOSTLY_LOAD_STORE, bool, "method is mostly load/store", INFORMATION, CALLEE)
+INLINE_OBSERVATION(IS_PROFITABLE_INLINE, bool, "profitable inline", INFORMATION, CALLEE)
INLINE_OBSERVATION(LOOKS_LIKE_WRAPPER, bool, "thin wrapper around a call", INFORMATION, CALLEE)
INLINE_OBSERVATION(MAXSTACK, int, "maxstack", INFORMATION, CALLEE)
-INLINE_OBSERVATION(NATIVE_SIZE_ESTIMATE, double, "native size estimate", INFORMATION, CALLEE)
INLINE_OBSERVATION(OPCODE, int, "next opcode in IL stream", INFORMATION, CALLEE)
INLINE_OBSERVATION(OPCODE_NORMED, int, "next opcode in IL stream", INFORMATION, CALLEE)
INLINE_OBSERVATION(NUMBER_OF_ARGUMENTS, int, "number of arguments", INFORMATION, CALLEE)
@@ -134,6 +135,7 @@ INLINE_OBSERVATION(LDARGA_NOT_LOCAL_VAR, bool, "ldarga not on local var",
INLINE_OBSERVATION(LDFLD_NEEDS_HELPER, bool, "ldfld needs helper", FATAL, CALLSITE)
INLINE_OBSERVATION(LDVIRTFN_ON_NON_VIRTUAL, bool, "ldvirtfn on non-virtual", FATAL, CALLSITE)
INLINE_OBSERVATION(NOT_CANDIDATE, bool, "not inline candidate", FATAL, CALLSITE)
+INLINE_OBSERVATION(NOT_PROFITABLE_INLINE, bool, "unprofitable inline", FATAL, CALLSITE)
INLINE_OBSERVATION(REQUIRES_SAME_THIS, bool, "requires same this", FATAL, CALLSITE)
INLINE_OBSERVATION(RETURN_TYPE_MISMATCH, bool, "return type mismatch", FATAL, CALLSITE)
INLINE_OBSERVATION(STFLD_NEEDS_HELPER, bool, "stfld needs helper", FATAL, CALLSITE)
@@ -144,12 +146,10 @@ INLINE_OBSERVATION(TOO_MANY_LOCALS, bool, "too many locals",
// ------ Call Site Information -------
-INLINE_OBSERVATION(BENEFIT_MULTIPLIER, double, "benefit multiplier", INFORMATION, CALLSITE)
INLINE_OBSERVATION(CONSTANT_ARG_FEEDS_TEST, bool, "constant argument feeds test", INFORMATION, CALLSITE)
INLINE_OBSERVATION(DEPTH, int, "depth", INFORMATION, CALLSITE)
INLINE_OBSERVATION(FREQUENCY, int, "execution frequency", INFORMATION, CALLSITE)
-INLINE_OBSERVATION(NATIVE_SIZE_ESTIMATE, double, "native size estimate", INFORMATION, CALLSITE)
-INLINE_OBSERVATION(NATIVE_SIZE_ESTIMATE_OK, bool, "native size estimate ok", INFORMATION, CALLSITE)
+INLINE_OBSERVATION(IS_PROFITABLE_INLINE, bool, "profitable inline", INFORMATION, CALLSITE)
// ------ Final Sentinel -------
diff --git a/src/jit/inline.h b/src/jit/inline.h
index 923140daa9..8e1cbea8b3 100644
--- a/src/jit/inline.h
+++ b/src/jit/inline.h
@@ -241,9 +241,7 @@ public:
virtual void NoteDouble(InlineObservation obs, double value) = 0;
// Policy determinations
- virtual double DetermineMultiplier() = 0;
- virtual int DetermineNativeSizeEstimate() = 0;
- virtual int DetermineCallsiteNativeSizeEstimate(CORINFO_METHOD_INFO* methodInfo) = 0;
+ virtual void DetermineProfitability(CORINFO_METHOD_INFO* methodInfo) = 0;
// Policy policies
virtual bool PropagateNeverToRuntime() const = 0;
@@ -320,6 +318,16 @@ public:
return InlDecisionIsCandidate(m_Policy->GetDecision());
}
+ // Has the policy determined this inline attempt is still viable
+ // and is a discretionary inline?
+ bool IsDiscretionaryCandidate() const
+ {
+ bool result = InlDecisionIsCandidate(m_Policy->GetDecision()) &&
+ (m_Policy->GetObservation() == InlineObservation::CALLEE_IS_DISCRETIONARY_INLINE);
+
+ return result;
+ }
+
// Has the policy made a determination?
bool IsDecided() const
{
@@ -373,22 +381,10 @@ public:
m_Policy->NoteDouble(obs, value);
}
- // Determine the benfit multiplier for this inline.
- double DetermineMultiplier()
- {
- return m_Policy->DetermineMultiplier();
- }
-
- // Determine the native size estimate for this inline
- int DetermineNativeSizeEstimate()
- {
- return m_Policy->DetermineNativeSizeEstimate();
- }
-
- // Determine the native size estimate for this call site
- int DetermineCallsiteNativeSizeEstimate(CORINFO_METHOD_INFO* methodInfo)
+ // Determine if this inline is profitable
+ void DetermineProfitability(CORINFO_METHOD_INFO* methodInfo)
{
- return m_Policy->DetermineCallsiteNativeSizeEstimate(methodInfo);
+ return m_Policy->DetermineProfitability(methodInfo);
}
// Ensure details of this inlining process are appropriately
diff --git a/src/jit/inlinepolicy.cpp b/src/jit/inlinepolicy.cpp
index a712ec7f59..a5956d1bf1 100644
--- a/src/jit/inlinepolicy.cpp
+++ b/src/jit/inlinepolicy.cpp
@@ -99,10 +99,6 @@ void LegacyPolicy::NoteBool(InlineObservation obs, bool value)
case InlineObservation::CALLSITE_CONSTANT_ARG_FEEDS_TEST:
m_ConstantFeedsConstantTest = value;
break;
- case InlineObservation::CALLSITE_NATIVE_SIZE_ESTIMATE_OK:
- // Passed the profitability screen. Update candidacy.
- SetCandidate(obs);
- break;
case InlineObservation::CALLEE_BEGIN_OPCODE_SCAN:
{
// Set up the state machine, if this inline is
@@ -120,17 +116,9 @@ void LegacyPolicy::NoteBool(InlineObservation obs, bool value)
case InlineObservation::CALLEE_END_OPCODE_SCAN:
{
- // We only expect to see this observation once, so the
- // native size estimate should have its initial value.
- assert(m_NativeSizeEstimate == NATIVE_SIZE_INVALID);
-
- // If we were using the state machine, get it to kick
- // out a size estimate.
if (m_StateMachine != nullptr)
{
m_StateMachine->End();
- m_NativeSizeEstimate = m_StateMachine->NativeSize;
- assert(m_NativeSizeEstimate != NATIVE_SIZE_INVALID);
}
break;
@@ -525,11 +513,9 @@ double LegacyPolicy::DetermineMultiplier()
int LegacyPolicy::DetermineNativeSizeEstimate()
{
// Should be a discretionary candidate.
- assert(m_Observation == InlineObservation::CALLEE_IS_DISCRETIONARY_INLINE);
- // Should have a valid state machine estimate.
- assert(m_NativeSizeEstimate != NATIVE_SIZE_INVALID);
+ assert(m_StateMachine != nullptr);
- return m_NativeSizeEstimate;
+ return m_StateMachine->NativeSize;
}
//------------------------------------------------------------------------
@@ -594,3 +580,82 @@ int LegacyPolicy::DetermineCallsiteNativeSizeEstimate(CORINFO_METHOD_INFO* methI
return callsiteSize;
}
+
+//------------------------------------------------------------------------
+// DetermineProfitability: determine if this inline is profitable
+//
+// Arguments:
+// methodInfo -- method info for the callee
+//
+// Notes:
+// A profitable inline is one that is projected to have a beneficial
+// size/speed tradeoff.
+//
+// It is expected that this method is only invoked for discretionary
+// candidates, since it does not make sense to do this assessment for
+// failed, always, or forced inlines.
+
+void LegacyPolicy::DetermineProfitability(CORINFO_METHOD_INFO* methodInfo)
+{
+ assert(InlDecisionIsCandidate(m_Decision));
+ assert(m_Observation == InlineObservation::CALLEE_IS_DISCRETIONARY_INLINE);
+
+ const int calleeNativeSizeEstimate = DetermineNativeSizeEstimate();
+ const int callsiteNativeSizeEstimate = DetermineCallsiteNativeSizeEstimate(methodInfo);
+ const double multiplier = DetermineMultiplier();
+ const int threshold = (int)(callsiteNativeSizeEstimate * multiplier);
+
+ JITDUMP("calleeNativeSizeEstimate=%d\n", calleeNativeSizeEstimate)
+ JITDUMP("callsiteNativeSizeEstimate=%d\n", callsiteNativeSizeEstimate);
+ JITDUMP("benefit multiplier=%g\n", multiplier);
+ JITDUMP("threshold=%d\n", threshold);
+
+#if DEBUG
+ // Size estimates are in bytes * 10
+ const double sizeDescaler = 10.0;
+#endif
+
+ // Reject if callee size is over the threshold
+ if (calleeNativeSizeEstimate > threshold)
+ {
+ // Inline appears to be unprofitable
+ JITLOG_THIS(m_Compiler,
+ (LL_INFO100000,
+ "Native estimate for function size exceedsn threshold"
+ " for inlining %g > %g (multiplier = %g)\n",
+ calleeNativeSizeEstimate / sizeDescaler,
+ threshold / sizeDescaler,
+ multiplier));
+
+ // Fail the inline
+ if (m_IsPrejitRoot)
+ {
+ SetNever(InlineObservation::CALLEE_NOT_PROFITABLE_INLINE);
+ }
+ else
+ {
+ SetFailure(InlineObservation::CALLSITE_NOT_PROFITABLE_INLINE);
+ }
+ }
+ else
+ {
+ // Inline appears to be profitable
+ JITLOG_THIS(m_Compiler,
+ (LL_INFO100000,
+ "Native estimate for function size is within threshold"
+ " for inlining %g <= %g (multiplier = %g)\n",
+ calleeNativeSizeEstimate / sizeDescaler,
+ threshold / sizeDescaler,
+ multiplier));
+
+ // Update candidacy
+ if (m_IsPrejitRoot)
+ {
+ SetCandidate(InlineObservation::CALLEE_IS_PROFITABLE_INLINE);
+ }
+ else
+ {
+ SetCandidate(InlineObservation::CALLSITE_IS_PROFITABLE_INLINE);
+ }
+ }
+}
diff --git a/src/jit/inlinepolicy.h b/src/jit/inlinepolicy.h
index 0f9138ffb8..34e1b99e78 100644
--- a/src/jit/inlinepolicy.h
+++ b/src/jit/inlinepolicy.h
@@ -43,7 +43,6 @@ public:
, m_Compiler(compiler)
, m_StateMachine(nullptr)
, m_CodeSize(0)
- , m_NativeSizeEstimate(NATIVE_SIZE_INVALID)
, m_CallsiteFrequency(InlineCallsiteFrequency::UNUSED)
, m_IsForceInline(false)
, m_IsForceInlineKnown(false)
@@ -67,9 +66,7 @@ public:
void NoteDouble(InlineObservation obs, double value) override;
// Policy determinations
- double DetermineMultiplier() override;
- int DetermineNativeSizeEstimate() override;
- int DetermineCallsiteNativeSizeEstimate(CORINFO_METHOD_INFO* methodInfo) override;
+ void DetermineProfitability(CORINFO_METHOD_INFO* methodInfo) override;
// Policy policies
bool PropagateNeverToRuntime() const override { return true; }
@@ -85,6 +82,9 @@ private:
void SetCandidate(InlineObservation obs);
void SetFailure(InlineObservation obs);
void SetNever(InlineObservation obs);
+ double DetermineMultiplier();
+ int DetermineNativeSizeEstimate();
+ int DetermineCallsiteNativeSizeEstimate(CORINFO_METHOD_INFO* methodInfo);
// Constants
const unsigned MAX_BASIC_BLOCKS = 5;
@@ -93,7 +93,6 @@ private:
Compiler* m_Compiler;
CodeSeqSM* m_StateMachine;
unsigned m_CodeSize;
- int m_NativeSizeEstimate;
InlineCallsiteFrequency m_CallsiteFrequency;
bool m_IsForceInline :1;
bool m_IsForceInlineKnown :1;