Skip to content

Commit

Permalink
JIT: boost inlining when callee unboxes an arg
Browse files Browse the repository at this point in the history
Especially so if the caller is passing an exact type. This may lead
to the JIT being able to stack allocate the box and promote the underlying
payload.

Fixes dotnet#104479
  • Loading branch information
AndyAyersMS committed Dec 10, 2024
1 parent 016d356 commit f4da87d
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 0 deletions.
18 changes: 18 additions & 0 deletions src/coreclr/jit/fgbasic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1106,6 +1106,24 @@ void Compiler::fgFindJumpTargets(const BYTE* codeAddr, IL_OFFSET codeSize, Fixed
break;
}

case CEE_UNBOX:
case CEE_UNBOX_ANY:
{
if (makeInlineObservations)
{
FgStack::FgSlot slot = pushedStack.Top();
if (FgStack::IsExactArgument(slot, impInlineInfo))
{
compInlineResult->Note(InlineObservation::CALLSITE_UNBOX_EXACT_ARG);
}
else if (FgStack::IsArgument(slot))
{
compInlineResult->Note(InlineObservation::CALLEE_UNBOX_ARG);
}
}
break;
}

case CEE_CASTCLASS:
case CEE_ISINST:
{
Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/jit/inline.def
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ INLINE_OBSERVATION(NUMBER_OF_ARGUMENTS, int, "number of arguments",
INLINE_OBSERVATION(NUMBER_OF_BASIC_BLOCKS, int, "number of basic blocks", INFORMATION, CALLEE)
INLINE_OBSERVATION(NUMBER_OF_LOCALS, int, "number of locals", INFORMATION, CALLEE)
INLINE_OBSERVATION(RANDOM_ACCEPT, bool, "random accept", INFORMATION, CALLEE)
INLINE_OBSERVATION(UNBOX_ARG, int, "callee unboxes arg", INFORMATION, CALLEE)
INLINE_OBSERVATION(UNSUPPORTED_OPCODE, bool, "unsupported opcode", INFORMATION, CALLEE)

// ------ Caller Correctness -------
Expand Down Expand Up @@ -194,6 +195,7 @@ INLINE_OBSERVATION(LOG_REPLAY_ACCEPT, bool, "accepted by log replay",
INLINE_OBSERVATION(PROFILE_FREQUENCY, double, "frequency from profile data", INFORMATION, CALLSITE)
INLINE_OBSERVATION(RANDOM_ACCEPT, bool, "random accept", INFORMATION, CALLSITE)
INLINE_OBSERVATION(WEIGHT, int, "frequency from block weight", INFORMATION, CALLSITE)
INLINE_OBSERVATION(UNBOX_EXACT_ARG, int, "unbox of arg with exact class", INFORMATION, CALLSITE)

// ------ Final Sentinel -------

Expand Down
32 changes: 32 additions & 0 deletions src/coreclr/jit/inlinepolicy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1362,6 +1362,14 @@ void ExtendedDefaultPolicy::NoteBool(InlineObservation obs, bool value)
m_IsCallsiteInNoReturnRegion = value;
break;

case InlineObservation::CALLEE_UNBOX_ARG:
m_ArgUnbox++;
break;

case InlineObservation::CALLSITE_UNBOX_EXACT_ARG:
m_ArgUnboxExact++;
break;

default:
DefaultPolicy::NoteBool(obs, value);
break;
Expand Down Expand Up @@ -1716,6 +1724,30 @@ double ExtendedDefaultPolicy::DetermineMultiplier()
JITDUMP("\nPrejit root candidate has arg that feeds a conditional. Multiplier increased to %g.", multiplier);
}

if (m_ArgUnboxExact > 0)
{
// Callee has unbox(arg), caller supplies exact type (a box)
// We can likely optimize
multiplier += 4.0;
JITDUMP("\nInline candidate has %d exact arg unboxes. Multiplier increased to %g.", m_ArgUnboxExact,
multiplier);
}

if (m_ArgUnbox > 0)
{
// Callee has unbox(arg), caller arg not known type
if (m_IsPrejitRoot)
{
// Assume these might be met with exact type args
multiplier += 4.0;
}
else
{
multiplier += 1.0;
}
JITDUMP("\nInline candidate has %d arg unboxes. Multiplier increased to %g.", m_ArgUnboxExact, multiplier);
}

switch (m_CallsiteFrequency)
{
case InlineCallsiteFrequency::RARE:
Expand Down
4 changes: 4 additions & 0 deletions src/coreclr/jit/inlinepolicy.h
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,8 @@ class ExtendedDefaultPolicy : public DefaultPolicy
, m_UnrollableMemop(0)
, m_Switch(0)
, m_DivByCns(0)
, m_ArgUnbox(0)
, m_ArgUnboxExact(0)
, m_ReturnsStructByValue(false)
, m_IsFromValueClass(false)
, m_NonGenericCallsGeneric(false)
Expand Down Expand Up @@ -272,6 +274,8 @@ class ExtendedDefaultPolicy : public DefaultPolicy
unsigned m_UnrollableMemop;
unsigned m_Switch;
unsigned m_DivByCns;
unsigned m_ArgUnbox;
unsigned m_ArgUnboxExact;
bool m_ReturnsStructByValue : 1;
bool m_IsFromValueClass : 1;
bool m_NonGenericCallsGeneric : 1;
Expand Down

0 comments on commit f4da87d

Please sign in to comment.