summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce Forstall <brucefo@microsoft.com>2017-05-19 14:00:07 -0700
committerGitHub <noreply@github.com>2017-05-19 14:00:07 -0700
commit25472eeb5db62ba18a5763a32fd693aa836b6e23 (patch)
tree7477c520578fb8c36bd6c5779ca762d3ae3d29c2
parent698a89e6e2d6866666dd942bdf7506f96fb8310e (diff)
downloadcoreclr-25472eeb5db62ba18a5763a32fd693aa836b6e23.tar.gz
coreclr-25472eeb5db62ba18a5763a32fd693aa836b6e23.tar.bz2
coreclr-25472eeb5db62ba18a5763a32fd693aa836b6e23.zip
LSRA throughput tweaks (#11698)
Convert LinearScan::getVarReg() to take a tracked var index, not varNum Change LSRA to create Intervals only for tracked variables Change getIntervalForLocalVar() to take a tracked variable index. Create getIntervalForLocalVarNode() This reduces instruction count of superpmi replay over minopts tests by 0.6%.
-rw-r--r--src/jit/lsra.cpp238
-rw-r--r--src/jit/lsra.h18
-rw-r--r--src/jit/lsraxarch.cpp1
3 files changed, 139 insertions, 118 deletions
diff --git a/src/jit/lsra.cpp b/src/jit/lsra.cpp
index 98a5d26e29..03ab4ae1f8 100644
--- a/src/jit/lsra.cpp
+++ b/src/jit/lsra.cpp
@@ -1810,7 +1810,7 @@ void LinearScan::recordVarLocationsAtStartOfBB(BasicBlock* bb)
{
unsigned varNum = compiler->lvaTrackedToVarNum[varIndex];
LclVarDsc* varDsc = &(compiler->lvaTable[varNum]);
- regNumber regNum = getVarReg(map, varNum);
+ regNumber regNum = getVarReg(map, varIndex);
regNumber oldRegNum = varDsc->lvRegNum;
regNumber newRegNum = regNum;
@@ -1837,11 +1837,15 @@ void LinearScan::recordVarLocationsAtStartOfBB(BasicBlock* bb)
JITDUMP("\n");
}
-void Interval::setLocalNumber(unsigned lclNum, LinearScan* linScan)
+void Interval::setLocalNumber(Compiler* compiler, unsigned lclNum, LinearScan* linScan)
{
- linScan->localVarIntervals[lclNum] = this;
+ LclVarDsc* varDsc = &compiler->lvaTable[lclNum];
+ assert(varDsc->lvTracked);
+ assert(varDsc->lvVarIndex < compiler->lvaTrackedCount);
- assert(linScan->getIntervalForLocalVar(lclNum) == this);
+ linScan->localVarIntervals[varDsc->lvVarIndex] = this;
+
+ assert(linScan->getIntervalForLocalVar(varDsc->lvVarIndex) == this);
this->isLocalVar = true;
this->varNum = lclNum;
}
@@ -1968,9 +1972,6 @@ void LinearScan::identifyCandidates()
identifyCandidatesExceptionDataflow();
}
- // initialize mapping from local to interval
- localVarIntervals = new (compiler, CMK_LSRA) Interval*[compiler->lvaCount];
-
unsigned lclNum;
LclVarDsc* varDsc;
@@ -2036,14 +2037,28 @@ void LinearScan::identifyCandidates()
}
#endif // DOUBLE_ALIGN
+ // initialize mapping from tracked local to interval
+ if (compiler->lvaTrackedCount > 0)
+ {
+ localVarIntervals = new (compiler, CMK_LSRA) Interval*[compiler->lvaTrackedCount];
+ }
+
for (lclNum = 0, varDsc = compiler->lvaTable; lclNum < compiler->lvaCount; lclNum++, varDsc++)
{
- // Assign intervals to all the variables - this makes it easier to map
- // them back
- var_types intervalType = (var_types)varDsc->lvType;
- Interval* newInt = newInterval(intervalType);
+ Interval* newInt;
- newInt->setLocalNumber(lclNum, this);
+ if (varDsc->lvTracked)
+ {
+ // Create an interval for all tracked variables, even if the tracked variable
+ // is not a register candidate. This is probably just done for consistency
+ // (e.g., code that simply walks over all tracked variables don't need to check if
+ // they are register candidates, or if the interval exists). It might be possible to
+ // only allocate intervals for register candidate tracked variables, if all the code
+ // that depends on every tracked variable having a non-null Interval was fixed.
+
+ newInt = newInterval((var_types)varDsc->lvType);
+ newInt->setLocalNumber(compiler, lclNum, this);
+ }
#if DOUBLE_ALIGN
if (checkDoubleAlign)
@@ -2070,11 +2085,6 @@ void LinearScan::identifyCandidates()
}
#endif // DOUBLE_ALIGN
- if (varDsc->lvIsStructField)
- {
- newInt->isStructField = true;
- }
-
// Initialize all variables to REG_STK
varDsc->lvRegNum = REG_STK;
#ifndef _TARGET_64BIT_
@@ -2082,7 +2092,7 @@ void LinearScan::identifyCandidates()
#endif // _TARGET_64BIT_
#if !defined(_TARGET_64BIT_)
- if (intervalType == TYP_LONG)
+ if (varDsc->lvType == TYP_LONG)
{
// Long variables should not be register candidates.
// Lowering will have split any candidate lclVars into lo/hi vars.
@@ -2093,14 +2103,21 @@ void LinearScan::identifyCandidates()
/* Track all locals that can be enregistered */
- varDsc->lvLRACandidate = 1;
-
if (!isRegCandidate(varDsc))
{
varDsc->lvLRACandidate = 0;
continue;
}
+ assert(varDsc->lvTracked);
+
+ varDsc->lvLRACandidate = 1;
+
+ if (varDsc->lvIsStructField)
+ {
+ newInt->isStructField = true;
+ }
+
// Start with lvRegister as false - set it true only if the variable gets
// the same register assignment throughout
varDsc->lvRegister = false;
@@ -2450,10 +2467,10 @@ VarToRegMap LinearScan::getOutVarToRegMap(unsigned int bbNum)
return outVarToRegMaps[bbNum];
}
-regNumber LinearScan::getVarReg(VarToRegMap bbVarToRegMap, unsigned int varNum)
+regNumber LinearScan::getVarReg(VarToRegMap bbVarToRegMap, unsigned int trackedVarIndex)
{
- assert(compiler->lvaTable[varNum].lvTracked);
- return bbVarToRegMap[compiler->lvaTable[varNum].lvVarIndex];
+ assert(trackedVarIndex < compiler->lvaTrackedCount);
+ return bbVarToRegMap[trackedVarIndex];
}
// Initialize the incoming VarToRegMap to the given map values (generally a predecessor of
@@ -2887,7 +2904,7 @@ bool LinearScan::buildKillPositionsForNode(GenTree* tree, LsraLocation currentLo
{
continue;
}
- Interval* interval = getIntervalForLocalVar(varNum);
+ Interval* interval = getIntervalForLocalVar(varIndex);
if (isCallKill)
{
interval->preferCalleeSave = true;
@@ -3313,8 +3330,7 @@ LinearScan::buildUpperVectorSaveRefPositions(GenTree* tree, LsraLocation current
VARSET_ITER_INIT(compiler, iter, liveLargeVectors, varIndex);
while (iter.NextElem(&varIndex))
{
- unsigned varNum = compiler->lvaTrackedToVarNum[varIndex];
- Interval* varInterval = getIntervalForLocalVar(varNum);
+ Interval* varInterval = getIntervalForLocalVar(varIndex);
Interval* tempInterval = newInterval(LargeVectorType);
tempInterval->isInternal = true;
RefPosition* pos =
@@ -3340,8 +3356,7 @@ void LinearScan::buildUpperVectorRestoreRefPositions(GenTree* tree,
VARSET_ITER_INIT(compiler, iter, liveLargeVectors, varIndex);
while (iter.NextElem(&varIndex))
{
- unsigned varNum = compiler->lvaTrackedToVarNum[varIndex];
- Interval* varInterval = getIntervalForLocalVar(varNum);
+ Interval* varInterval = getIntervalForLocalVar(varIndex);
Interval* tempInterval = varInterval->relatedInterval;
assert(tempInterval->isInternal == true);
RefPosition* pos =
@@ -3509,7 +3524,10 @@ void LinearScan::buildRefPositionsForNode(GenTree* tree,
// is processed, unless this is marked "isLocalDefUse" because it is a stack-based argument
// to a call
- Interval* interval = getIntervalForLocalVar(tree->gtLclVarCommon.gtLclNum);
+ LclVarDsc* varDsc = &compiler->lvaTable[tree->gtLclVarCommon.gtLclNum];
+ assert(varDsc->lvTracked);
+ unsigned varIndex = varDsc->lvVarIndex;
+ Interval* interval = getIntervalForLocalVar(varIndex);
regMaskTP candidates = getUseCandidates(tree);
regMaskTP fixedAssignment = fixedCandidateMask(tree->TypeGet(), candidates);
@@ -3525,8 +3543,7 @@ void LinearScan::buildRefPositionsForNode(GenTree* tree,
// we can update currentLiveVars at the same place that we create the RefPosition.
if ((tree->gtFlags & GTF_VAR_DEATH) != 0)
{
- VarSetOps::RemoveElemD(compiler, currentLiveVars,
- compiler->lvaTable[tree->gtLclVarCommon.gtLclNum].lvVarIndex);
+ VarSetOps::RemoveElemD(compiler, currentLiveVars, varIndex);
}
JITDUMP("t%u (i:%u)\n", currentLoc, interval->intervalIndex);
@@ -3624,9 +3641,12 @@ void LinearScan::buildRefPositionsForNode(GenTree* tree,
if (isCandidateLocalRef(tree))
{
// We always push the tracked lclVar intervals
- varDefInterval = getIntervalForLocalVar(tree->gtLclVarCommon.gtLclNum);
- defRefType = refTypeForLocalRefNode(tree);
- defNode = tree;
+ LclVarDsc* varDsc = &compiler->lvaTable[tree->gtLclVarCommon.gtLclNum];
+ assert(varDsc->lvTracked);
+ unsigned varIndex = varDsc->lvVarIndex;
+ varDefInterval = getIntervalForLocalVar(varIndex);
+ defRefType = refTypeForLocalRefNode(tree);
+ defNode = tree;
if (produce == 0)
{
produce = 1;
@@ -3679,8 +3699,7 @@ void LinearScan::buildRefPositionsForNode(GenTree* tree,
if ((tree->gtFlags & GTF_VAR_DEATH) == 0)
{
- VarSetOps::AddElemD(compiler, currentLiveVars,
- compiler->lvaTable[tree->gtLclVarCommon.gtLclNum].lvVarIndex);
+ VarSetOps::AddElemD(compiler, currentLiveVars, varIndex);
}
}
}
@@ -4166,7 +4185,7 @@ void LinearScan::insertZeroInitRefPositions()
if (!varDsc->lvIsParam && isCandidateVar(varDsc))
{
JITDUMP("V%02u was live in to first block:", varNum);
- Interval* interval = getIntervalForLocalVar(varNum);
+ Interval* interval = getIntervalForLocalVar(varIndex);
if (compiler->info.compInitMem || varTypeIsGC(varDsc->TypeGet()))
{
JITDUMP(" creating ZeroInit\n");
@@ -4500,7 +4519,7 @@ void LinearScan::buildIntervals()
if (isCandidateVar(argDsc))
{
- Interval* interval = getIntervalForLocalVar(lclNum);
+ Interval* interval = getIntervalForLocalVar(varIndex);
regMaskTP mask = allRegs(TypeGet(argDsc));
if (argDsc->lvIsRegArg)
{
@@ -4520,7 +4539,8 @@ void LinearScan::buildIntervals()
LclVarDsc* fieldVarDsc = &(compiler->lvaTable[fieldVarNum]);
if (fieldVarDsc->lvLRACandidate)
{
- Interval* interval = getIntervalForLocalVar(fieldVarNum);
+ assert(fieldVarDsc->lvTracked);
+ Interval* interval = getIntervalForLocalVar(fieldVarDsc->lvVarIndex);
RefPosition* pos =
newRefPosition(interval, MinLocation, RefTypeParamDef, nullptr, allRegs(TypeGet(fieldVarDsc)));
}
@@ -4625,7 +4645,7 @@ void LinearScan::buildIntervals()
// If this is the entry block, don't add any incoming parameters (they're handled with ParamDefs).
if (isCandidateVar(varDsc) && (predBlock != nullptr || !varDsc->lvIsParam))
{
- Interval* interval = getIntervalForLocalVar(varNum);
+ Interval* interval = getIntervalForLocalVar(varIndex);
RefPosition* pos =
newRefPosition(interval, currentLoc, RefTypeDummyDef, nullptr, allRegs(interval->registerType));
}
@@ -4715,7 +4735,7 @@ void LinearScan::buildIntervals()
LclVarDsc* varDsc = compiler->lvaTable + varNum;
if (isCandidateVar(varDsc))
{
- Interval* interval = getIntervalForLocalVar(varNum);
+ Interval* interval = getIntervalForLocalVar(varIndex);
RefPosition* pos =
newRefPosition(interval, currentLoc, RefTypeExpUse, nullptr, allRegs(interval->registerType));
JITDUMP(" V%02u", varNum);
@@ -4733,7 +4753,7 @@ void LinearScan::buildIntervals()
LclVarDsc* const varDsc = &compiler->lvaTable[varNum];
if (isCandidateVar(varDsc))
{
- RefPosition* const lastRP = getIntervalForLocalVar(varNum)->lastRefPosition;
+ RefPosition* const lastRP = getIntervalForLocalVar(varIndex)->lastRefPosition;
if ((lastRP != nullptr) && (lastRP->bbNum == block->bbNum))
{
lastRP->lastUse = false;
@@ -4763,10 +4783,11 @@ void LinearScan::buildIntervals()
{
unsigned keepAliveVarNum = compiler->info.compThisArg;
assert(compiler->info.compIsStatic == false);
- if (isCandidateVar(&compiler->lvaTable[keepAliveVarNum]))
+ LclVarDsc* varDsc = compiler->lvaTable + keepAliveVarNum;
+ if (isCandidateVar(varDsc))
{
JITDUMP("Adding exposed use of this, for lvaKeepAliveAndReportThis\n");
- Interval* interval = getIntervalForLocalVar(keepAliveVarNum);
+ Interval* interval = getIntervalForLocalVar(varDsc->lvVarIndex);
RefPosition* pos =
newRefPosition(interval, currentLoc, RefTypeExpUse, nullptr, allRegs(interval->registerType));
}
@@ -4781,7 +4802,7 @@ void LinearScan::buildIntervals()
if (varDsc->lvLRACandidate)
{
JITDUMP("Adding exposed use of V%02u for LsraExtendLifetimes\n", lclNum);
- Interval* interval = getIntervalForLocalVar(lclNum);
+ Interval* interval = getIntervalForLocalVar(varDsc->lvVarIndex);
RefPosition* pos =
newRefPosition(interval, currentLoc, RefTypeExpUse, nullptr, allRegs(interval->registerType));
}
@@ -4820,12 +4841,16 @@ void LinearScan::dumpVarRefPositions(const char* title)
for (unsigned i = 0; i < compiler->lvaCount; i++)
{
- Interval* interval = getIntervalForLocalVar(i);
printf("--- V%02u\n", i);
- for (RefPosition* ref = interval->firstRefPosition; ref != nullptr; ref = ref->nextRefPosition)
+ LclVarDsc* varDsc = compiler->lvaTable + i;
+ if (varDsc->lvTracked)
{
- ref->dump();
+ Interval* interval = getIntervalForLocalVar(varDsc->lvVarIndex);
+ for (RefPosition* ref = interval->firstRefPosition; ref != nullptr; ref = ref->nextRefPosition)
+ {
+ ref->dump();
+ }
}
}
@@ -4834,7 +4859,7 @@ void LinearScan::dumpVarRefPositions(const char* title)
void LinearScan::validateIntervals()
{
- for (unsigned i = 0; i < compiler->lvaCount; i++)
+ for (unsigned i = 0; i < compiler->lvaTrackedCount; i++)
{
Interval* interval = getIntervalForLocalVar(i);
@@ -4850,7 +4875,7 @@ void LinearScan::validateIntervals()
{
printf("%s: ", compiler->info.compMethodName);
}
- printf("LocalVar V%02u: undefined use at %u\n", i, ref->nodeLocation);
+ printf("LocalVar V%02u: undefined use at %u\n", interval->varNum, ref->nodeLocation);
}
// Note that there can be multiple last uses if they are on disjoint paths,
// so we can't really check the lastUse flag
@@ -6655,7 +6680,7 @@ void LinearScan::processBlockStartLocations(BasicBlock* currentBlock, bool alloc
continue;
}
regNumber targetReg;
- Interval* interval = getIntervalForLocalVar(varNum);
+ Interval* interval = getIntervalForLocalVar(varIndex);
RefPosition* nextRefPosition = interval->getNextRefPosition();
assert(nextRefPosition != nullptr);
@@ -6871,8 +6896,7 @@ void LinearScan::processBlockEndLocations(BasicBlock* currentBlock)
VARSET_ITER_INIT(compiler, iter, liveOut, varIndex);
while (iter.NextElem(&varIndex))
{
- unsigned varNum = compiler->lvaTrackedToVarNum[varIndex];
- Interval* interval = getIntervalForLocalVar(varNum);
+ Interval* interval = getIntervalForLocalVar(varIndex);
if (interval->isActive)
{
assert(interval->physReg != REG_NA && interval->physReg != REG_STK);
@@ -8488,10 +8512,10 @@ void LinearScan::resolveRegisters()
}
// Clear "recentRefPosition" for lclVar intervals
- for (unsigned lclNum = 0; lclNum < compiler->lvaCount; lclNum++)
+ for (unsigned varIndex = 0; varIndex < compiler->lvaTrackedCount; varIndex++)
{
- localVarIntervals[lclNum]->recentRefPosition = nullptr;
- localVarIntervals[lclNum]->isActive = false;
+ localVarIntervals[varIndex]->recentRefPosition = nullptr;
+ localVarIntervals[varIndex]->isActive = false;
}
// handle incoming arguments and special temps
@@ -8849,7 +8873,7 @@ void LinearScan::resolveRegisters()
}
else
{
- Interval* interval = getIntervalForLocalVar(lclNum);
+ Interval* interval = getIntervalForLocalVar(varDsc->lvVarIndex);
// Determine initial position for parameters
@@ -9319,8 +9343,7 @@ void LinearScan::handleOutgoingCriticalEdges(BasicBlock* block)
VARSET_ITER_INIT(compiler, iter1, block->bbLiveOut, varIndex1);
while (iter1.NextElem(&varIndex1))
{
- unsigned varNum = compiler->lvaTrackedToVarNum[varIndex1];
- regNumber fromReg = getVarReg(outVarToRegMap, varNum);
+ regNumber fromReg = getVarReg(outVarToRegMap, varIndex1);
if (fromReg != REG_STK)
{
liveOutRegs |= genRegMask(fromReg);
@@ -9362,8 +9385,7 @@ void LinearScan::handleOutgoingCriticalEdges(BasicBlock* block)
VARSET_ITER_INIT(compiler, iter, outResolutionSet, varIndex);
while (iter.NextElem(&varIndex))
{
- unsigned varNum = compiler->lvaTrackedToVarNum[varIndex];
- regNumber fromReg = getVarReg(outVarToRegMap, varNum);
+ regNumber fromReg = getVarReg(outVarToRegMap, varIndex);
bool isMatch = true;
bool isSame = false;
bool maybeSingleTarget = false;
@@ -9384,7 +9406,7 @@ void LinearScan::handleOutgoingCriticalEdges(BasicBlock* block)
liveOnlyAtSplitEdge = ((succBlock->bbPreds->flNext == nullptr) && (succBlock != compiler->fgFirstBB));
}
- regNumber toReg = getVarReg(getInVarToRegMap(succBlock->bbNum), varNum);
+ regNumber toReg = getVarReg(getInVarToRegMap(succBlock->bbNum), varIndex);
if (sameToReg == REG_NA)
{
sameToReg = toReg;
@@ -9490,10 +9512,8 @@ void LinearScan::handleOutgoingCriticalEdges(BasicBlock* block)
VARSET_ITER_INIT(compiler, iter, edgeResolutionSet, varIndex);
while (iter.NextElem(&varIndex))
{
- unsigned varNum = compiler->lvaTrackedToVarNum[varIndex];
- Interval* interval = getIntervalForLocalVar(varNum);
- regNumber fromReg = getVarReg(outVarToRegMap, varNum);
- regNumber toReg = getVarReg(succInVarToRegMap, varNum);
+ regNumber fromReg = getVarReg(outVarToRegMap, varIndex);
+ regNumber toReg = getVarReg(succInVarToRegMap, varIndex);
if (fromReg == toReg)
{
@@ -9695,19 +9715,18 @@ void LinearScan::resolveEdges()
VARSET_ITER_INIT(compiler, iter, block->bbLiveIn, varIndex);
while (iter.NextElem(&varIndex))
{
- unsigned varNum = compiler->lvaTrackedToVarNum[varIndex];
- regNumber fromReg = getVarReg(fromVarToRegMap, varNum);
- regNumber toReg = getVarReg(toVarToRegMap, varNum);
+ regNumber fromReg = getVarReg(fromVarToRegMap, varIndex);
+ regNumber toReg = getVarReg(toVarToRegMap, varIndex);
if (fromReg != toReg)
{
- Interval* interval = getIntervalForLocalVar(varNum);
if (!foundMismatch)
{
foundMismatch = true;
printf("Found mismatched var locations after resolution!\n");
}
- printf(" V%02u: BB%02u to BB%02u: ", varNum, predBlock->bbNum, block->bbNum);
- printf("%s to %s\n", getRegName(fromReg), getRegName(toReg));
+ unsigned varNum = compiler->lvaTrackedToVarNum[varIndex];
+ printf(" V%02u: BB%02u to BB%02u: %s to %s\n", varNum, predBlock->bbNum, block->bbNum,
+ getRegName(fromReg), getRegName(toReg));
}
}
}
@@ -9851,11 +9870,8 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock,
VARSET_ITER_INIT(compiler, iter, liveSet, varIndex);
while (iter.NextElem(&varIndex))
{
- unsigned varNum = compiler->lvaTrackedToVarNum[varIndex];
- bool isSpilled = false;
- Interval* interval = getIntervalForLocalVar(varNum);
- regNumber fromReg = getVarReg(fromVarToRegMap, varNum);
- regNumber toReg = getVarReg(toVarToRegMap, varNum);
+ regNumber fromReg = getVarReg(fromVarToRegMap, varIndex);
+ regNumber toReg = getVarReg(toVarToRegMap, varIndex);
if (fromReg == toReg)
{
continue;
@@ -9874,28 +9890,25 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock,
assert(fromReg < UCHAR_MAX && toReg < UCHAR_MAX);
- bool done = false;
+ Interval* interval = getIntervalForLocalVar(varIndex);
- if (fromReg != toReg)
+ if (fromReg == REG_STK)
{
- if (fromReg == REG_STK)
- {
- stackToRegIntervals[toReg] = interval;
- targetRegsFromStack |= genRegMask(toReg);
- }
- else if (toReg == REG_STK)
- {
- // Do the reg to stack moves now
- addResolution(block, insertionPoint, interval, REG_STK, fromReg);
- JITDUMP(" (%s)\n", resolveTypeName[resolveType]);
- }
- else
- {
- location[fromReg] = (regNumberSmall)fromReg;
- source[toReg] = (regNumberSmall)fromReg;
- sourceIntervals[fromReg] = interval;
- targetRegsToDo |= genRegMask(toReg);
- }
+ stackToRegIntervals[toReg] = interval;
+ targetRegsFromStack |= genRegMask(toReg);
+ }
+ else if (toReg == REG_STK)
+ {
+ // Do the reg to stack moves now
+ addResolution(block, insertionPoint, interval, REG_STK, fromReg);
+ JITDUMP(" (%s)\n", resolveTypeName[resolveType]);
+ }
+ else
+ {
+ location[fromReg] = (regNumberSmall)fromReg;
+ source[toReg] = (regNumberSmall)fromReg;
+ sourceIntervals[fromReg] = interval;
+ targetRegsToDo |= genRegMask(toReg);
}
}
@@ -10653,7 +10666,7 @@ void LinearScan::lsraDispNode(GenTreePtr tree, LsraTupleDumpMode mode, bool hasD
{
if (mode == LSRA_DUMP_REFPOS)
{
- printf(" V%02u(L%d)", varNum, getIntervalForLocalVar(varNum)->intervalIndex);
+ printf(" V%02u(L%d)", varNum, getIntervalForLocalVar(varDsc->lvVarIndex)->intervalIndex);
}
else
{
@@ -11921,9 +11934,8 @@ void LinearScan::verifyFinalAllocation()
VARSET_ITER_INIT(compiler, iter, currentBlock->bbLiveOut, varIndex);
while (iter.NextElem(&varIndex))
{
- unsigned varNum = compiler->lvaTrackedToVarNum[varIndex];
- regNumber regNum = getVarReg(outVarToRegMap, varNum);
- interval = getIntervalForLocalVar(varNum);
+ regNumber regNum = getVarReg(outVarToRegMap, varIndex);
+ interval = getIntervalForLocalVar(varIndex);
assert(interval->physReg == regNum || (interval->physReg == REG_NA && regNum == REG_STK));
interval->physReg = REG_NA;
interval->assignedReg = nullptr;
@@ -11947,9 +11959,8 @@ void LinearScan::verifyFinalAllocation()
VARSET_ITER_INIT(compiler, iter, currentBlock->bbLiveIn, varIndex);
while (iter.NextElem(&varIndex))
{
- unsigned varNum = compiler->lvaTrackedToVarNum[varIndex];
- regNumber regNum = getVarReg(inVarToRegMap, varNum);
- interval = getIntervalForLocalVar(varNum);
+ regNumber regNum = getVarReg(inVarToRegMap, varIndex);
+ interval = getIntervalForLocalVar(varIndex);
interval->physReg = regNum;
interval->assignedReg = &(physRegs[regNum]);
interval->isActive = true;
@@ -12189,9 +12200,8 @@ void LinearScan::verifyFinalAllocation()
VARSET_ITER_INIT(compiler, iter, currentBlock->bbLiveIn, varIndex);
while (iter.NextElem(&varIndex))
{
- unsigned varNum = compiler->lvaTrackedToVarNum[varIndex];
- regNumber regNum = getVarReg(inVarToRegMap, varNum);
- Interval* interval = getIntervalForLocalVar(varNum);
+ regNumber regNum = getVarReg(inVarToRegMap, varIndex);
+ Interval* interval = getIntervalForLocalVar(varIndex);
interval->physReg = regNum;
interval->assignedReg = &(physRegs[regNum]);
interval->isActive = true;
@@ -12217,9 +12227,8 @@ void LinearScan::verifyFinalAllocation()
VARSET_ITER_INIT(compiler, iter, currentBlock->bbLiveOut, varIndex);
while (iter.NextElem(&varIndex))
{
- unsigned varNum = compiler->lvaTrackedToVarNum[varIndex];
- regNumber regNum = getVarReg(outVarToRegMap, varNum);
- Interval* interval = getIntervalForLocalVar(varNum);
+ regNumber regNum = getVarReg(outVarToRegMap, varIndex);
+ Interval* interval = getIntervalForLocalVar(varIndex);
assert(interval->physReg == regNum || (interval->physReg == REG_NA && regNum == REG_STK));
interval->physReg = REG_NA;
interval->assignedReg = nullptr;
@@ -12255,8 +12264,10 @@ void LinearScan::verifyResolutionMove(GenTree* resolutionMove, LsraLocation curr
GenTreeLclVarCommon* right = dst->gtGetOp2()->AsLclVarCommon();
regNumber leftRegNum = left->gtRegNum;
regNumber rightRegNum = right->gtRegNum;
- Interval* leftInterval = getIntervalForLocalVar(left->gtLclNum);
- Interval* rightInterval = getIntervalForLocalVar(right->gtLclNum);
+ LclVarDsc* leftVarDsc = compiler->lvaTable + left->gtLclNum;
+ LclVarDsc* rightVarDsc = compiler->lvaTable + right->gtLclNum;
+ Interval* leftInterval = getIntervalForLocalVar(leftVarDsc->lvVarIndex);
+ Interval* rightInterval = getIntervalForLocalVar(rightVarDsc->lvVarIndex);
assert(leftInterval->physReg == leftRegNum && rightInterval->physReg == rightRegNum);
leftInterval->physReg = rightRegNum;
rightInterval->physReg = leftRegNum;
@@ -12301,7 +12312,8 @@ void LinearScan::verifyResolutionMove(GenTree* resolutionMove, LsraLocation curr
dstRegNum = REG_STK;
}
}
- Interval* interval = getIntervalForLocalVar(lcl->gtLclNum);
+
+ Interval* interval = getIntervalForLocalVarNode(lcl);
assert(interval->physReg == srcRegNum || (srcRegNum == REG_STK && interval->physReg == REG_NA));
if (srcRegNum != REG_STK)
{
diff --git a/src/jit/lsra.h b/src/jit/lsra.h
index f0a9d54aad..5db0c8a677 100644
--- a/src/jit/lsra.h
+++ b/src/jit/lsra.h
@@ -849,10 +849,19 @@ public:
private:
Interval* newInterval(RegisterType regType);
- Interval* getIntervalForLocalVar(unsigned varNum)
+ Interval* getIntervalForLocalVar(unsigned varIndex)
{
- return localVarIntervals[varNum];
+ assert(varIndex < compiler->lvaTrackedCount);
+ return localVarIntervals[varIndex];
}
+
+ Interval* getIntervalForLocalVarNode(GenTreeLclVarCommon* tree)
+ {
+ LclVarDsc* varDsc = &compiler->lvaTable[tree->gtLclNum];
+ assert(varDsc->lvTracked);
+ return getIntervalForLocalVar(varDsc->lvVarIndex);
+ }
+
RegRecord* getRegisterRecord(regNumber regNum);
RefPosition* newRefPositionRaw(LsraLocation nodeLocation, GenTree* treeNode, RefType refType);
@@ -947,7 +956,7 @@ private:
void setOutVarRegForBB(unsigned int bbNum, unsigned int varNum, regNumber reg);
VarToRegMap getInVarToRegMap(unsigned int bbNum);
VarToRegMap getOutVarToRegMap(unsigned int bbNum);
- regNumber getVarReg(VarToRegMap map, unsigned int varNum);
+ regNumber getVarReg(VarToRegMap map, unsigned int trackedVarIndex);
// Initialize the incoming VarToRegMap to the given map values (generally a predecessor of
// the block)
VarToRegMap setInVarToRegMap(unsigned int bbNum, VarToRegMap srcVarToRegMap);
@@ -1100,6 +1109,7 @@ private:
RegRecord physRegs[REG_COUNT];
+ // Map from tracked variable index to Interval*.
Interval** localVarIntervals;
// Set of blocks that have been visited.
@@ -1242,7 +1252,7 @@ public:
void microDump();
#endif // DEBUG
- void setLocalNumber(unsigned localNum, LinearScan* l);
+ void setLocalNumber(Compiler* compiler, unsigned lclNum, LinearScan* l);
// Fixed registers for which this Interval has a preference
regMaskTP registerPreferences;
diff --git a/src/jit/lsraxarch.cpp b/src/jit/lsraxarch.cpp
index 97eb1b9d55..56f1bd26d6 100644
--- a/src/jit/lsraxarch.cpp
+++ b/src/jit/lsraxarch.cpp
@@ -2072,7 +2072,6 @@ void Lowering::TreeNodeInfoInitLclHeap(GenTree* tree)
void Lowering::TreeNodeInfoInitLogicalOp(GenTree* tree)
{
TreeNodeInfo* info = &(tree->gtLsraInfo);
- LinearScan* l = m_lsra;
// We're not marking a constant hanging on the left of the add
// as containable so we assign it to a register having CQ impact.