Skip to content

Commit d7aa91c

Browse files
authored
Clean up GenTreeCall's inline info (#86540)
1 parent e7e9dbd commit d7aa91c

File tree

9 files changed

+126
-66
lines changed

9 files changed

+126
-66
lines changed

src/coreclr/jit/fginline.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -752,7 +752,7 @@ void Compiler::fgMorphCallInline(GenTreeCall* call, InlineResult* inlineResult)
752752
{
753753
bool inliningFailed = false;
754754

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

757757
// Is this call an inline candidate?
758758
if (call->IsInlineCandidate())
@@ -778,7 +778,7 @@ void Compiler::fgMorphCallInline(GenTreeCall* call, InlineResult* inlineResult)
778778
#ifdef DEBUG
779779
// In debug we always put all inline attempts into the inline tree.
780780
InlineContext* ctx =
781-
m_inlineStrategy->NewContext(call->gtInlineCandidateInfo->inlinersContext, fgMorphStmt, call);
781+
m_inlineStrategy->NewContext(call->GetInlineCandidateInfo()->inlinersContext, fgMorphStmt, call);
782782
ctx->SetFailed(inlineResult);
783783
#endif
784784
}
@@ -1045,7 +1045,7 @@ void Compiler::fgInvokeInlineeCompiler(GenTreeCall* call, InlineResult* inlineRe
10451045
inlineInfo.hasSIMDTypeArgLocalOrReturn = false;
10461046
#endif // FEATURE_SIMD
10471047

1048-
InlineCandidateInfo* inlineCandidateInfo = call->gtInlineCandidateInfo;
1048+
InlineCandidateInfo* inlineCandidateInfo = call->GetInlineCandidateInfo();
10491049
noway_assert(inlineCandidateInfo);
10501050
// Store the link to inlineCandidateInfo into inlineInfo
10511051
inlineInfo.inlineCandidateInfo = inlineCandidateInfo;

src/coreclr/jit/gentree.cpp

Lines changed: 64 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2179,6 +2179,64 @@ GenTree* Compiler::getArrayLengthFromAllocation(GenTree* tree DEBUGARG(BasicBloc
21792179
return arrayLength;
21802180
}
21812181

2182+
//-------------------------------------------------------------------------
2183+
// SetSingleInlineCadidateInfo: set a single inline candidate info in the current call.
2184+
//
2185+
// Arguments:
2186+
// candidateInfo - inline candidate info
2187+
//
2188+
void GenTreeCall::SetSingleInlineCadidateInfo(InlineCandidateInfo* candidateInfo)
2189+
{
2190+
if (candidateInfo != nullptr)
2191+
{
2192+
gtFlags |= GTF_CALL_INLINE_CANDIDATE;
2193+
gtInlineInfoCount = 1;
2194+
}
2195+
else
2196+
{
2197+
gtInlineInfoCount = 0;
2198+
gtFlags &= ~GTF_CALL_INLINE_CANDIDATE;
2199+
gtCallMoreFlags &= ~GTF_CALL_M_GUARDED_DEVIRT;
2200+
}
2201+
gtInlineCandidateInfo = candidateInfo;
2202+
}
2203+
2204+
//-------------------------------------------------------------------------
2205+
// GetGDVCandidateInfo: Get GDV candidate info in the current call by index.
2206+
//
2207+
// Return Value:
2208+
// GDV candidate info
2209+
//
2210+
InlineCandidateInfo* GenTreeCall::GetGDVCandidateInfo(uint8_t index)
2211+
{
2212+
assert(index < gtInlineInfoCount);
2213+
return &gtInlineCandidateInfo[index];
2214+
}
2215+
2216+
//-------------------------------------------------------------------------
2217+
// AddGDVCandidateInfo: Record a guarded devirtualization (GDV) candidate info
2218+
// for this call. For now, we only support one GDV candidate per call.
2219+
//
2220+
// Arguments:
2221+
// candidateInfo - GDV candidate info
2222+
//
2223+
void GenTreeCall::AddGDVCandidateInfo(InlineCandidateInfo* candidateInfo)
2224+
{
2225+
assert(candidateInfo != nullptr);
2226+
if (gtInlineInfoCount == 0)
2227+
{
2228+
gtInlineCandidateInfo = candidateInfo;
2229+
}
2230+
else
2231+
{
2232+
// Allocate a fixed list of InlineCandidateInfo structs
2233+
assert(!"multiple GDV candidates are not implemented yet");
2234+
}
2235+
2236+
gtCallMoreFlags |= GTF_CALL_M_GUARDED_DEVIRT;
2237+
gtInlineInfoCount++;
2238+
}
2239+
21822240
//-------------------------------------------------------------------------
21832241
// HasSideEffects:
21842242
// Returns true if this call has any side effects. All non-helpers are considered to have side-effects. Only helpers
@@ -7758,7 +7816,7 @@ GenTreeCall* Compiler::gtNewCallNode(gtCallTypes callType,
77587816
}
77597817
else
77607818
{
7761-
node->gtInlineCandidateInfo = nullptr;
7819+
node->ClearInlineInfo();
77627820
}
77637821
node->gtReturnType = type;
77647822

@@ -9409,6 +9467,7 @@ GenTreeCall* Compiler::gtCloneExprCallHelper(GenTreeCall* tree,
94099467
{
94109468
copy->gtCallMethHnd = tree->gtCallMethHnd;
94119469
copy->gtInlineCandidateInfo = tree->gtInlineCandidateInfo;
9470+
copy->gtInlineInfoCount = tree->gtInlineInfoCount;
94129471
}
94139472

94149473
copy->gtCallType = tree->gtCallType;
@@ -12419,10 +12478,10 @@ void Compiler::gtDispTree(GenTree* tree,
1241912478
printf(" (FramesRoot last use)");
1242012479
}
1242112480

12422-
if (((call->gtFlags & GTF_CALL_INLINE_CANDIDATE) != 0) && (call->gtInlineCandidateInfo != nullptr) &&
12423-
(call->gtInlineCandidateInfo->exactContextHnd != nullptr))
12481+
if (((call->gtFlags & GTF_CALL_INLINE_CANDIDATE) != 0) && (call->GetInlineCandidateInfo() != nullptr) &&
12482+
(call->GetInlineCandidateInfo()->exactContextHnd != nullptr))
1242412483
{
12425-
printf(" (exactContextHnd=0x%p)", dspPtr(call->gtInlineCandidateInfo->exactContextHnd));
12484+
printf(" (exactContextHnd=0x%p)", dspPtr(call->GetInlineCandidateInfo()->exactContextHnd));
1242612485
}
1242712486

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

1799718056
// Grab it as our first cut at a return type.

src/coreclr/jit/gentree.h

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,6 @@ enum TargetHandleType : BYTE
172172
struct BasicBlock;
173173
enum BasicBlockFlags : unsigned __int64;
174174
struct InlineCandidateInfo;
175-
struct GuardedDevirtualizationCandidateInfo;
176175
struct HandleHistogramProfileCandidateInfo;
177176
struct LateDevirtualizationInfo;
178177

@@ -5375,11 +5374,6 @@ struct GenTreeCall final : public GenTree
53755374
gtCallMoreFlags &= ~GTF_CALL_M_GUARDED_DEVIRT;
53765375
}
53775376

5378-
void SetGuardedDevirtualizationCandidate()
5379-
{
5380-
gtCallMoreFlags |= GTF_CALL_M_GUARDED_DEVIRT;
5381-
}
5382-
53835377
void SetIsGuarded()
53845378
{
53855379
gtCallMoreFlags |= GTF_CALL_M_GUARDED;
@@ -5435,6 +5429,22 @@ struct GenTreeCall final : public GenTree
54355429
return (gtCallMoreFlags & GTF_CALL_M_RETBUFFARG_LCLOPT) != 0;
54365430
}
54375431

5432+
InlineCandidateInfo* GetInlineCandidateInfo()
5433+
{
5434+
return gtInlineCandidateInfo;
5435+
}
5436+
5437+
void SetSingleInlineCadidateInfo(InlineCandidateInfo* candidateInfo);
5438+
5439+
InlineCandidateInfo* GetGDVCandidateInfo(uint8_t index = 0);
5440+
5441+
void AddGDVCandidateInfo(InlineCandidateInfo* candidateInfo);
5442+
5443+
void ClearInlineInfo()
5444+
{
5445+
SetSingleInlineCadidateInfo(nullptr);
5446+
}
5447+
54385448
//-----------------------------------------------------------------------------------------
54395449
// GetIndirectionCellArgKind: Get the kind of indirection cell used by this call.
54405450
//
@@ -5505,10 +5515,13 @@ struct GenTreeCall final : public GenTree
55055515
return mayUseDispatcher && shouldUseDispatcher ? CFGCallKind::Dispatch : CFGCallKind::ValidateAndCall;
55065516
}
55075517

5508-
GenTreeCallFlags gtCallMoreFlags; // in addition to gtFlags
5509-
gtCallTypes gtCallType : 3; // value from the gtCallTypes enumeration
5510-
var_types gtReturnType : 5; // exact return type
5511-
CORINFO_CLASS_HANDLE gtRetClsHnd; // The return type handle of the call if it is a struct; always available
5518+
GenTreeCallFlags gtCallMoreFlags; // in addition to gtFlags
5519+
gtCallTypes gtCallType : 3; // value from the gtCallTypes enumeration
5520+
var_types gtReturnType : 5; // exact return type
5521+
5522+
uint8_t gtInlineInfoCount; // number of inline candidates for the given call
5523+
5524+
CORINFO_CLASS_HANDLE gtRetClsHnd; // The return type handle of the call if it is a struct; always available
55125525
union {
55135526
void* gtStubCallStubAddr; // GTF_CALL_VIRT_STUB - these are never inlined
55145527
CORINFO_CLASS_HANDLE gtInitClsHnd; // Used by static init helpers, represents a class they init
@@ -5518,10 +5531,9 @@ struct GenTreeCall final : public GenTree
55185531
// only used for CALLI unmanaged calls (CT_INDIRECT)
55195532
GenTree* gtCallCookie;
55205533
// gtInlineCandidateInfo is only used when inlining methods
5521-
InlineCandidateInfo* gtInlineCandidateInfo;
5522-
GuardedDevirtualizationCandidateInfo* gtGuardedDevirtualizationCandidateInfo;
5523-
HandleHistogramProfileCandidateInfo* gtHandleHistogramProfileCandidateInfo;
5524-
LateDevirtualizationInfo* gtLateDevirtualizationInfo;
5534+
InlineCandidateInfo* gtInlineCandidateInfo;
5535+
HandleHistogramProfileCandidateInfo* gtHandleHistogramProfileCandidateInfo;
5536+
LateDevirtualizationInfo* gtLateDevirtualizationInfo;
55255537
CORINFO_GENERIC_HANDLE compileTimeHelperArgumentHandle; // Used to track type handle argument of dynamic helpers
55265538
void* gtDirectCallAddress; // Used to pass direct call address between lower and codegen
55275539
};

src/coreclr/jit/importer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1702,7 +1702,7 @@ bool Compiler::impSpillStackEntry(unsigned level,
17021702
{
17031703
JITDUMP("\n*** see V%02u = GT_RET_EXPR, noting temp\n", tnum);
17041704
GenTree* call = tree->AsRetExpr()->gtInlineCandidate;
1705-
InlineCandidateInfo* ici = call->AsCall()->gtInlineCandidateInfo;
1705+
InlineCandidateInfo* ici = call->AsCall()->GetInlineCandidateInfo();
17061706
ici->preexistingSpillTemp = tnum;
17071707
}
17081708
}

src/coreclr/jit/importercalls.cpp

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1351,7 +1351,7 @@ var_types Compiler::impImportCall(OPCODE opcode,
13511351
GenTreeRetExpr* retExpr = gtNewInlineCandidateReturnExpr(call->AsCall(), genActualType(callRetTyp));
13521352

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

13561356
// Propagate retExpr as the placeholder for the call.
13571357
call = retExpr;
@@ -6059,7 +6059,6 @@ void Compiler::addGuardedDevirtualizationCandidate(GenTreeCall* call,
60596059
classHandle != NO_CLASS_HANDLE ? "class" : "method",
60606060
classHandle != NO_CLASS_HANDLE ? eeGetClassName(classHandle) : eeGetMethodFullName(methodHandle));
60616061
setMethodHasGuardedDevirtualization();
6062-
call->SetGuardedDevirtualizationCandidate();
60636062

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

60746073
pInfo->guardedMethodHandle = methodHandle;
60756074
pInfo->guardedMethodUnboxedEntryHandle = nullptr;
@@ -6094,7 +6093,7 @@ void Compiler::addGuardedDevirtualizationCandidate(GenTreeCall* call,
60946093
}
60956094
}
60966095

6097-
call->gtGuardedDevirtualizationCandidateInfo = pInfo;
6096+
call->AddGDVCandidateInfo(pInfo);
60986097
}
60996098

