Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit a46475c

Browse files
authored
JIT: fix issue with inline observations (#15713)
In DEBUG/CHECK builds the jit tries to keep track of failed inlines. Because inlines can be rejected "early" (when the parent method is being imported) as well as "late" (when their call site is encountered by the inliner) there is a tracking mechanism to convey the early observations that cause failures to be resurrected later on. These observations sometimes didn't end up in the inline context, leading to assertions when dumping methods. Fix is to add a new way to propagate the earlier observation to the context that bypasses some of the policy sanity checks and simply record the reason that the inline failed.
1 parent a91d3fd commit a46475c

File tree

5 files changed

+46
-16
lines changed

5 files changed

+46
-16
lines changed

src/jit/flowgraph.cpp

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22077,22 +22077,8 @@ void Compiler::fgNoteNonInlineCandidate(GenTreeStmt* stmt, GenTreeCall* call)
2207722077
currentObservation = priorObservation;
2207822078
}
2207922079

22080-
// Would like to just call noteFatal here, since this
22081-
// observation blocked candidacy, but policy comes into play
22082-
// here too. Also note there's no need to re-report these
22083-
// failures, since we reported them during the initial
22084-
// candidate scan.
22085-
InlineImpact impact = InlGetImpact(currentObservation);
22086-
22087-
if (impact == InlineImpact::FATAL)
22088-
{
22089-
inlineResult.NoteFatal(currentObservation);
22090-
}
22091-
else
22092-
{
22093-
inlineResult.Note(currentObservation);
22094-
}
22095-
22080+
// Propagate the prior failure observation to this result.
22081+
inlineResult.NotePriorFailure(currentObservation);
2209622082
inlineResult.SetReported();
2209722083

2209822084
if (call->gtCallType == CT_USER_FUNC)

src/jit/inline.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1260,6 +1260,8 @@ InlineContext* InlineStrategy::NewFailure(GenTreeStmt* stmt, InlineResult* inlin
12601260
failedContext->m_Callee = inlineResult->GetCallee();
12611261
failedContext->m_Success = false;
12621262

1263+
assert(InlIsValidObservation(failedContext->m_Observation));
1264+
12631265
#if defined(DEBUG) || defined(INLINE_DATA)
12641266

12651267
// Update offset with more accurate info

src/jit/inline.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,9 @@ class InlinePolicy
254254

255255
#if defined(DEBUG) || defined(INLINE_DATA)
256256

257+
// Record observation for prior failure
258+
virtual void NotePriorFailure(InlineObservation obs) = 0;
259+
257260
// Name of the policy
258261
virtual const char* GetName() const = 0;
259262
// Detailed data value dump
@@ -398,6 +401,17 @@ class InlineResult
398401
m_Policy->NoteInt(obs, value);
399402
}
400403

404+
#if defined(DEBUG) || defined(INLINE_DATA)
405+
406+
// Record observation from an earlier failure.
407+
void NotePriorFailure(InlineObservation obs)
408+
{
409+
m_Policy->NotePriorFailure(obs);
410+
assert(IsFailure());
411+
}
412+
413+
#endif // defined(DEBUG) || defined(INLINE_DATA)
414+
401415
// Determine if this inline is profitable
402416
void DetermineProfitability(CORINFO_METHOD_INFO* methodInfo)
403417
{

src/jit/inlinepolicy.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,27 @@ void LegalPolicy::NoteFatal(InlineObservation obs)
104104
assert(InlDecisionIsFailure(m_Decision));
105105
}
106106

107+
#if defined(DEBUG) || defined(INLINE_DATA)
108+
109+
//------------------------------------------------------------------------
110+
// NotePriorFailure: record reason for earlier inline failure
111+
//
112+
// Arguments:
113+
// obs - the current obsevation
114+
//
115+
// Notes:
116+
// Used to "resurrect" failure observations from the early inline
117+
// screen when building the inline context tree. Only used during
118+
// debug modes.
119+
120+
void LegalPolicy::NotePriorFailure(InlineObservation obs)
121+
{
122+
NoteInternal(obs);
123+
assert(InlDecisionIsFailure(m_Decision));
124+
}
125+
126+
#endif // defined(DEBUG) || defined(INLINE_DATA)
127+
107128
//------------------------------------------------------------------------
108129
// NoteInternal: helper for handling an observation
109130
//

src/jit/inlinepolicy.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,13 @@ class LegalPolicy : public InlinePolicy
5656
// Handle an observation that must cause inlining to fail.
5757
void NoteFatal(InlineObservation obs) override;
5858

59+
#if defined(DEBUG) || defined(INLINE_DATA)
60+
61+
// Record observation for prior failure
62+
void NotePriorFailure(InlineObservation obs) override;
63+
64+
#endif // defined(DEBUG) || defined(INLINE_DATA)
65+
5966
protected:
6067
// Helper methods
6168
void NoteInternal(InlineObservation obs);

0 commit comments

Comments
 (0)