Skip to content

Clean up GenTreeCall's inline info #86540

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

Merged
merged 1 commit into from
May 20, 2023
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
6 changes: 3 additions & 3 deletions src/coreclr/jit/fginline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -752,7 +752,7 @@ void Compiler::fgMorphCallInline(GenTreeCall* call, InlineResult* inlineResult)
{
bool inliningFailed = false;

InlineCandidateInfo* inlCandInfo = call->gtInlineCandidateInfo;
InlineCandidateInfo* inlCandInfo = call->GetInlineCandidateInfo();

// Is this call an inline candidate?
if (call->IsInlineCandidate())
Expand All @@ -778,7 +778,7 @@ void Compiler::fgMorphCallInline(GenTreeCall* call, InlineResult* inlineResult)
#ifdef DEBUG
// In debug we always put all inline attempts into the inline tree.
InlineContext* ctx =
m_inlineStrategy->NewContext(call->gtInlineCandidateInfo->inlinersContext, fgMorphStmt, call);
m_inlineStrategy->NewContext(call->GetInlineCandidateInfo()->inlinersContext, fgMorphStmt, call);
ctx->SetFailed(inlineResult);
#endif
}
Expand Down Expand Up @@ -1045,7 +1045,7 @@ void Compiler::fgInvokeInlineeCompiler(GenTreeCall* call, InlineResult* inlineRe
inlineInfo.hasSIMDTypeArgLocalOrReturn = false;
#endif // FEATURE_SIMD

InlineCandidateInfo* inlineCandidateInfo = call->gtInlineCandidateInfo;
InlineCandidateInfo* inlineCandidateInfo = call->GetInlineCandidateInfo();
noway_assert(inlineCandidateInfo);
// Store the link to inlineCandidateInfo into inlineInfo
inlineInfo.inlineCandidateInfo = inlineCandidateInfo;
Expand Down
69 changes: 64 additions & 5 deletions src/coreclr/jit/gentree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2179,6 +2179,64 @@ GenTree* Compiler::getArrayLengthFromAllocation(GenTree* tree DEBUGARG(BasicBloc
return arrayLength;
}

//-------------------------------------------------------------------------
// SetSingleInlineCadidateInfo: set a single inline candidate info in the current call.
//
// Arguments:
// candidateInfo - inline candidate info
//
void GenTreeCall::SetSingleInlineCadidateInfo(InlineCandidateInfo* candidateInfo)
{
if (candidateInfo != nullptr)
{
gtFlags |= GTF_CALL_INLINE_CANDIDATE;
gtInlineInfoCount = 1;
}
else
{
gtInlineInfoCount = 0;
gtFlags &= ~GTF_CALL_INLINE_CANDIDATE;
gtCallMoreFlags &= ~GTF_CALL_M_GUARDED_DEVIRT;
}
gtInlineCandidateInfo = candidateInfo;
}

//-------------------------------------------------------------------------
// GetGDVCandidateInfo: Get GDV candidate info in the current call by index.
//
// Return Value:
// GDV candidate info
//
InlineCandidateInfo* GenTreeCall::GetGDVCandidateInfo(uint8_t index)
{
assert(index < gtInlineInfoCount);
return &gtInlineCandidateInfo[index];
}

//-------------------------------------------------------------------------
// AddGDVCandidateInfo: Record a guarded devirtualization (GDV) candidate info
// for this call. For now, we only support one GDV candidate per call.
//
// Arguments:
// candidateInfo - GDV candidate info
//
void GenTreeCall::AddGDVCandidateInfo(InlineCandidateInfo* candidateInfo)
{
assert(candidateInfo != nullptr);
if (gtInlineInfoCount == 0)
{
gtInlineCandidateInfo = candidateInfo;
}
else
{
// Allocate a fixed list of InlineCandidateInfo structs
assert(!"multiple GDV candidates are not implemented yet");
}

gtCallMoreFlags |= GTF_CALL_M_GUARDED_DEVIRT;
gtInlineInfoCount++;
}

//-------------------------------------------------------------------------
// HasSideEffects:
// Returns true if this call has any side effects. All non-helpers are considered to have side-effects. Only helpers
Expand Down Expand Up @@ -7758,7 +7816,7 @@ GenTreeCall* Compiler::gtNewCallNode(gtCallTypes callType,
}
else
{
node->gtInlineCandidateInfo = nullptr;
node->ClearInlineInfo();
}
node->gtReturnType = type;

Expand Down Expand Up @@ -9409,6 +9467,7 @@ GenTreeCall* Compiler::gtCloneExprCallHelper(GenTreeCall* tree,
{
copy->gtCallMethHnd = tree->gtCallMethHnd;
copy->gtInlineCandidateInfo = tree->gtInlineCandidateInfo;
copy->gtInlineInfoCount = tree->gtInlineInfoCount;
}

copy->gtCallType = tree->gtCallType;
Expand Down Expand Up @@ -12419,10 +12478,10 @@ void Compiler::gtDispTree(GenTree* tree,
printf(" (FramesRoot last use)");
}

if (((call->gtFlags & GTF_CALL_INLINE_CANDIDATE) != 0) && (call->gtInlineCandidateInfo != nullptr) &&
(call->gtInlineCandidateInfo->exactContextHnd != nullptr))
if (((call->gtFlags & GTF_CALL_INLINE_CANDIDATE) != 0) && (call->GetInlineCandidateInfo() != nullptr) &&
(call->GetInlineCandidateInfo()->exactContextHnd != nullptr))
{
printf(" (exactContextHnd=0x%p)", dspPtr(call->gtInlineCandidateInfo->exactContextHnd));
printf(" (exactContextHnd=0x%p)", dspPtr(call->GetInlineCandidateInfo()->exactContextHnd));
}

gtDispCommonEndLine(tree);
Expand Down Expand Up @@ -17991,7 +18050,7 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b
// type class handle in the inline info (for GDV candidates,
// this data is valid only for a correct guess, so we cannot
// use it).
InlineCandidateInfo* inlInfo = call->gtInlineCandidateInfo;
InlineCandidateInfo* inlInfo = call->GetInlineCandidateInfo();
assert(inlInfo != nullptr);

// Grab it as our first cut at a return type.
Expand Down
40 changes: 26 additions & 14 deletions src/coreclr/jit/gentree.h
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,6 @@ enum TargetHandleType : BYTE
struct BasicBlock;
enum BasicBlockFlags : unsigned __int64;
struct InlineCandidateInfo;
struct GuardedDevirtualizationCandidateInfo;
struct HandleHistogramProfileCandidateInfo;
struct LateDevirtualizationInfo;

Expand Down Expand Up @@ -5375,11 +5374,6 @@ struct GenTreeCall final : public GenTree
gtCallMoreFlags &= ~GTF_CALL_M_GUARDED_DEVIRT;
}

void SetGuardedDevirtualizationCandidate()
{
gtCallMoreFlags |= GTF_CALL_M_GUARDED_DEVIRT;
}

void SetIsGuarded()
{
gtCallMoreFlags |= GTF_CALL_M_GUARDED;
Expand Down Expand Up @@ -5435,6 +5429,22 @@ struct GenTreeCall final : public GenTree
return (gtCallMoreFlags & GTF_CALL_M_RETBUFFARG_LCLOPT) != 0;
}

InlineCandidateInfo* GetInlineCandidateInfo()
{
return gtInlineCandidateInfo;
}

void SetSingleInlineCadidateInfo(InlineCandidateInfo* candidateInfo);

InlineCandidateInfo* GetGDVCandidateInfo(uint8_t index = 0);

void AddGDVCandidateInfo(InlineCandidateInfo* candidateInfo);

void ClearInlineInfo()
{
SetSingleInlineCadidateInfo(nullptr);
}

//-----------------------------------------------------------------------------------------
// GetIndirectionCellArgKind: Get the kind of indirection cell used by this call.
//
Expand Down Expand Up @@ -5505,10 +5515,13 @@ struct GenTreeCall final : public GenTree
return mayUseDispatcher && shouldUseDispatcher ? CFGCallKind::Dispatch : CFGCallKind::ValidateAndCall;
}

GenTreeCallFlags gtCallMoreFlags; // in addition to gtFlags
gtCallTypes gtCallType : 3; // value from the gtCallTypes enumeration
var_types gtReturnType : 5; // exact return type
CORINFO_CLASS_HANDLE gtRetClsHnd; // The return type handle of the call if it is a struct; always available
GenTreeCallFlags gtCallMoreFlags; // in addition to gtFlags
gtCallTypes gtCallType : 3; // value from the gtCallTypes enumeration
var_types gtReturnType : 5; // exact return type

uint8_t gtInlineInfoCount; // number of inline candidates for the given call

CORINFO_CLASS_HANDLE gtRetClsHnd; // The return type handle of the call if it is a struct; always available
union {
void* gtStubCallStubAddr; // GTF_CALL_VIRT_STUB - these are never inlined
CORINFO_CLASS_HANDLE gtInitClsHnd; // Used by static init helpers, represents a class they init
Expand All @@ -5518,10 +5531,9 @@ struct GenTreeCall final : public GenTree
// only used for CALLI unmanaged calls (CT_INDIRECT)
GenTree* gtCallCookie;
// gtInlineCandidateInfo is only used when inlining methods
InlineCandidateInfo* gtInlineCandidateInfo;
GuardedDevirtualizationCandidateInfo* gtGuardedDevirtualizationCandidateInfo;
HandleHistogramProfileCandidateInfo* gtHandleHistogramProfileCandidateInfo;
LateDevirtualizationInfo* gtLateDevirtualizationInfo;
InlineCandidateInfo* gtInlineCandidateInfo;
HandleHistogramProfileCandidateInfo* gtHandleHistogramProfileCandidateInfo;
LateDevirtualizationInfo* gtLateDevirtualizationInfo;
CORINFO_GENERIC_HANDLE compileTimeHelperArgumentHandle; // Used to track type handle argument of dynamic helpers
void* gtDirectCallAddress; // Used to pass direct call address between lower and codegen
};
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 @@ -1702,7 +1702,7 @@ bool Compiler::impSpillStackEntry(unsigned level,
{
JITDUMP("\n*** see V%02u = GT_RET_EXPR, noting temp\n", tnum);
GenTree* call = tree->AsRetExpr()->gtInlineCandidate;
InlineCandidateInfo* ici = call->AsCall()->gtInlineCandidateInfo;
InlineCandidateInfo* ici = call->AsCall()->GetInlineCandidateInfo();
ici->preexistingSpillTemp = tnum;
}
}
Expand Down
24 changes: 10 additions & 14 deletions src/coreclr/jit/importercalls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1351,7 +1351,7 @@ var_types Compiler::impImportCall(OPCODE opcode,
GenTreeRetExpr* retExpr = gtNewInlineCandidateReturnExpr(call->AsCall(), genActualType(callRetTyp));

// Link the retExpr to the call so if necessary we can manipulate it later.
origCall->gtInlineCandidateInfo->retExpr = retExpr;
origCall->GetInlineCandidateInfo()->retExpr = retExpr;

// Propagate retExpr as the placeholder for the call.
call = retExpr;
Expand Down Expand Up @@ -6059,7 +6059,6 @@ void Compiler::addGuardedDevirtualizationCandidate(GenTreeCall* call,
classHandle != NO_CLASS_HANDLE ? "class" : "method",
classHandle != NO_CLASS_HANDLE ? eeGetClassName(classHandle) : eeGetMethodFullName(methodHandle));
setMethodHasGuardedDevirtualization();
call->SetGuardedDevirtualizationCandidate();

// Spill off any GT_RET_EXPR subtrees so we can clone the call.
//
Expand All @@ -6069,7 +6068,7 @@ void Compiler::addGuardedDevirtualizationCandidate(GenTreeCall* call,
// Gather some information for later. Note we actually allocate InlineCandidateInfo
// here, as the devirtualized half of this call will likely become an inline candidate.
//
GuardedDevirtualizationCandidateInfo* pInfo = new (this, CMK_Inlining) InlineCandidateInfo;
InlineCandidateInfo* pInfo = new (this, CMK_Inlining) InlineCandidateInfo;

pInfo->guardedMethodHandle = methodHandle;
pInfo->guardedMethodUnboxedEntryHandle = nullptr;
Expand All @@ -6094,7 +6093,7 @@ void Compiler::addGuardedDevirtualizationCandidate(GenTreeCall* call,
}
}

call->gtGuardedDevirtualizationCandidateInfo = pInfo;
call->AddGDVCandidateInfo(pInfo);
}

//------------------------------------------------------------------------
Expand Down Expand Up @@ -6270,13 +6269,13 @@ void Compiler::impMarkInlineCandidateHelper(GenTreeCall* call,

if (call->IsGuardedDevirtualizationCandidate())
{
if (call->gtGuardedDevirtualizationCandidateInfo->guardedMethodUnboxedEntryHandle != nullptr)
if (call->GetGDVCandidateInfo()->guardedMethodUnboxedEntryHandle != nullptr)
{
fncHandle = call->gtGuardedDevirtualizationCandidateInfo->guardedMethodUnboxedEntryHandle;
fncHandle = call->GetGDVCandidateInfo()->guardedMethodUnboxedEntryHandle;
}
else
{
fncHandle = call->gtGuardedDevirtualizationCandidateInfo->guardedMethodHandle;
fncHandle = call->GetGDVCandidateInfo()->guardedMethodHandle;
}
methAttr = info.compCompHnd->getMethodAttribs(fncHandle);
}
Expand Down Expand Up @@ -6377,13 +6376,13 @@ void Compiler::impMarkInlineCandidateHelper(GenTreeCall* call,
}

// The old value should be null OR this call should be a guarded devirtualization candidate.
assert((call->gtInlineCandidateInfo == nullptr) || call->IsGuardedDevirtualizationCandidate());
assert((call->GetInlineCandidateInfo() == nullptr) || call->IsGuardedDevirtualizationCandidate());

// The new value should not be null.
assert(inlineCandidateInfo != nullptr);
inlineCandidateInfo->exactContextNeedsRuntimeLookup = exactContextNeedsRuntimeLookup;
inlineCandidateInfo->ilOffset = ilOffset;
call->gtInlineCandidateInfo = inlineCandidateInfo;
call->SetSingleInlineCadidateInfo(inlineCandidateInfo);

// 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 All @@ -6396,9 +6395,6 @@ void Compiler::impMarkInlineCandidateHelper(GenTreeCall* call,
inlineCandidateInfo->preexistingSpillTemp);
}

