From 25472eeb5db62ba18a5763a32fd693aa836b6e23 Mon Sep 17 00:00:00 2001 From: Bruce Forstall Date: Fri, 19 May 2017 14:00:07 -0700 Subject: 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%. --- src/jit/lsra.cpp | 238 ++++++++++++++++++++++++++------------------------ src/jit/lsra.h | 18 +++- src/jit/lsraxarch.cpp | 1 - 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. -- cgit v1.2.3