61006099
//------------------------------------------------------------------------
@@ -6270,13 +6269,13 @@ void Compiler::impMarkInlineCandidateHelper(GenTreeCall* call,
62706269

62716270
if (call->IsGuardedDevirtualizationCandidate())
62726271
{
6273-
if (call->gtGuardedDevirtualizationCandidateInfo->guardedMethodUnboxedEntryHandle != nullptr)
6272+
if (call->GetGDVCandidateInfo()->guardedMethodUnboxedEntryHandle != nullptr)
62746273
{
6275-
fncHandle = call->gtGuardedDevirtualizationCandidateInfo->guardedMethodUnboxedEntryHandle;
6274+
fncHandle = call->GetGDVCandidateInfo()->guardedMethodUnboxedEntryHandle;
62766275
}
62776276
else
62786277
{
6279-
fncHandle = call->gtGuardedDevirtualizationCandidateInfo->guardedMethodHandle;
6278+
fncHandle = call->GetGDVCandidateInfo()->guardedMethodHandle;
62806279
}
62816280
methAttr = info.compCompHnd->getMethodAttribs(fncHandle);
62826281
}
@@ -6377,13 +6376,13 @@ void Compiler::impMarkInlineCandidateHelper(GenTreeCall* call,
63776376
}
63786377

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

63826381
// The new value should not be null.
63836382
assert(inlineCandidateInfo != nullptr);
63846383
inlineCandidateInfo->exactContextNeedsRuntimeLookup = exactContextNeedsRuntimeLookup;
63856384
inlineCandidateInfo->ilOffset = ilOffset;
6386-
call->gtInlineCandidateInfo = inlineCandidateInfo;
6385+
call->SetSingleInlineCadidateInfo(inlineCandidateInfo);
63876386

63886387
// If we're in an inlinee compiler, and have a return spill temp, and this inline candidate
63896388
// is also a tail call candidate, it can use the same return spill temp.
@@ -6396,9 +6395,6 @@ void Compiler::impMarkInlineCandidateHelper(GenTreeCall* call,
63966395
inlineCandidateInfo->preexistingSpillTemp);
63976396
}
63986397