// Mark the call node as inline candidate.
call->gtFlags |= GTF_CALL_INLINE_CANDIDATE;

// Let the strategy know there's another candidate.
impInlineRoot()->m_inlineStrategy->NoteCandidate();

Expand Down Expand Up @@ -6895,7 +6891,7 @@ void Compiler::impDevirtualizeCall(GenTreeCall* call,
// Clear the inline candidate info (may be non-null since
// it's a union field used for other things by virtual
// stubs)
call->gtInlineCandidateInfo = nullptr;
call->ClearInlineInfo();
call->gtCallMoreFlags &= ~GTF_CALL_M_HAS_LATE_DEVIRT_INFO;

#if defined(DEBUG)
Expand Down Expand Up @@ -7675,7 +7671,7 @@ void Compiler::impCheckCanInline(GenTreeCall* call,

if (pParam->call->IsGuardedDevirtualizationCandidate())
{
pInfo = pParam->call->gtInlineCandidateInfo;
pInfo = pParam->call->GetInlineCandidateInfo();
}
else
{
Expand Down
18 changes: 9 additions & 9 deletions src/coreclr/jit/indirectcalltransformer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -465,7 +465,7 @@ class IndirectCallTransformer
return;
}

likelihood = origCall->gtGuardedDevirtualizationCandidateInfo->likelihood;
likelihood = origCall->GetGDVCandidateInfo()->likelihood;
assert((likelihood >= 0) && (likelihood <= 100));
JITDUMP("Likelihood of correct guess is %u\n", likelihood);

Expand Down Expand Up @@ -574,7 +574,7 @@ class IndirectCallTransformer
//
lastStmt = checkBlock->lastStmt();

GuardedDevirtualizationCandidateInfo* guardedInfo = origCall->gtGuardedDevirtualizationCandidateInfo;
InlineCandidateInfo* guardedInfo = origCall->GetGDVCandidateInfo();

// Create comparison. On success we will jump to do the indirect call.
GenTree* compare;
Expand Down Expand Up @@ -655,7 +655,7 @@ class IndirectCallTransformer
//
// Note implicit by-ref returns should have already been converted
// so any struct copy we induce here should be cheap.
InlineCandidateInfo* const inlineInfo = origCall->gtInlineCandidateInfo;
InlineCandidateInfo* const inlineInfo = origCall->GetInlineCandidateInfo();

if (!origCall->TypeIs(TYP_VOID))
{
Expand Down Expand Up @@ -736,7 +736,7 @@ class IndirectCallTransformer
{
thenBlock = CreateAndInsertBasicBlock(BBJ_ALWAYS, checkBlock);
thenBlock->bbFlags |= currBlock->bbFlags & BBF_SPLIT_GAINED;
InlineCandidateInfo* inlineInfo = origCall->gtInlineCandidateInfo;
InlineCandidateInfo* inlineInfo = origCall->GetInlineCandidateInfo();
CORINFO_CLASS_HANDLE clsHnd = inlineInfo->guardedClassHandle;

//
Expand Down Expand Up @@ -840,7 +840,7 @@ class IndirectCallTransformer
"inlineable\n");

call->gtFlags &= ~GTF_CALL_INLINE_CANDIDATE;
call->gtInlineCandidateInfo = nullptr;
call->ClearInlineInfo();

if (returnTemp != BAD_VAR_NUM)
{
Expand All @@ -864,7 +864,7 @@ class IndirectCallTransformer
inlineInfo->clsHandle = compiler->info.compCompHnd->getMethodClass(methodHnd);
inlineInfo->exactContextHnd = context;
inlineInfo->preexistingSpillTemp = returnTemp;
call->gtInlineCandidateInfo = inlineInfo;
call->SetSingleInlineCadidateInfo(inlineInfo);

// If there was a ret expr for this call, we need to create a new one
// and append it just after the call.
Expand Down Expand Up @@ -1092,11 +1092,11 @@ class IndirectCallTransformer
GenTreeCall* const call = root->AsCall();

if (call->IsGuardedDevirtualizationCandidate() &&
(call->gtGuardedDevirtualizationCandidateInfo->likelihood >= gdvChainLikelihood))
(call->GetGDVCandidateInfo()->likelihood >= gdvChainLikelihood))
{
JITDUMP("GDV call at [%06u] has likelihood %u >= %u; chaining (%u stmts, %u nodes to dup).\n",
compiler->dspTreeID(call), call->gtGuardedDevirtualizationCandidateInfo->likelihood,
gdvChainLikelihood, chainStatementDup, chainNodeDup);
compiler->dspTreeID(call), call->GetGDVCandidateInfo()->likelihood, gdvChainLikelihood,
chainStatementDup, chainNodeDup);

call->gtCallMoreFlags |= GTF_CALL_M_GUARDED_DEVIRT_CHAIN;
break;
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/inline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1281,7 +1281,7 @@ InlineContext* InlineStrategy::NewContext(InlineContext* parentContext, Statemen

if (call->IsInlineCandidate())
{
InlineCandidateInfo* info = call->gtInlineCandidateInfo;
InlineCandidateInfo* info = call->GetInlineCandidateInfo();
context->m_Code = info->methInfo.ILCode;
context->m_ILSize = info->methInfo.ILCodeSize;
context->m_ActualCallOffset = info->ilOffset;
Expand Down
Loading