Esempio n. 1
0
void LegacyPolicy::NoteSuccess()
{
    assert(InlDecisionIsCandidate(m_Decision));
    m_Decision = InlineDecision::SUCCESS;
}
Esempio n. 2
0
//------------------------------------------------------------------------
// 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);
    }
}
Esempio n. 3
0
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);
        }
    }
}