Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JIT: Preliminary for enabling inlining late devirted calls #111782

Merged
merged 5 commits into from
Jan 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions src/coreclr/jit/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -2866,6 +2866,7 @@ class Compiler

bool bbInCatchHandlerILRange(BasicBlock* blk);
bool bbInFilterILRange(BasicBlock* blk);
bool bbInCatchHandlerBBRange(BasicBlock* blk);
bool bbInFilterBBRange(BasicBlock* blk);
bool bbInTryRegions(unsigned regionIndex, BasicBlock* blk);
bool bbInExnFlowRegions(unsigned regionIndex, BasicBlock* blk);
Expand Down Expand Up @@ -5223,15 +5224,13 @@ class Compiler
void impMarkInlineCandidate(GenTree* call,
CORINFO_CONTEXT_HANDLE exactContextHnd,
bool exactContextNeedsRuntimeLookup,
CORINFO_CALL_INFO* callInfo,
IL_OFFSET ilOffset);
CORINFO_CALL_INFO* callInfo);

void impMarkInlineCandidateHelper(GenTreeCall* call,
uint8_t candidateIndex,
CORINFO_CONTEXT_HANDLE exactContextHnd,
bool exactContextNeedsRuntimeLookup,
CORINFO_CALL_INFO* callInfo,
IL_OFFSET ilOffset,
InlineResult* inlineResult);

