{
currentInterval = interval;
refPosition = refPos;
- score = 0;
- regType = linearScan->getRegisterType(currentInterval, refPosition);
- currentLocation = refPosition->nodeLocation;
- nextRefPos = refPosition->nextRefPosition;
- 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.
rangeEndLocation = refPosition->getRangeEndLocation();
relatedLastLocation = rangeEndLocation;
preferCalleeSave = currentInterval->preferCalleeSave;
- rangeEndRefPosition = nullptr;
lastRefPosition = currentInterval->lastRefPosition;
- lastLocation = MinLocation;
- prevRegRec = currentInterval->assignedReg;
// 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;
+ coversSet = RBM_NONE;
+ preferenceSet = RBM_NONE;
+ coversRelatedSet = RBM_NONE;
+ coversFullSet = RBM_NONE;
+ coversSetsCalculated = false;
+ found = false;
+ skipAllocation = false;
+ coversFullApplied = false;
+ constAvailableApplied = false;
}
// ----------------------------------------------------------
regMaskTP newCandidates = candidates & selectionCandidates;
if (newCandidates != RBM_NONE)
{
- score += selectionScore;
candidates = newCandidates;
return LinearScan::isSingleRegister(candidates);
}
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);
+ }
}
}
return;
}
- if (prevRegRec != nullptr)
+ if (currentInterval->assignedReg != nullptr)
{
found = applySelection(THIS_ASSIGNED, freeCandidates & preferences & prevRegBit);
}
calculateCoversSets();
#endif
- found = applySelection(COVERS_FULL, (coversFullSet & freeCandidates));
+ regMaskTP newCandidates = candidates & coversFullSet & freeCandidates;
+ if (newCandidates != RBM_NONE)
+ {
+ candidates = newCandidates;
+ found = isSingleRegister(candidates);
+ coversFullApplied = true;
+ }
}
// ----------------------------------------------------------
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;)
{
void LinearScan::RegisterSelection::try_IS_PREV_REG()
{
// TODO: We do not check found here.
- if ((prevRegRec != nullptr) && ((score & COVERS_FULL) != 0))
+ if ((currentInterval->assignedReg != nullptr) && coversFullApplied)
{
found = applySingleRegSelection(IS_PREV_REG, prevRegBit);
}
// 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;
// process data-structures
if (RefTypeIsDef(refPosition->refType))
{
+ RefPosition* nextRefPos = refPosition->nextRefPosition;
if (currentInterval->hasConflictingDefUse)
{
linearScan->resolveConflictingDefAndUse(currentInterval, refPosition);
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;
}
// 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))
{
- prevRegBit = genRegMask(prevRegRec->regNum);
+ RegRecord* prevRegRec = currentInterval->assignedReg;
+ prevRegBit = genRegMask(prevRegRec->regNum);
if ((prevRegRec->assignedInterval == currentInterval) && ((candidates & prevRegBit) != RBM_NONE))
{
candidates = prevRegBit;
Selection_Done:
if (skipAllocation)
{
+ foundRegBit = RBM_NONE;
return RBM_NONE;
}
// Did we apply CONST_AVAILABLE heuristics
FORCEINLINE bool isConstAvailable()
{
- return (score & CONST_AVAILABLE) != 0;
+ return constAvailableApplied;
}
private:
ScoreMappingTable* mappingTable = nullptr;
#endif
LinearScan* linearScan = nullptr;
- int score = 0;
Interval* currentInterval = nullptr;
RefPosition* refPosition = nullptr;
- RegisterType regType = RegisterType::TYP_UNKNOWN;
- LsraLocation currentLocation = MinLocation;
- RefPosition* nextRefPos = nullptr;
+ RegisterType regType = RegisterType::TYP_UNKNOWN;
regMaskTP candidates;
regMaskTP preferences = RBM_NONE;
RefPosition* lastRefPosition;
regMaskTP callerCalleePrefs = RBM_NONE;
LsraLocation lastLocation;
- RegRecord* prevRegRec = nullptr;
+
+ regMaskTP foundRegBit;
regMaskTP prevRegBit = RBM_NONE;
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.
regMaskTP preferenceSet;
regMaskTP coversRelatedSet;
regMaskTP coversFullSet;
- bool coversSetsCalculated = false;
- bool found = false;
- bool skipAllocation = false;
- regNumber foundReg = REG_NA;
+ 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
FORCEINLINE bool isAlreadyAssigned()