void LegacyPolicy::NoteFatal(InlineObservation obs) { // As a safeguard, all fatal impact must be // reported via noteFatal. assert(InlGetImpact(obs) == InlineImpact::FATAL); NoteInternal(obs); assert(InlDecisionIsFailure(m_Decision)); }
const char* InlGetImpactString(InlineObservation obs) { InlineImpact i = InlGetImpact(obs); switch (i) { case InlineImpact::FATAL: return "correctness -- fatal"; case InlineImpact::FUNDAMENTAL: return "correctness -- fundamental limitation"; case InlineImpact::LIMITATION: return "correctness -- jit limitation"; case InlineImpact::PERFORMANCE: return "performance"; case InlineImpact::INFORMATION: return "information"; default: return "unexpected impact"; } }
//------------------------------------------------------------------------ // 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); } }