6399-
// Mark the call node as inline candidate.
6400-
call->gtFlags |= GTF_CALL_INLINE_CANDIDATE;
6401-
64026398
// Let the strategy know there's another candidate.
64036399
impInlineRoot()->m_inlineStrategy->NoteCandidate();
64046400

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

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

76767672
if (pParam->call->IsGuardedDevirtualizationCandidate())
76777673
{
7678-
pInfo = pParam->call->gtInlineCandidateInfo;
7674+
pInfo = pParam->call->GetInlineCandidateInfo();
76797675
}
76807676
else
76817677
{

src/coreclr/jit/indirectcalltransformer.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -465,7 +465,7 @@ class IndirectCallTransformer
465465
return;
466466
}
467467

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

@@ -574,7 +574,7 @@ class IndirectCallTransformer
574574
//
575575
lastStmt = checkBlock->lastStmt();
576576

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

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

660660
if (!origCall->TypeIs(TYP_VOID))
661661
{
@@ -736,7 +736,7 @@ class IndirectCallTransformer
736736
{
737737
thenBlock = CreateAndInsertBasicBlock(BBJ_ALWAYS, checkBlock);
738738
thenBlock->bbFlags |= currBlock->bbFlags & BBF_SPLIT_GAINED;
739-
InlineCandidateInfo* inlineInfo = origCall->gtInlineCandidateInfo;
739+
InlineCandidateInfo* inlineInfo = origCall->GetInlineCandidateInfo();
740740
CORINFO_CLASS_HANDLE clsHnd = inlineInfo->guardedClassHandle;
741741

742742
//
@@ -840,7 +840,7 @@ class IndirectCallTransformer
840840
"inlineable\n");
841841

842842
call->gtFlags &= ~GTF_CALL_INLINE_CANDIDATE;
843-
call->gtInlineCandidateInfo = nullptr;
843+
call->ClearInlineInfo();
844844

845845
if (returnTemp != BAD_VAR_NUM)
846846
{
@@ -864,7 +864,7 @@ class IndirectCallTransformer
864864
inlineInfo->clsHandle = compiler->info.compCompHnd->getMethodClass(methodHnd);
865865
inlineInfo->exactContextHnd = context;
866866
inlineInfo->preexistingSpillTemp = returnTemp;
867-
call->gtInlineCandidateInfo = inlineInfo;
867+
call->SetSingleInlineCadidateInfo(inlineInfo);
868868

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

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

11011101
call->gtCallMoreFlags |= GTF_CALL_M_GUARDED_DEVIRT_CHAIN;
11021102
break;

src/coreclr/jit/inline.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1281,7 +1281,7 @@ InlineContext* InlineStrategy::NewContext(InlineContext* parentContext, Statemen
12811281

12821282
if (call->IsInlineCandidate())
12831283
{
1284-
InlineCandidateInfo* info = call->gtInlineCandidateInfo;
1284+
InlineCandidateInfo* info = call->GetInlineCandidateInfo();
12851285
context->m_Code = info->methInfo.ILCode;
12861286
context->m_ILSize = info->methInfo.ILCodeSize;
12871287
context->m_ActualCallOffset = info->ilOffset;

0 commit comments

Comments
 (0)