From 8dacb652589154c90bacd8e11f6ac7604873cf30 Mon Sep 17 00:00:00 2001 From: Jakob Botsch Nielsen Date: Thu, 9 Feb 2023 21:39:15 +0100 Subject: [PATCH 01/10] Remove LinearScan::RegisterSelection::score --- src/coreclr/jit/lsra.cpp | 25 +++++++++++++++++++------ src/coreclr/jit/lsra.h | 5 +++-- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/src/coreclr/jit/lsra.cpp b/src/coreclr/jit/lsra.cpp index 80c3a19516601..3345cec036085 100644 --- a/src/coreclr/jit/lsra.cpp +++ b/src/coreclr/jit/lsra.cpp @@ -11078,7 +11078,9 @@ void LinearScan::RegisterSelection::reset(Interval* interval, RefPosition* refPo { currentInterval = interval; refPosition = refPos; - score = 0; + + coversFullApplied = false; + constAvailableApplied = false; regType = linearScan->getRegisterType(currentInterval, refPosition); currentLocation = refPosition->nodeLocation; @@ -11130,7 +11132,6 @@ bool LinearScan::RegisterSelection::applySelection(int selectionScore, regMaskTP regMaskTP newCandidates = candidates & selectionCandidates; if (newCandidates != RBM_NONE) { - score += selectionScore; candidates = newCandidates; return LinearScan::isSingleRegister(candidates); } @@ -11188,7 +11189,13 @@ void LinearScan::RegisterSelection::try_CONST_AVAILABLE() if (currentInterval->isConstant && RefTypeIsDef(refPosition->refType)) { - found = applySelection(CONST_AVAILABLE, matchingConstants); + regMaskTP newCandidates = candidates & matchingConstants; + if (newCandidates != RBM_NONE) + { + candidates = newCandidates; + constAvailableApplied = true; + found = isSingleRegister(newCandidates); + } } } @@ -11296,7 +11303,13 @@ void LinearScan::RegisterSelection::try_COVERS_FULL() calculateCoversSets(); #endif - found = applySelection(COVERS_FULL, (coversFullSet & freeCandidates)); + regMaskTP newCandidates = candidates & coversFullSet & freeCandidates; + if (newCandidates != RBM_NONE) + { + candidates = newCandidates; + found = isSingleRegister(candidates); + coversFullApplied = true; + } } // ---------------------------------------------------------- @@ -11314,7 +11327,7 @@ void LinearScan::RegisterSelection::try_BEST_FIT() regMaskTP bestFitSet = RBM_NONE; // If the best score includes COVERS_FULL, pick the one that's killed soonest. // If none cover the full range, the BEST_FIT is the one that's killed later. - bool earliestIsBest = ((score & COVERS_FULL) != 0); + bool earliestIsBest = coversFullApplied; LsraLocation bestFitLocation = earliestIsBest ? MaxLocation : MinLocation; for (regMaskTP bestFitCandidates = candidates; bestFitCandidates != RBM_NONE;) { @@ -11382,7 +11395,7 @@ void LinearScan::RegisterSelection::try_BEST_FIT() void LinearScan::RegisterSelection::try_IS_PREV_REG() { // TODO: We do not check found here. - if ((prevRegRec != nullptr) && ((score & COVERS_FULL) != 0)) + if ((prevRegRec != nullptr) && coversFullApplied) { found = applySingleRegSelection(IS_PREV_REG, prevRegBit); } diff --git a/src/coreclr/jit/lsra.h b/src/coreclr/jit/lsra.h index dc43e40b95454..87be778c092e0 100644 --- a/src/coreclr/jit/lsra.h +++ b/src/coreclr/jit/lsra.h @@ -1242,7 +1242,7 @@ class LinearScan : public LinearScanInterface // Did we apply CONST_AVAILABLE heuristics FORCEINLINE bool isConstAvailable() { - return (score & CONST_AVAILABLE) != 0; + return constAvailableApplied; } private: @@ -1251,7 +1251,6 @@ class LinearScan : public LinearScanInterface ScoreMappingTable* mappingTable = nullptr; #endif LinearScan* linearScan = nullptr; - int score = 0; Interval* currentInterval = nullptr; RefPosition* refPosition = nullptr; @@ -1290,6 +1289,8 @@ class LinearScan : public LinearScanInterface bool coversSetsCalculated = false; bool found = false; bool skipAllocation = false; + bool coversFullApplied = false; + bool constAvailableApplied = false; regNumber foundReg = REG_NA; // If the selected register is already assigned to the current internal From 4533555a03836c8eb01d56576896392aeaf54137 Mon Sep 17 00:00:00 2001 From: Jakob Botsch Nielsen Date: Thu, 9 Feb 2023 21:44:39 +0100 Subject: [PATCH 02/10] Remove currentLocation from state --- src/coreclr/jit/lsra.cpp | 7 +++---- src/coreclr/jit/lsra.h | 1 - 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/coreclr/jit/lsra.cpp b/src/coreclr/jit/lsra.cpp index 3345cec036085..562d849b62657 100644 --- a/src/coreclr/jit/lsra.cpp +++ b/src/coreclr/jit/lsra.cpp @@ -11083,7 +11083,6 @@ void LinearScan::RegisterSelection::reset(Interval* interval, RefPosition* refPo constAvailableApplied = false; regType = linearScan->getRegisterType(currentInterval, refPosition); - currentLocation = refPosition->nodeLocation; nextRefPos = refPosition->nextRefPosition; candidates = refPosition->registerAssignment; preferences = currentInterval->registerPreferences; @@ -11462,7 +11461,7 @@ void LinearScan::RegisterSelection::try_SPILL_COST() // Can and should the interval in this register be spilled for this one, // if we don't find a better alternative? - if ((linearScan->getNextIntervalRef(spillCandidateRegNum, regType) == currentLocation) && + if ((linearScan->getNextIntervalRef(spillCandidateRegNum, regType) == refPosition->nodeLocation) && !assignedInterval->getNextRefPosition()->RegOptional()) { continue; @@ -11962,8 +11961,8 @@ regMaskTP LinearScan::RegisterSelection::select(Interval* currentInterval, regNumber checkConflictReg = genRegNumFromMask(checkConflictBit); LsraLocation checkConflictLocation = linearScan->nextFixedRef[checkConflictReg]; - if ((checkConflictLocation == currentLocation) || - (refPosition->delayRegFree && (checkConflictLocation == (currentLocation + 1)))) + if ((checkConflictLocation == refPosition->nodeLocation) || + (refPosition->delayRegFree && (checkConflictLocation == (refPosition->nodeLocation + 1)))) { candidates &= ~checkConflictBit; } diff --git a/src/coreclr/jit/lsra.h b/src/coreclr/jit/lsra.h index 87be778c092e0..2a727cb07879a 100644 --- a/src/coreclr/jit/lsra.h +++ b/src/coreclr/jit/lsra.h @@ -1255,7 +1255,6 @@ class LinearScan : public LinearScanInterface RefPosition* refPosition = nullptr; RegisterType regType = RegisterType::TYP_UNKNOWN; - LsraLocation currentLocation = MinLocation; RefPosition* nextRefPos = nullptr; regMaskTP candidates; From d9afa470d94e5536620a94e565c620290a220b22 Mon Sep 17 00:00:00 2001 From: Jakob Botsch Nielsen Date: Thu, 9 Feb 2023 21:45:55 +0100 Subject: [PATCH 03/10] Remove nextRefPos from state --- src/coreclr/jit/lsra.cpp | 2 +- src/coreclr/jit/lsra.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/coreclr/jit/lsra.cpp b/src/coreclr/jit/lsra.cpp index 562d849b62657..3e780d84b7465 100644 --- a/src/coreclr/jit/lsra.cpp +++ b/src/coreclr/jit/lsra.cpp @@ -11083,7 +11083,6 @@ void LinearScan::RegisterSelection::reset(Interval* interval, RefPosition* refPo constAvailableApplied = false; regType = linearScan->getRegisterType(currentInterval, refPosition); - nextRefPos = refPosition->nextRefPosition; candidates = refPosition->registerAssignment; preferences = currentInterval->registerPreferences; @@ -11752,6 +11751,7 @@ regMaskTP LinearScan::RegisterSelection::select(Interval* currentInterval, // process data-structures if (RefTypeIsDef(refPosition->refType)) { + RefPosition* nextRefPos = refPosition->nextRefPosition; if (currentInterval->hasConflictingDefUse) { linearScan->resolveConflictingDefAndUse(currentInterval, refPosition); diff --git a/src/coreclr/jit/lsra.h b/src/coreclr/jit/lsra.h index 2a727cb07879a..86aed5571698d 100644 --- a/src/coreclr/jit/lsra.h +++ b/src/coreclr/jit/lsra.h @@ -1255,7 +1255,6 @@ class LinearScan : public LinearScanInterface RefPosition* refPosition = nullptr; RegisterType regType = RegisterType::TYP_UNKNOWN; - RefPosition* nextRefPos = nullptr; regMaskTP candidates; regMaskTP preferences = RBM_NONE; From 21ed6cce13d6425d8dee34af34237efc3b99cd8b Mon Sep 17 00:00:00 2001 From: Jakob Botsch Nielsen Date: Thu, 9 Feb 2023 21:53:28 +0100 Subject: [PATCH 04/10] Remove rangeEndRefPosition --- src/coreclr/jit/lsra.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/coreclr/jit/lsra.cpp b/src/coreclr/jit/lsra.cpp index 3e780d84b7465..b6e8f73b9e289 100644 --- a/src/coreclr/jit/lsra.cpp +++ b/src/coreclr/jit/lsra.cpp @@ -11094,7 +11094,6 @@ void LinearScan::RegisterSelection::reset(Interval* interval, RefPosition* refPo rangeEndLocation = refPosition->getRangeEndLocation(); relatedLastLocation = rangeEndLocation; preferCalleeSave = currentInterval->preferCalleeSave; - rangeEndRefPosition = nullptr; lastRefPosition = currentInterval->lastRefPosition; lastLocation = MinLocation; prevRegRec = currentInterval->assignedReg; From e6687101bf7b1986cb18ab9ef019e01ce615d091 Mon Sep 17 00:00:00 2001 From: Jakob Botsch Nielsen Date: Thu, 9 Feb 2023 21:54:06 +0100 Subject: [PATCH 05/10] Remove lastLocation --- src/coreclr/jit/lsra.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/coreclr/jit/lsra.cpp b/src/coreclr/jit/lsra.cpp index b6e8f73b9e289..392584c5eeaeb 100644 --- a/src/coreclr/jit/lsra.cpp +++ b/src/coreclr/jit/lsra.cpp @@ -11095,7 +11095,6 @@ void LinearScan::RegisterSelection::reset(Interval* interval, RefPosition* refPo relatedLastLocation = rangeEndLocation; preferCalleeSave = currentInterval->preferCalleeSave; lastRefPosition = currentInterval->lastRefPosition; - lastLocation = MinLocation; prevRegRec = currentInterval->assignedReg; // These are used in the post-selection updates, and must be set for any selection. From 6bef31dae35e68a0448edc1c732937bf556b3198 Mon Sep 17 00:00:00 2001 From: Jakob Botsch Nielsen Date: Thu, 9 Feb 2023 22:03:21 +0100 Subject: [PATCH 06/10] Remove prevRegRec from state --- src/coreclr/jit/lsra.cpp | 8 ++++---- src/coreclr/jit/lsra.h | 1 - 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/coreclr/jit/lsra.cpp b/src/coreclr/jit/lsra.cpp index 392584c5eeaeb..814a697169c56 100644 --- a/src/coreclr/jit/lsra.cpp +++ b/src/coreclr/jit/lsra.cpp @@ -11095,7 +11095,6 @@ void LinearScan::RegisterSelection::reset(Interval* interval, RefPosition* refPo relatedLastLocation = rangeEndLocation; preferCalleeSave = currentInterval->preferCalleeSave; lastRefPosition = currentInterval->lastRefPosition; - prevRegRec = currentInterval->assignedReg; // These are used in the post-selection updates, and must be set for any selection. freeCandidates = RBM_NONE; @@ -11206,7 +11205,7 @@ void LinearScan::RegisterSelection::try_THIS_ASSIGNED() return; } - if (prevRegRec != nullptr) + if (currentInterval->assignedReg != nullptr) { found = applySelection(THIS_ASSIGNED, freeCandidates & preferences & prevRegBit); } @@ -11391,7 +11390,7 @@ void LinearScan::RegisterSelection::try_BEST_FIT() void LinearScan::RegisterSelection::try_IS_PREV_REG() { // TODO: We do not check found here. - if ((prevRegRec != nullptr) && coversFullApplied) + if ((currentInterval->assignedReg != nullptr) && coversFullApplied) { found = applySingleRegSelection(IS_PREV_REG, prevRegBit); } @@ -11973,8 +11972,9 @@ regMaskTP LinearScan::RegisterSelection::select(Interval* currentInterval, // been restored as inactive after a kill? // NOTE: this is not currently considered one of the selection criteria - it always wins // if it is the assignedInterval of 'prevRegRec'. - if (!found && (prevRegRec != nullptr)) + if (!found && (currentInterval->assignedReg != nullptr)) { + RegRecord* prevRegRec = currentInterval->assignedReg; prevRegBit = genRegMask(prevRegRec->regNum); if ((prevRegRec->assignedInterval == currentInterval) && ((candidates & prevRegBit) != RBM_NONE)) { diff --git a/src/coreclr/jit/lsra.h b/src/coreclr/jit/lsra.h index 86aed5571698d..b75b00d0625df 100644 --- a/src/coreclr/jit/lsra.h +++ b/src/coreclr/jit/lsra.h @@ -1268,7 +1268,6 @@ class LinearScan : public LinearScanInterface RefPosition* lastRefPosition; regMaskTP callerCalleePrefs = RBM_NONE; LsraLocation lastLocation; - RegRecord* prevRegRec = nullptr; regMaskTP prevRegBit = RBM_NONE; From 8c0742206d7f7f1e53c733eada0997515574d0e0 Mon Sep 17 00:00:00 2001 From: Jakob Botsch Nielsen Date: Thu, 9 Feb 2023 22:03:31 +0100 Subject: [PATCH 07/10] Remove unused field --- src/coreclr/jit/lsra.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/coreclr/jit/lsra.h b/src/coreclr/jit/lsra.h index b75b00d0625df..9a0ebe9ee4dd9 100644 --- a/src/coreclr/jit/lsra.h +++ b/src/coreclr/jit/lsra.h @@ -1288,7 +1288,6 @@ class LinearScan : public LinearScanInterface bool skipAllocation = false; bool coversFullApplied = false; bool constAvailableApplied = false; - regNumber foundReg = REG_NA; // If the selected register is already assigned to the current internal FORCEINLINE bool isAlreadyAssigned() From a2ec931a31e628fe39bbd933c33c71905e386fe7 Mon Sep 17 00:00:00 2001 From: Jakob Botsch Nielsen Date: Thu, 9 Feb 2023 22:05:53 +0100 Subject: [PATCH 08/10] Reorder zero initialization --- src/coreclr/jit/lsra.cpp | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/src/coreclr/jit/lsra.cpp b/src/coreclr/jit/lsra.cpp index 814a697169c56..c62b3778cc042 100644 --- a/src/coreclr/jit/lsra.cpp +++ b/src/coreclr/jit/lsra.cpp @@ -11079,9 +11079,6 @@ void LinearScan::RegisterSelection::reset(Interval* interval, RefPosition* refPo currentInterval = interval; refPosition = refPos; - coversFullApplied = false; - constAvailableApplied = false; - regType = linearScan->getRegisterType(currentInterval, refPosition); candidates = refPosition->registerAssignment; preferences = currentInterval->registerPreferences; @@ -11097,19 +11094,19 @@ void LinearScan::RegisterSelection::reset(Interval* interval, RefPosition* refPo lastRefPosition = currentInterval->lastRefPosition; // These are used in the post-selection updates, and must be set for any selection. - freeCandidates = RBM_NONE; - matchingConstants = RBM_NONE; - unassignedSet = RBM_NONE; - - coversSet = RBM_NONE; - preferenceSet = RBM_NONE; - coversRelatedSet = RBM_NONE; - coversFullSet = RBM_NONE; - - foundRegBit = REG_NA; - found = false; - skipAllocation = false; - coversSetsCalculated = false; + freeCandidates = RBM_NONE; + matchingConstants = RBM_NONE; + unassignedSet = RBM_NONE; + foundRegBit = RBM_NONE; + coversSet = RBM_NONE; + preferenceSet = RBM_NONE; + coversRelatedSet = RBM_NONE; + coversFullSet = RBM_NONE; + coversSetsCalculated = false; + found = false; + skipAllocation = false; + coversFullApplied = false; + constAvailableApplied = false; } // ---------------------------------------------------------- From 7cbbc36ecf1d52f681dc23aed955eae6be84a034 Mon Sep 17 00:00:00 2001 From: Jakob Botsch Nielsen Date: Thu, 9 Feb 2023 22:08:32 +0100 Subject: [PATCH 09/10] Run jit-format --- src/coreclr/jit/lsra.cpp | 18 +++++++++--------- src/coreclr/jit/lsra.h | 10 +++++----- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/coreclr/jit/lsra.cpp b/src/coreclr/jit/lsra.cpp index c62b3778cc042..95857620694f4 100644 --- a/src/coreclr/jit/lsra.cpp +++ b/src/coreclr/jit/lsra.cpp @@ -11079,9 +11079,9 @@ void LinearScan::RegisterSelection::reset(Interval* interval, RefPosition* refPo currentInterval = interval; refPosition = refPos; - regType = linearScan->getRegisterType(currentInterval, refPosition); - candidates = refPosition->registerAssignment; - preferences = currentInterval->registerPreferences; + regType = linearScan->getRegisterType(currentInterval, refPosition); + candidates = refPosition->registerAssignment; + preferences = currentInterval->registerPreferences; // This is not actually a preference, it's merely to track the lclVar that this // "specialPutArg" is using. @@ -11184,9 +11184,9 @@ void LinearScan::RegisterSelection::try_CONST_AVAILABLE() regMaskTP newCandidates = candidates & matchingConstants; if (newCandidates != RBM_NONE) { - candidates = newCandidates; + candidates = newCandidates; constAvailableApplied = true; - found = isSingleRegister(newCandidates); + found = isSingleRegister(newCandidates); } } } @@ -11298,8 +11298,8 @@ void LinearScan::RegisterSelection::try_COVERS_FULL() regMaskTP newCandidates = candidates & coversFullSet & freeCandidates; if (newCandidates != RBM_NONE) { - candidates = newCandidates; - found = isSingleRegister(candidates); + candidates = newCandidates; + found = isSingleRegister(candidates); coversFullApplied = true; } } @@ -11319,7 +11319,7 @@ void LinearScan::RegisterSelection::try_BEST_FIT() regMaskTP bestFitSet = RBM_NONE; // If the best score includes COVERS_FULL, pick the one that's killed soonest. // If none cover the full range, the BEST_FIT is the one that's killed later. - bool earliestIsBest = coversFullApplied; + bool earliestIsBest = coversFullApplied; LsraLocation bestFitLocation = earliestIsBest ? MaxLocation : MinLocation; for (regMaskTP bestFitCandidates = candidates; bestFitCandidates != RBM_NONE;) { @@ -11972,7 +11972,7 @@ regMaskTP LinearScan::RegisterSelection::select(Interval* currentInterval, if (!found && (currentInterval->assignedReg != nullptr)) { RegRecord* prevRegRec = currentInterval->assignedReg; - prevRegBit = genRegMask(prevRegRec->regNum); + prevRegBit = genRegMask(prevRegRec->regNum); if ((prevRegRec->assignedInterval == currentInterval) && ((candidates & prevRegBit) != RBM_NONE)) { candidates = prevRegBit; diff --git a/src/coreclr/jit/lsra.h b/src/coreclr/jit/lsra.h index 9a0ebe9ee4dd9..ebe642489cbc5 100644 --- a/src/coreclr/jit/lsra.h +++ b/src/coreclr/jit/lsra.h @@ -1254,7 +1254,7 @@ class LinearScan : public LinearScanInterface Interval* currentInterval = nullptr; RefPosition* refPosition = nullptr; - RegisterType regType = RegisterType::TYP_UNKNOWN; + RegisterType regType = RegisterType::TYP_UNKNOWN; regMaskTP candidates; regMaskTP preferences = RBM_NONE; @@ -1283,10 +1283,10 @@ class LinearScan : public LinearScanInterface regMaskTP preferenceSet; regMaskTP coversRelatedSet; regMaskTP coversFullSet; - bool coversSetsCalculated = false; - bool found = false; - bool skipAllocation = false; - bool coversFullApplied = false; + bool coversSetsCalculated = false; + bool found = false; + bool skipAllocation = false; + bool coversFullApplied = false; bool constAvailableApplied = false; // If the selected register is already assigned to the current internal From ad400c8fe98b675b516eaaac2174c7cb5212429f Mon Sep 17 00:00:00 2001 From: Jakob Botsch Nielsen Date: Thu, 9 Feb 2023 22:11:21 +0100 Subject: [PATCH 10/10] Stop resetting foundRegBit --- src/coreclr/jit/lsra.cpp | 2 +- src/coreclr/jit/lsra.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/coreclr/jit/lsra.cpp b/src/coreclr/jit/lsra.cpp index 95857620694f4..f7133c5127cfc 100644 --- a/src/coreclr/jit/lsra.cpp +++ b/src/coreclr/jit/lsra.cpp @@ -11097,7 +11097,6 @@ void LinearScan::RegisterSelection::reset(Interval* interval, RefPosition* refPo freeCandidates = RBM_NONE; matchingConstants = RBM_NONE; unassignedSet = RBM_NONE; - foundRegBit = RBM_NONE; coversSet = RBM_NONE; preferenceSet = RBM_NONE; coversRelatedSet = RBM_NONE; @@ -12066,6 +12065,7 @@ regMaskTP LinearScan::RegisterSelection::select(Interval* currentInterval, Selection_Done: if (skipAllocation) { + foundRegBit = RBM_NONE; return RBM_NONE; } diff --git a/src/coreclr/jit/lsra.h b/src/coreclr/jit/lsra.h index ebe642489cbc5..9f8cebaf2dd4d 100644 --- a/src/coreclr/jit/lsra.h +++ b/src/coreclr/jit/lsra.h @@ -1269,13 +1269,14 @@ class LinearScan : public LinearScanInterface regMaskTP callerCalleePrefs = RBM_NONE; LsraLocation lastLocation; + regMaskTP foundRegBit; + regMaskTP prevRegBit = RBM_NONE; // These are used in the post-selection updates, and must be set for any selection. regMaskTP freeCandidates; regMaskTP matchingConstants; regMaskTP unassignedSet; - regMaskTP foundRegBit; // Compute the sets for COVERS, OWN_PREFERENCE, COVERS_RELATED, COVERS_FULL and UNASSIGNED together, // as they all require similar computation.