bool impTailCallRetTypeCompatible(bool allowWidening,
Expand Down
3 changes: 2 additions & 1 deletion src/coreclr/jit/fginline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1323,7 +1323,8 @@ void Compiler::fgInvokeInlineeCompiler(GenTreeCall* call, InlineResult* inlineRe
// (This could happen for example for a BBJ_THROW block fall through a BBJ_RETURN block which
// causes the BBJ_RETURN block not to be imported at all.)
// Fail the inlining attempt
if ((inlineCandidateInfo->fncRetType != TYP_VOID) && (inlineCandidateInfo->retExpr->gtSubstExpr == nullptr))
if ((inlineCandidateInfo->methInfo.args.retType != CORINFO_TYPE_VOID) &&
(inlineCandidateInfo->retExpr->gtSubstExpr == nullptr))
{
#ifdef DEBUG
if (verbose)
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/importer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10981,7 +10981,7 @@ bool Compiler::impReturnInstruction(int prefixFlags, OPCODE& opcode)
// Make sure the type matches the original call.

var_types returnType = genActualType(op2->gtType);
var_types originalCallType = inlCandInfo->fncRetType;
var_types originalCallType = genActualType(JITtype2varType(inlCandInfo->methInfo.args.retType));
if ((returnType != originalCallType) && (originalCallType == TYP_STRUCT))
{
originalCallType = impNormStructType(inlCandInfo->methInfo.args.retTypeClass);
Expand Down
29 changes: 10 additions & 19 deletions src/coreclr/jit/importercalls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1030,7 +1030,7 @@ var_types Compiler::impImportCall(OPCODE opcode,
INDEBUG(call->AsCall()->gtRawILOffset = rawILOffset);

// Is it an inline candidate?
impMarkInlineCandidate(call, exactContextHnd, exactContextNeedsRuntimeLookup, callInfo, rawILOffset);
impMarkInlineCandidate(call, exactContextHnd, exactContextNeedsRuntimeLookup, callInfo);
}

// append the call node.
Expand Down Expand Up @@ -1240,7 +1240,7 @@ var_types Compiler::impImportCall(OPCODE opcode,
INDEBUG(call->AsCall()->gtRawILOffset = rawILOffset);

// Is it an inline candidate?
impMarkInlineCandidate(call, exactContextHnd, exactContextNeedsRuntimeLookup, callInfo, rawILOffset);
impMarkInlineCandidate(call, exactContextHnd, exactContextNeedsRuntimeLookup, callInfo);
}

// Extra checks for tail calls and tail recursion.
Expand Down Expand Up @@ -7450,7 +7450,6 @@ void Compiler::addGuardedDevirtualizationCandidate(GenTreeCall* call,
// exactContextHnd -- context handle for inlining
// exactContextNeedsRuntimeLookup -- true if context required runtime lookup
// callInfo -- call info from VM
// ilOffset -- the actual IL offset of the instruction that produced this inline candidate
//
// Notes:
// Mostly a wrapper for impMarkInlineCandidateHelper that also undoes
Expand All @@ -7460,8 +7459,7 @@ void Compiler::addGuardedDevirtualizationCandidate(GenTreeCall* call,
void Compiler::impMarkInlineCandidate(GenTree* callNode,
CORINFO_CONTEXT_HANDLE exactContextHnd,
bool exactContextNeedsRuntimeLookup,
CORINFO_CALL_INFO* callInfo,
IL_OFFSET ilOffset)
CORINFO_CALL_INFO* callInfo)
{
if (!opts.OptEnabled(CLFLG_INLINING))
{
Expand All @@ -7484,7 +7482,7 @@ void Compiler::impMarkInlineCandidate(GenTree* callNode,

// Do the actual evaluation
impMarkInlineCandidateHelper(call, candidateId, exactContextHnd, exactContextNeedsRuntimeLookup, callInfo,
ilOffset, &inlineResult);
&inlineResult);
// Ignore non-inlineable candidates
// TODO: Consider keeping them to just devirtualize without inlining, at least for interface
// calls on NativeAOT, but that requires more changes elsewhere too.
Expand All @@ -7507,8 +7505,7 @@ void Compiler::impMarkInlineCandidate(GenTree* callNode,
const uint8_t candidatesCount = call->GetInlineCandidatesCount();
assert(candidatesCount <= 1);
InlineResult inlineResult(this, call, nullptr, "impMarkInlineCandidate");
impMarkInlineCandidateHelper(call, 0, exactContextHnd, exactContextNeedsRuntimeLookup, callInfo, ilOffset,
&inlineResult);
impMarkInlineCandidateHelper(call, 0, exactContextHnd, exactContextNeedsRuntimeLookup, callInfo, &inlineResult);
}

// If this call is an inline candidate or is not a guarded devirtualization
Expand Down Expand Up @@ -7541,7 +7538,6 @@ void Compiler::impMarkInlineCandidate(GenTree* callNode,
// exactContextHnd -- context handle for inlining
// exactContextNeedsRuntimeLookup -- true if context required runtime lookup
// callInfo -- call info from VM
// ilOffset -- IL offset of instruction creating the inline candidate
//
// Notes:
// If callNode is an inline candidate, this method sets the flag
Expand All @@ -7558,7 +7554,6 @@ void Compiler::impMarkInlineCandidateHelper(GenTreeCall* call,
CORINFO_CONTEXT_HANDLE exactContextHnd,
bool exactContextNeedsRuntimeLookup,
CORINFO_CALL_INFO* callInfo,
IL_OFFSET ilOffset,
InlineResult* inlineResult)
{
// Let the strategy know there's another call
Expand Down Expand Up @@ -7696,21 +7691,20 @@ void Compiler::impMarkInlineCandidateHelper(GenTreeCall* call,
if (!(methAttr & CORINFO_FLG_FORCEINLINE))
{
/* Don't bother inline blocks that are in the filter region */
if (bbInCatchHandlerILRange(compCurBB))
if (bbInCatchHandlerBBRange(compCurBB))
{
#ifdef DEBUG
if (verbose)
{
printf("\nWill not inline blocks that are in the catch handler region\n");
}

#endif

inlineResult->NoteFatal(InlineObservation::CALLSITE_IS_WITHIN_CATCH);
return;
}

if (bbInFilterILRange(compCurBB))
if (bbInFilterBBRange(compCurBB))
{
#ifdef DEBUG
if (verbose)
Expand Down Expand Up @@ -7767,7 +7761,6 @@ void Compiler::impMarkInlineCandidateHelper(GenTreeCall* call,
// The new value should not be null.
assert(inlineCandidateInfo != nullptr);
inlineCandidateInfo->exactContextNeedsRuntimeLookup = exactContextNeedsRuntimeLookup;
inlineCandidateInfo->ilOffset = ilOffset;

// If we're in an inlinee compiler, and have a return spill temp, and this inline candidate
// is also a tail call candidate, it can use the same return spill temp.
Expand Down Expand Up @@ -9201,12 +9194,11 @@ void Compiler::impCheckCanInline(GenTreeCall* call,
CORINFO_CLASS_HANDLE clsHandle = compCompHnd->getMethodClass(ftn);
unsigned const clsAttr = compCompHnd->getClassAttribs(clsHandle);

#ifdef DEBUG
// Return type
//
var_types const fncRetType = pParam->call->TypeGet();

#ifdef DEBUG
var_types fncRealRetType = JITtype2varType(methInfo.args.retType);
var_types const fncRetType = pParam->call->gtReturnType;
var_types const fncRealRetType = JITtype2varType(methInfo.args.retType);

assert((genActualType(fncRealRetType) == genActualType(fncRetType)) ||
// <BUGNUM> VSW 288602 </BUGNUM>
Expand Down Expand Up @@ -9250,7 +9242,6 @@ void Compiler::impCheckCanInline(GenTreeCall* call,
pInfo->clsAttr = clsAttr;
pInfo->methAttr = pParam->methAttr;
pInfo->initClassResult = initClassResult;
pInfo->fncRetType = fncRetType;
pInfo->exactContextNeedsRuntimeLookup = false;
pInfo->inlinersContext = pParam->pThis->compInlineContext;

Expand Down
3 changes: 0 additions & 3 deletions src/coreclr/jit/inline.h
Original file line number Diff line number Diff line change
Expand Up @@ -622,10 +622,7 @@ struct InlineCandidateInfo : public HandleHistogramProfileCandidateInfo
unsigned clsAttr;
unsigned methAttr;

// actual IL offset of instruction that resulted in this inline candidate
IL_OFFSET ilOffset;
CorInfoInitClassResult initClassResult;
var_types fncRetType;
bool exactContextNeedsRuntimeLookup;
InlineContext* inlinersContext;
};
Expand Down
22 changes: 22 additions & 0 deletions src/coreclr/jit/jiteh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,28 @@ bool Compiler::bbInFilterILRange(BasicBlock* blk)
return HBtab->InFilterRegionILRange(blk);
}

//------------------------------------------------------------------------
// bbInCatchHandlerBBRange:
// Check if this block is part of a catch handler.
//
// Arguments:
// blk - The block
//
// Return Value:
// True if the block is part of a catch handler clause. Otherwise false.
//
bool Compiler::bbInCatchHandlerBBRange(BasicBlock* blk)
{
EHblkDsc* HBtab = ehGetBlockHndDsc(blk);

if (HBtab == nullptr)
{
return false;
}

return HBtab->HasCatchHandler() && HBtab->InHndRegionBBRange(blk);
}

//------------------------------------------------------------------------
// bbInFilterBBRange:
// Check if this block is part of a filter.
Expand Down
Loading