Skip to content

Commit 2c55431

Browse files
Make more extensive use of lvaGetDesc() (#61494)
Including the version with a `GenTreeLclVarCommon*` overload. I mostly replaced `&lvaTable[varNum]` and `lvaTable + varNum` expressions, leaving `lvaTable[varNum].xxx`. Made many resulting `varDsc*` const. Removed unused `lvaRefCount`. Simplifies code, and centralizes assert checking. Added new `lvaGetLclNum(LclVarDsc*)` function to map back to a varNum. This deletes many `noway_assert` in favor of the lvaGetDesc `assert`; I'm not worried about removing asserts from the Release build.
1 parent ef5ddf5 commit 2c55431

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+364
-491
lines changed

src/coreclr/jit/assertionprop.cpp

Lines changed: 13 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -660,12 +660,11 @@ void Compiler::optAddCopies()
660660
Statement* stmt;
661661
unsigned copyLclNum = lvaGrabTemp(false DEBUGARG("optAddCopies"));
662662

663-
// Because lvaGrabTemp may have reallocated the lvaTable, ensure varDsc
664-
// is still in sync with lvaTable[lclNum];
665-
varDsc = &lvaTable[lclNum];
663+
// Because lvaGrabTemp may have reallocated the lvaTable, ensure varDsc is still in sync.
664+
varDsc = lvaGetDesc(lclNum);
666665

667666
// Set lvType on the new Temp Lcl Var
668-
lvaTable[copyLclNum].lvType = typ;
667+
lvaGetDesc(copyLclNum)->lvType = typ;
669668

670669
#ifdef DEBUG
671670
if (verbose)
@@ -1103,9 +1102,7 @@ void Compiler::optPrintAssertion(AssertionDsc* curAssertion, AssertionIndex asse
11031102
else
11041103
{
11051104
unsigned lclNum = curAssertion->op1.lcl.lclNum;
1106-
assert(lclNum < lvaCount);
1107-
LclVarDsc* varDsc = lvaTable + lclNum;
1108-
op1Type = varDsc->lvType;
1105+
op1Type = lvaGetDesc(lclNum)->lvType;
11091106
}
11101107

11111108
if (op1Type == TYP_REF)
@@ -1315,9 +1312,8 @@ AssertionIndex Compiler::optCreateAssertion(GenTree* op1,
13151312
goto DONE_ASSERTION; // Don't make an assertion
13161313
}
13171314

1318-
unsigned lclNum = op1->AsLclVarCommon()->GetLclNum();
1319-
noway_assert(lclNum < lvaCount);
1320-
LclVarDsc* lclVar = &lvaTable[lclNum];
1315+
unsigned lclNum = op1->AsLclVarCommon()->GetLclNum();
1316+
LclVarDsc* lclVar = lvaGetDesc(lclNum);
13211317

13221318
ValueNum vn;
13231319

@@ -1394,9 +1390,8 @@ AssertionIndex Compiler::optCreateAssertion(GenTree* op1,
13941390
//
13951391
else if (op1->gtOper == GT_LCL_VAR)
13961392
{
1397-
unsigned lclNum = op1->AsLclVarCommon()->GetLclNum();
1398-
noway_assert(lclNum < lvaCount);
1399-
LclVarDsc* lclVar = &lvaTable[lclNum];
1393+
unsigned lclNum = op1->AsLclVarCommon()->GetLclNum();
1394+
LclVarDsc* lclVar = lvaGetDesc(lclNum);
14001395

14011396
// If the local variable has its address exposed then bail
14021397
if (lclVar->IsAddressExposed())
@@ -1559,9 +1554,8 @@ AssertionIndex Compiler::optCreateAssertion(GenTree* op1,
15591554
goto DONE_ASSERTION; // Don't make an assertion
15601555
}
15611556

1562-
unsigned lclNum2 = op2->AsLclVarCommon()->GetLclNum();
1563-
noway_assert(lclNum2 < lvaCount);
1564-
LclVarDsc* lclVar2 = &lvaTable[lclNum2];
1557+
unsigned lclNum2 = op2->AsLclVarCommon()->GetLclNum();
1558+
LclVarDsc* lclVar2 = lvaGetDesc(lclNum2);
15651559

15661560
// If the two locals are the same then bail
15671561
if (lclNum == lclNum2)
@@ -1632,7 +1626,6 @@ AssertionIndex Compiler::optCreateAssertion(GenTree* op1,
16321626
if (op1->gtOper == GT_LCL_VAR)
16331627
{
16341628
unsigned lclNum = op1->AsLclVarCommon()->GetLclNum();
1635-
noway_assert(lclNum < lvaCount);
16361629

16371630
// If the local variable is not in SSA then bail
16381631
if (!lvaInSsa(lclNum))
@@ -1656,7 +1649,7 @@ AssertionIndex Compiler::optCreateAssertion(GenTree* op1,
16561649
assert((assertion.op1.lcl.ssaNum == SsaConfig::RESERVED_SSA_NUM) ||
16571650
(assertion.op1.vn ==
16581651
vnStore->VNConservativeNormalValue(
1659-
lvaTable[lclNum].GetPerSsaData(assertion.op1.lcl.ssaNum)->m_vnPair)));
1652+
lvaGetDesc(lclNum)->GetPerSsaData(assertion.op1.lcl.ssaNum)->m_vnPair)));
16601653

16611654
ssize_t cnsValue = 0;
16621655
GenTreeFlags iconFlags = GTF_EMPTY;
@@ -1971,9 +1964,8 @@ void Compiler::optDebugCheckAssertion(AssertionDsc* assertion)
19711964
case O1K_LCLVAR:
19721965
case O1K_EXACT_TYPE:
19731966
case O1K_SUBTYPE:
1974-
assert(assertion->op1.lcl.lclNum < lvaCount);
19751967
assert(optLocalAssertionProp ||
1976-
lvaTable[assertion->op1.lcl.lclNum].lvPerSsaData.IsValidSsaNum(assertion->op1.lcl.ssaNum));
1968+
lvaGetDesc(assertion->op1.lcl.lclNum)->lvPerSsaData.IsValidSsaNum(assertion->op1.lcl.ssaNum));
19771969
break;
19781970
case O1K_ARR_BND:
19791971
// It would be good to check that bnd.vnIdx and bnd.vnLen are valid value numbers.
@@ -2006,7 +1998,7 @@ void Compiler::optDebugCheckAssertion(AssertionDsc* assertion)
20061998
assert(assertion->op2.u1.iconFlags != GTF_EMPTY);
20071999
break;
20082000
case O1K_LCLVAR:
2009-
assert((lvaTable[assertion->op1.lcl.lclNum].lvType != TYP_REF) ||
2001+
assert((lvaGetDesc(assertion->op1.lcl.lclNum)->lvType != TYP_REF) ||
20102002
(assertion->op2.u1.iconVal == 0) || doesMethodHaveFrozenString());
20112003
break;
20122004
case O1K_VALUE_NUMBER:

src/coreclr/jit/codegen.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1302,8 +1302,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
13021302
{
13031303
return false;
13041304
}
1305-
const LclVarDsc* varDsc = &compiler->lvaTable[tree->AsLclVarCommon()->GetLclNum()];
1306-
return (varDsc->lvIsRegCandidate());
1305+
return compiler->lvaGetDesc(tree->AsLclVarCommon())->lvIsRegCandidate();
13071306
}
13081307

13091308
#ifdef FEATURE_PUT_STRUCT_ARG_STK

src/coreclr/jit/codegenarm.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -966,7 +966,7 @@ void CodeGen::genCodeForLclVar(GenTreeLclVar* tree)
966966
// lcl_vars are not defs
967967
assert((tree->gtFlags & GTF_VAR_DEF) == 0);
968968

969-
bool isRegCandidate = compiler->lvaTable[tree->GetLclNum()].lvIsRegCandidate();
969+
bool isRegCandidate = compiler->lvaGetDesc(tree)->lvIsRegCandidate();
970970

971971
// If this is a register candidate that has been spilled, genConsumeReg() will
972972
// reload it at the point of use. Otherwise, if it's not in a register, we load it here.
@@ -1001,9 +1001,8 @@ void CodeGen::genCodeForStoreLclFld(GenTreeLclFld* tree)
10011001
// We must have a stack store with GT_STORE_LCL_FLD
10021002
noway_assert(targetReg == REG_NA);
10031003

1004-
unsigned varNum = tree->GetLclNum();
1005-
assert(varNum < compiler->lvaCount);
1006-
LclVarDsc* varDsc = &(compiler->lvaTable[varNum]);
1004+
unsigned varNum = tree->GetLclNum();
1005+
LclVarDsc* varDsc = compiler->lvaGetDesc(varNum);
10071006

10081007
// Ensure that lclVar nodes are typed correctly.
10091008
assert(!varDsc->lvNormalizeOnStore() || targetType == genActualType(varDsc->TypeGet()));
@@ -1083,8 +1082,7 @@ void CodeGen::genCodeForStoreLclVar(GenTreeLclVar* tree)
10831082
}
10841083
if (regCount == 1)
10851084
{
1086-
unsigned varNum = tree->GetLclNum();
1087-
assert(varNum < compiler->lvaCount);
1085+
unsigned varNum = tree->GetLclNum();
10881086
LclVarDsc* varDsc = compiler->lvaGetDesc(varNum);
10891087
var_types targetType = varDsc->GetRegisterType(tree);
10901088

src/coreclr/jit/codegenarm64.cpp

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1871,8 +1871,7 @@ void CodeGen::genCodeForBinary(GenTreeOp* treeNode)
18711871
void CodeGen::genCodeForLclVar(GenTreeLclVar* tree)
18721872
{
18731873

1874-
unsigned varNum = tree->GetLclNum();
1875-
assert(varNum < compiler->lvaCount);
1874+
unsigned varNum = tree->GetLclNum();
18761875
LclVarDsc* varDsc = compiler->lvaGetDesc(varNum);
18771876
var_types targetType = varDsc->GetRegisterType(tree);
18781877

@@ -1926,9 +1925,8 @@ void CodeGen::genCodeForStoreLclFld(GenTreeLclFld* tree)
19261925
// We must have a stack store with GT_STORE_LCL_FLD
19271926
noway_assert(targetReg == REG_NA);
19281927

1929-
unsigned varNum = tree->GetLclNum();
1930-
assert(varNum < compiler->lvaCount);
1931-
LclVarDsc* varDsc = &(compiler->lvaTable[varNum]);
1928+
unsigned varNum = tree->GetLclNum();
1929+
LclVarDsc* varDsc = compiler->lvaGetDesc(varNum);
19321930

19331931
// Ensure that lclVar nodes are typed correctly.
19341932
assert(!varDsc->lvNormalizeOnStore() || targetType == genActualType(varDsc->TypeGet()));
@@ -2120,15 +2118,14 @@ void CodeGen::genSimpleReturn(GenTree* treeNode)
21202118
if (op1->OperGet() == GT_LCL_VAR)
21212119
{
21222120
GenTreeLclVarCommon* lcl = op1->AsLclVarCommon();
2123-
bool isRegCandidate = compiler->lvaTable[lcl->GetLclNum()].lvIsRegCandidate();
2121+
const LclVarDsc* varDsc = compiler->lvaGetDesc(lcl);
2122+
bool isRegCandidate = varDsc->lvIsRegCandidate();
21242123
if (isRegCandidate && ((op1->gtFlags & GTF_SPILLED) == 0))
21252124
{
21262125
// We may need to generate a zero-extending mov instruction to load the value from this GT_LCL_VAR
21272126

2128-
unsigned lclNum = lcl->GetLclNum();
2129-
LclVarDsc* varDsc = &(compiler->lvaTable[lclNum]);
2130-
var_types op1Type = genActualType(op1->TypeGet());
2131-
var_types lclType = genActualType(varDsc->TypeGet());
2127+
var_types op1Type = genActualType(op1->TypeGet());
2128+
var_types lclType = genActualType(varDsc->TypeGet());
21322129

21332130
if (genTypeSize(op1Type) < genTypeSize(lclType))
21342131
{
@@ -3310,10 +3307,10 @@ void CodeGen::genCodeForSwap(GenTreeOp* tree)
33103307
assert(genIsRegCandidateLocal(tree->gtOp1) && genIsRegCandidateLocal(tree->gtOp2));
33113308

33123309
GenTreeLclVarCommon* lcl1 = tree->gtOp1->AsLclVarCommon();
3313-
LclVarDsc* varDsc1 = &(compiler->lvaTable[lcl1->GetLclNum()]);
3310+
LclVarDsc* varDsc1 = compiler->lvaGetDesc(lcl1);
33143311
var_types type1 = varDsc1->TypeGet();
33153312
GenTreeLclVarCommon* lcl2 = tree->gtOp2->AsLclVarCommon();
3316-
LclVarDsc* varDsc2 = &(compiler->lvaTable[lcl2->GetLclNum()]);
3313+
LclVarDsc* varDsc2 = compiler->lvaGetDesc(lcl2);
33173314
var_types type2 = varDsc2->TypeGet();
33183315

33193316
// We must have both int or both fp regs

src/coreclr/jit/codegenarmarch.cpp

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -712,7 +712,7 @@ void CodeGen::genPutArgStk(GenTreePutArgStk* treeNode)
712712
// Since it is a fast tail call, the existence of first incoming arg is guaranteed
713713
// because fast tail call requires that in-coming arg area of caller is >= out-going
714714
// arg area required for tail call.
715-
LclVarDsc* varDsc = &(compiler->lvaTable[varNumOut]);
715+
LclVarDsc* varDsc = compiler->lvaGetDesc(varNumOut);
716716
assert(varDsc != nullptr);
717717
#endif // FEATURE_FASTTAILCALL
718718
}
@@ -1247,10 +1247,9 @@ void CodeGen::genPutArgSplit(GenTreePutArgSplit* treeNode)
12471247
{
12481248
assert(varNode->isContained());
12491249
srcVarNum = varNode->GetLclNum();
1250-
assert(srcVarNum < compiler->lvaCount);
12511250

12521251
// handle promote situation
1253-
LclVarDsc* varDsc = compiler->lvaTable + srcVarNum;
1252+
LclVarDsc* varDsc = compiler->lvaGetDesc(srcVarNum);
12541253

12551254
// This struct also must live in the stack frame
12561255
// And it can't live in a register (SIMD)
@@ -2648,16 +2647,16 @@ void CodeGen::genJmpMethod(GenTree* jmp)
26482647
// But that would require us to deal with circularity while moving values around. Spilling
26492648
// to stack makes the implementation simple, which is not a bad trade off given Jmp calls
26502649
// are not frequent.
2651-
for (varNum = 0; (varNum < compiler->info.compArgsCount); varNum++)
2650+
for (varNum = 0; varNum < compiler->info.compArgsCount; varNum++)
26522651
{
2653-
varDsc = compiler->lvaTable + varNum;
2652+
varDsc = compiler->lvaGetDesc(varNum);
26542653

26552654
if (varDsc->lvPromoted)
26562655
{
26572656
noway_assert(varDsc->lvFieldCnt == 1); // We only handle one field here
26582657

26592658
unsigned fieldVarNum = varDsc->lvFieldLclStart;
2660-
varDsc = compiler->lvaTable + fieldVarNum;
2659+
varDsc = compiler->lvaGetDesc(fieldVarNum);
26612660
}
26622661
noway_assert(varDsc->lvIsParam);
26632662

@@ -2723,15 +2722,15 @@ void CodeGen::genJmpMethod(GenTree* jmp)
27232722
// Next move any un-enregistered register arguments back to their register.
27242723
regMaskTP fixedIntArgMask = RBM_NONE; // tracks the int arg regs occupying fixed args in case of a vararg method.
27252724
unsigned firstArgVarNum = BAD_VAR_NUM; // varNum of the first argument in case of a vararg method.
2726-
for (varNum = 0; (varNum < compiler->info.compArgsCount); varNum++)
2725+
for (varNum = 0; varNum < compiler->info.compArgsCount; varNum++)
27272726
{
2728-
varDsc = compiler->lvaTable + varNum;
2727+
varDsc = compiler->lvaGetDesc(varNum);
27292728
if (varDsc->lvPromoted)
27302729
{
27312730
noway_assert(varDsc->lvFieldCnt == 1); // We only handle one field here
27322731

27332732
unsigned fieldVarNum = varDsc->lvFieldLclStart;
2734-
varDsc = compiler->lvaTable + fieldVarNum;
2733+
varDsc = compiler->lvaGetDesc(fieldVarNum);
27352734
}
27362735
noway_assert(varDsc->lvIsParam);
27372736

@@ -3253,9 +3252,9 @@ void CodeGen::genCreateAndStoreGCInfo(unsigned codeSize,
32533252
if (compiler->opts.IsReversePInvoke())
32543253
{
32553254
unsigned reversePInvokeFrameVarNumber = compiler->lvaReversePInvokeFrameVar;
3256-
assert(reversePInvokeFrameVarNumber != BAD_VAR_NUM && reversePInvokeFrameVarNumber < compiler->lvaRefCount);
3257-
LclVarDsc& reversePInvokeFrameVar = compiler->lvaTable[reversePInvokeFrameVarNumber];
3258-
gcInfoEncoder->SetReversePInvokeFrameSlot(reversePInvokeFrameVar.GetStackOffset());
3255+
assert(reversePInvokeFrameVarNumber != BAD_VAR_NUM);
3256+
const LclVarDsc* reversePInvokeFrameVar = compiler->lvaGetDesc(reversePInvokeFrameVarNumber);
3257+
gcInfoEncoder->SetReversePInvokeFrameSlot(reversePInvokeFrameVar->GetStackOffset());
32593258
}
32603259

32613260
gcInfoEncoder->Build();

0 commit comments

Comments
 (0)