Skip to content

Commit

Permalink
JIT: allow some aggressive inlines to go over budget
Browse files Browse the repository at this point in the history
If we have a very small root method that calls a large method that is marked with
AggressiveInlining, we may fail to inline because of a budget check.

Allow such inlines to bypass the check.

Closes dotnet#38106.
  • Loading branch information
AndyAyersMS committed Jun 19, 2020
1 parent 2e75b8f commit 8a89a0d
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 7 deletions.
12 changes: 10 additions & 2 deletions src/coreclr/src/jit/inline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1151,8 +1151,16 @@ void InlineStrategy::NoteOutcome(InlineContext* context)

bool InlineStrategy::BudgetCheck(unsigned ilSize)
{
int timeDelta = EstimateInlineTime(ilSize);
return (timeDelta + m_CurrentTimeEstimate > m_CurrentTimeBudget);
const int timeDelta = EstimateInlineTime(ilSize);
const bool result = (timeDelta + m_CurrentTimeEstimate > m_CurrentTimeBudget);

if (result)
{
JITDUMP("\nBudgetCheck: for IL Size %d, timeDelta %d + currentEstimate %d > currentBudget %d\n", ilSize,
timeDelta, m_CurrentTimeEstimate, m_CurrentTimeBudget);
}

return result;
}

//------------------------------------------------------------------------
Expand Down
31 changes: 26 additions & 5 deletions src/coreclr/src/jit/inlinepolicy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -369,14 +369,33 @@ void DefaultPolicy::NoteBool(InlineObservation obs, bool value)
// the candidate IL size during the inlining pass it
// "reestablishes" candidacy rather than alters
// candidacy ... so instead we bail out here.

//
if (!m_IsPrejitRoot)
{
InlineStrategy* strategy = m_RootCompiler->m_inlineStrategy;
bool overBudget = strategy->BudgetCheck(m_CodeSize);
const bool overBudget = strategy->BudgetCheck(m_CodeSize);

if (overBudget)
{
SetFailure(InlineObservation::CALLSITE_OVER_BUDGET);
// If the candidate is a forceinline and the callsite is
// not too deep, allow the inline even if it goes over budget.
//
// For now, "not too deep" means a top-level inline. Note
// depth 0 is used for the root method, so inline candiate depth
// will be 1 or more.
//
assert(m_IsForceInlineKnown);
assert(m_CallsiteDepth > 0);
const bool allowOverBudget = m_IsForceInline && (m_CallsiteDepth == 1);

if (allowOverBudget)
{
JITDUMP("Allowing over-budget top-level forceinline\n");
}
else
{
SetFailure(InlineObservation::CALLSITE_OVER_BUDGET);
}
}
}

Expand Down Expand Up @@ -531,9 +550,9 @@ void DefaultPolicy::NoteInt(InlineObservation obs, int value)

case InlineObservation::CALLSITE_DEPTH:
{
unsigned depth = static_cast<unsigned>(value);
m_CallsiteDepth = static_cast<unsigned>(value);

if (depth > m_RootCompiler->m_inlineStrategy->GetMaxInlineDepth())
if (m_CallsiteDepth > m_RootCompiler->m_inlineStrategy->GetMaxInlineDepth())
{
SetFailure(InlineObservation::CALLSITE_IS_TOO_DEEP);
}
Expand Down Expand Up @@ -1858,6 +1877,7 @@ void DiscretionaryPolicy::DumpSchema(FILE* file) const
fprintf(file, ",CallerHasNewObj");
fprintf(file, ",CalleeDoesNotReturn");
fprintf(file, ",CalleeHasGCStruct");
fprintf(file, ",CallsiteDepth");
}

//------------------------------------------------------------------------
Expand Down Expand Up @@ -1940,6 +1960,7 @@ void DiscretionaryPolicy::DumpData(FILE* file) const
fprintf(file, ",%u", m_CallerHasNewObj ? 1 : 0);
fprintf(file, ",%u", m_IsNoReturn ? 1 : 0);
fprintf(file, ",%u", m_CalleeHasGCStruct ? 1 : 0);
fprintf(file, ",%u", m_CallsiteDepth);
}

#endif // defined(DEBUG) || defined(INLINE_DATA)
Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/src/jit/inlinepolicy.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ class DefaultPolicy : public LegalPolicy
, m_Multiplier(0.0)
, m_CodeSize(0)
, m_CallsiteFrequency(InlineCallsiteFrequency::UNUSED)
, m_CallsiteDepth(0)
, m_InstructionCount(0)
, m_LoadStoreCount(0)
, m_ArgFeedsTest(0)
Expand Down Expand Up @@ -154,6 +155,7 @@ class DefaultPolicy : public LegalPolicy
double m_Multiplier;
unsigned m_CodeSize;
InlineCallsiteFrequency m_CallsiteFrequency;
unsigned m_CallsiteDepth;
unsigned m_InstructionCount;
unsigned m_LoadStoreCount;
unsigned m_ArgFeedsTest;
Expand Down

0 comments on commit 8a89a0d

Please sign in to comment.