void LegacyPolicy::NoteSuccess() { assert(InlDecisionIsCandidate(m_Decision)); m_Decision = InlineDecision::SUCCESS; }
//------------------------------------------------------------------------ // NoteBool: handle a boolean observation with non-fatal impact // // Arguments: // obs - the current obsevation // value - the value of the observation void LegacyPolicy::NoteBool(InlineObservation obs, bool value) { // Check the impact InlineImpact impact = InlGetImpact(obs); // As a safeguard, all fatal impact must be // reported via noteFatal. assert(impact != InlineImpact::FATAL); // Handle most information here bool isInformation = (impact == InlineImpact::INFORMATION); bool propagate = !isInformation; if (isInformation) { switch (obs) { case InlineObservation::CALLEE_IS_FORCE_INLINE: // We may make the force-inline observation more than // once. All observations should agree. assert(!m_IsForceInlineKnown || (m_IsForceInline == value)); m_IsForceInline = value; m_IsForceInlineKnown = true; break; case InlineObservation::CALLEE_IS_INSTANCE_CTOR: m_IsInstanceCtor = value; break; case InlineObservation::CALLEE_CLASS_PROMOTABLE: m_IsFromPromotableValueClass = value; break; case InlineObservation::CALLEE_HAS_SIMD: m_HasSimd = value; break; case InlineObservation::CALLEE_LOOKS_LIKE_WRAPPER: m_LooksLikeWrapperMethod = value; break; case InlineObservation::CALLEE_ARG_FEEDS_CONSTANT_TEST: m_ArgFeedsConstantTest = value; break; case InlineObservation::CALLEE_ARG_FEEDS_RANGE_CHECK: m_ArgFeedsRangeCheck = value; break; case InlineObservation::CALLEE_IS_MOSTLY_LOAD_STORE: m_MethodIsMostlyLoadStore = value; break; case InlineObservation::CALLEE_HAS_SWITCH: // Pass this one on, it should cause inlining to fail. propagate = true; break; 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 // discretionary and is still a candidate. if (InlDecisionIsCandidate(m_Decision) && (m_Observation == InlineObservation::CALLEE_IS_DISCRETIONARY_INLINE)) { // Better not have a state machine already. assert(m_StateMachine == nullptr); m_StateMachine = new (m_Compiler, CMK_Inlining) CodeSeqSM; m_StateMachine->Start(m_Compiler); } break; } 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; } default: // Ignore the remainder for now break; } } if (propagate) { NoteInternal(obs); } }
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); } } }