diff --git a/src/coreclr/jit/fgbasic.cpp b/src/coreclr/jit/fgbasic.cpp index 30a3a83581a3b..c3ac9e7bf9d11 100644 --- a/src/coreclr/jit/fgbasic.cpp +++ b/src/coreclr/jit/fgbasic.cpp @@ -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: { diff --git a/src/coreclr/jit/inline.def b/src/coreclr/jit/inline.def index b1152d6f9ecc0..efacbd4deb27b 100644 --- a/src/coreclr/jit/inline.def +++ b/src/coreclr/jit/inline.def @@ -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 ------- @@ -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 ------- diff --git a/src/coreclr/jit/inlinepolicy.cpp b/src/coreclr/jit/inlinepolicy.cpp index d7b7bf6e1a024..d22676a62a3ea 100644 --- a/src/coreclr/jit/inlinepolicy.cpp +++ b/src/coreclr/jit/inlinepolicy.cpp @@ -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; @@ -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: diff --git a/src/coreclr/jit/inlinepolicy.h b/src/coreclr/jit/inlinepolicy.h index a8d8e67f1db3c..d08fbf7b32309 100644 --- a/src/coreclr/jit/inlinepolicy.h +++ b/src/coreclr/jit/inlinepolicy.h @@ -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) @@ -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;