Skip to content

Commit ccf0b25

Browse files
committed
Make more extensive use of lvaGetDesc()
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 aae8f51 commit ccf0b25

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)
@@ -1316,9 +1313,8 @@ AssertionIndex Compiler::optCreateAssertion(GenTree* op1,
13161313
goto DONE_ASSERTION; // Don't make an assertion
13171314
}
13181315

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

13231319
ValueNum vn;
13241320

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

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

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

15671561
// If the two locals are the same then bail
15681562
if (lclNum == lclNum2)
@@ -1633,7 +1627,6 @@ AssertionIndex Compiler::optCreateAssertion(GenTree* op1,
16331627
if (op1->gtOper == GT_LCL_VAR)
16341628
{
16351629
unsigned lclNum = op1->AsLclVarCommon()->GetLclNum();
1636-
noway_assert(lclNum < lvaCount);
16371630

16381631
// If the local variable is not in SSA then bail
16391632
if (!lvaInSsa(lclNum))
@@ -1657,7 +1650,7 @@ AssertionIndex Compiler::optCreateAssertion(GenTree* op1,
16571650
assert((assertion.op1.lcl.ssaNum == SsaConfig::RESERVED_SSA_NUM) ||
16581651
(assertion.op1.vn ==
16591652
vnStore->VNConservativeNormalValue(
1660-
lvaTable[lclNum].GetPerSsaData(assertion.op1.lcl.ssaNum)->m_vnPair)));
1653+
lvaGetDesc(lclNum)->GetPerSsaData(assertion.op1.lcl.ssaNum)->m_vnPair)));
16611654

16621655
ssize_t cnsValue = 0;
16631656
GenTreeFlags iconFlags = GTF_EMPTY;
@@ -1972,9 +1965,8 @@ void Compiler::optDebugCheckAssertion(AssertionDsc* assertion)
19721965
case O1K_LCLVAR:
19731966
case O1K_EXACT_TYPE:
19741967
case O1K_SUBTYPE:
1975-
assert(assertion->op1.lcl.lclNum < lvaCount);
19761968
assert(optLocalAssertionProp ||
1977-
lvaTable[assertion->op1.lcl.lclNum].lvPerSsaData.IsValidSsaNum(assertion->op1.lcl.ssaNum));
1969+
lvaGetDesc(assertion->op1.lcl.lclNum)->lvPerSsaData.IsValidSsaNum(assertion->op1.lcl.ssaNum));
19781970
break;
19791971
case O1K_ARR_BND:
19801972
// It would be good to check that bnd.vnIdx and bnd.vnLen are valid value numbers.
@@ -2007,7 +1999,7 @@ void Compiler::optDebugCheckAssertion(AssertionDsc* assertion)
20071999
assert(assertion->op2.u1.iconFlags != GTF_EMPTY);
20082000
break;
20092001
case O1K_LCLVAR:
2010-
assert((lvaTable[assertion->op1.lcl.lclNum].lvType != TYP_REF) ||
2002+
assert((lvaGetDesc(assertion->op1.lcl.lclNum)->lvType != TYP_REF) ||
20112003
(assertion->op2.u1.iconVal == 0) || doesMethodHaveFrozenString());
20122004
break;
20132005
case O1K_VALUE_NUMBER:

src/coreclr/jit/codegen.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1297,8 +1297,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
12971297
{
12981298
return false;
12991299
}
1300-
const LclVarDsc* varDsc = &compiler->lvaTable[tree->AsLclVarCommon()->GetLclNum()];
1301-
return (varDsc->lvIsRegCandidate());
1300+
return compiler->lvaGetDesc(tree->AsLclVarCommon())->lvIsRegCandidate();
13021301
}
13031302

13041303
#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
@@ -713,7 +713,7 @@ void CodeGen::genPutArgStk(GenTreePutArgStk* treeNode)
713713
// Since it is a fast tail call, the existence of first incoming arg is guaranteed
714714
// because fast tail call requires that in-coming arg area of caller is >= out-going
715715
// arg area required for tail call.
716-
LclVarDsc* varDsc = &(compiler->lvaTable[varNumOut]);
716+
LclVarDsc* varDsc = compiler->lvaGetDesc(varNumOut);
717717
assert(varDsc != nullptr);
718718
#endif // FEATURE_FASTTAILCALL
719719
}
@@ -1248,10 +1248,9 @@ void CodeGen::genPutArgSplit(GenTreePutArgSplit* treeNode)
12481248
{
12491249
assert(varNode->isContained());
12501250
srcVarNum = varNode->GetLclNum();
1251-
assert(srcVarNum < compiler->lvaCount);
12521251

12531252
// handle promote situation
1254-
LclVarDsc* varDsc = compiler->lvaTable + srcVarNum;
1253+
LclVarDsc* varDsc = compiler->lvaGetDesc(srcVarNum);
12551254

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

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

26602659
unsigned fieldVarNum = varDsc->lvFieldLclStart;
2661-
varDsc = compiler->lvaTable + fieldVarNum;
2660+
varDsc = compiler->lvaGetDesc(fieldVarNum);
26622661
}
26632662
noway_assert(varDsc->lvIsParam);
26642663

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

27342733
unsigned fieldVarNum = varDsc->lvFieldLclStart;
2735-
varDsc = compiler->lvaTable + fieldVarNum;
2734+
varDsc = compiler->lvaGetDesc(fieldVarNum);
27362735
}
27372736
noway_assert(varDsc->lvIsParam);
27382737

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

32623261
gcInfoEncoder->Build();

0 commit comments

Comments
 (0)