Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DO-NOT-MERGE: Lsra heuristic reordering #51626

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
jit format
  • Loading branch information
kunalspathak committed Apr 21, 2021
commit cf54583145d969327bb5c7b6ab20741e6b588c38
1 change: 0 additions & 1 deletion src/coreclr/jit/jitconfigvalues.h
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,6 @@ CONFIG_INTEGER(EnableIncompleteISAClass, W("EnableIncompleteISAClass"), 0) // En
// intrinsic classes
CONFIG_STRING(JitLsraOrdering, W("JitLsraOrdering")) // LSRA heuristics ordering


#endif // defined(DEBUG)

#if FEATURE_LOOP_ALIGN
Expand Down
39 changes: 18 additions & 21 deletions src/coreclr/jit/lsra.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -618,8 +618,7 @@ LinearScanInterface* getLinearScanAllocator(Compiler* comp)
// during Lowering, including (in DEBUG) getting the stress environment variables,
// as they may affect the block ordering.


//LinearScan::RegisterSelection* regSelector;
// LinearScan::RegisterSelection* regSelector;

LinearScan::LinearScan(Compiler* theCompiler)
: compiler(theCompiler)
Expand Down Expand Up @@ -2744,7 +2743,8 @@ bool LinearScan::isMatchingConstant(RegRecord* physRegRecord, RefPosition* refPo
//
regNumber LinearScan::allocateReg(Interval* currentInterval, RefPosition* refPosition)
{
regMaskTP foundRegBit = regSelector->select(currentInterval, refPosition/*, RegSelectionOrder, REGSELECT_HEURISTIC_COUNT*/);
regMaskTP foundRegBit =
regSelector->select(currentInterval, refPosition /*, RegSelectionOrder, REGSELECT_HEURISTIC_COUNT*/);
if (foundRegBit == REG_NA)
{
return REG_NA;
Expand All @@ -2753,7 +2753,8 @@ regNumber LinearScan::allocateReg(Interval* currentInterval, RefPosition* refPos
regNumber foundReg = genRegNumFromMask(foundRegBit);
RegRecord* availablePhysRegRecord = getRegisterRecord(foundReg);
Interval* assignedInterval = availablePhysRegRecord->assignedInterval;
if ((assignedInterval != currentInterval) && isAssigned(availablePhysRegRecord ARM_ARG(getRegisterType(currentInterval, refPosition))))
if ((assignedInterval != currentInterval) &&
isAssigned(availablePhysRegRecord ARM_ARG(getRegisterType(currentInterval, refPosition))))
{
if (regSelector->isSpilling())
{
Expand Down Expand Up @@ -8566,7 +8567,6 @@ void LinearScan::updateLsraStat(LsraStat stat, unsigned bbNum)
++(blockInfo[bbNum].stats[(unsigned)stat]);
}


// ----------------------------------------------------------
// getLsraStat: Get lsra stat corresponding to the RegisterScore stat
//
Expand Down Expand Up @@ -10777,7 +10777,6 @@ void LinearScan::verifyResolutionMove(GenTree* resolutionMove, LsraLocation curr
}
#endif // DEBUG


LinearScan::RegisterSelection::RegisterSelection(LinearScan* linearScan)
{
this->linearScan = linearScan;
Expand Down Expand Up @@ -10820,7 +10819,7 @@ void LinearScan::RegisterSelection::reset(Interval* interval, RefPosition* refPo
{
currentInterval = interval;
refPosition = refPos;
score = 0; //TODO:Kpathak - why is this used?
score = 0; // TODO:Kpathak - why is this used?

regType = linearScan->getRegisterType(currentInterval, refPosition);
currentLocation = refPosition->nodeLocation;
Expand All @@ -10830,7 +10829,7 @@ void LinearScan::RegisterSelection::reset(Interval* interval, RefPosition* refPo

// This is not actually a preference, it's merely to track the lclVar that this
// "specialPutArg" is using.
relatedInterval = currentInterval->isSpecialPutArg ? nullptr : currentInterval->relatedInterval;
relatedInterval = currentInterval->isSpecialPutArg ? nullptr : currentInterval->relatedInterval;
relatedPreferences = (relatedInterval == nullptr) ? RBM_NONE : relatedInterval->getCurrentPreferences();

rangeEndLocation = refPosition->getRangeEndLocation();
Expand All @@ -10851,13 +10850,12 @@ void LinearScan::RegisterSelection::reset(Interval* interval, RefPosition* refPo
coversRelatedSet = RBM_NONE;
coversFullSet = RBM_NONE;

foundRegBit = REG_NA;
found = false;
skipAllocation = false;
foundRegBit = REG_NA;
found = false;
skipAllocation = false;
coversSetsCalculated = false;
}


regMaskTP LinearScan::RegisterSelection::select(Interval* currentInterval, RefPosition* refPosition)
{
reset(currentInterval, refPosition);
Expand Down Expand Up @@ -11017,8 +11015,9 @@ regMaskTP LinearScan::RegisterSelection::select(Interval* currentInterval, RefPo
if (currentInterval->isWriteThru)
{
// We'll only prefer a callee-save register if it's already been used.
regMaskTP unusedCalleeSaves = calleeSaveCandidates & ~(linearScan->compiler->codeGen->regSet.rsGetModifiedRegsMask());
callerCalleePrefs = calleeSaveCandidates & ~unusedCalleeSaves;
regMaskTP unusedCalleeSaves =
calleeSaveCandidates & ~(linearScan->compiler->codeGen->regSet.rsGetModifiedRegsMask());
callerCalleePrefs = calleeSaveCandidates & ~unusedCalleeSaves;
preferences &= ~unusedCalleeSaves;
}
else
Expand Down Expand Up @@ -11134,7 +11133,7 @@ regMaskTP LinearScan::RegisterSelection::select(Interval* currentInterval, RefPo
if (currentInterval->isConstant && RefTypeIsDef(refPosition->refType))
{
matchingConstants = linearScan->getMatchingConstants(candidates, currentInterval, refPosition);
}
}
}

for (int orderId = 0; orderId < REGSELECT_HEURISTIC_COUNT /*heuristicsCount*/; orderId++)
Expand All @@ -11145,7 +11144,7 @@ regMaskTP LinearScan::RegisterSelection::select(Interval* currentInterval, RefPo
}

RegisterScore heuristicToApply = RegSelectionOrder[orderId];
HeuristicFn fn;
HeuristicFn fn;
// fn = mappingTable[heuristics[orderId]];
// (this->*fn)();

Expand Down Expand Up @@ -11240,7 +11239,6 @@ void LinearScan::RegisterSelection::tryThisAssigned()
return;
}


if (prevRegRec != nullptr)
{
found = applySelection(THIS_ASSIGNED, freeCandidates & preferences & prevRegBit);
Expand Down Expand Up @@ -11360,8 +11358,7 @@ void LinearScan::RegisterSelection::tryBestFit()
// are "local last uses" of the Interval - otherwise the liveRange would interfere with the reg.
// TODO: This duplicates code in an earlier loop, and is basically here to duplicate previous
// behavior; see if we can avoid this.
if (nextPhysRefLocation == rangeEndLocation &&
rangeEndRefPosition->isFixedRefOfReg(bestFitCandidateRegNum))
if (nextPhysRefLocation == rangeEndLocation && rangeEndRefPosition->isFixedRefOfReg(bestFitCandidateRegNum))
{
INDEBUG(linearScan->dumpLsraAllocationEvent(LSRA_EVENT_INCREMENT_RANGE_END, currentInterval));
nextPhysRefLocation++;
Expand Down Expand Up @@ -11405,7 +11402,7 @@ void LinearScan::RegisterSelection::tryBestFit()
// Oddly, the previous heuristics only considered this if it covered the range.
void LinearScan::RegisterSelection::tryIsPrevReg()
{
//TODO: We do not check found here.
// TODO: We do not check found here.
if ((prevRegRec != nullptr) && ((score & COVERS_FULL) != 0))
{
found = applySingleRegSelection(IS_PREV_REG, prevRegBit);
Expand All @@ -11417,7 +11414,7 @@ void LinearScan::RegisterSelection::tryRegOrder()
{
assert(!found);

if (freeCandidates == RBM_NONE) // TODO: Kpathak, is this needed?
if (freeCandidates == RBM_NONE) // TODO: Kpathak, is this needed?
{
return;
}
Expand Down
57 changes: 24 additions & 33 deletions src/coreclr/jit/lsra.h
Original file line number Diff line number Diff line change
Expand Up @@ -1125,7 +1125,7 @@ class LinearScan : public LinearScanInterface
****************************************************************************/
RegisterType getRegisterType(Interval* currentInterval, RefPosition* refPosition);
regNumber allocateReg(Interval* current, RefPosition* refPosition);
regNumber allocateReg(Interval* current, RefPosition* refPosition, int unused);
regNumber allocateReg(Interval* current, RefPosition* refPosition, int unused);
regNumber assignCopyReg(RefPosition* refPosition);

bool isMatchingConstant(RegRecord* physRegRecord, RefPosition* refPosition);
Expand Down Expand Up @@ -1207,7 +1207,6 @@ class LinearScan : public LinearScanInterface
}
};


public:
class RegisterSelection;

Expand Down Expand Up @@ -1248,15 +1247,14 @@ class LinearScan : public LinearScanInterface
typedef void (LinearScan::RegisterSelection::*HeuristicFn)();
typedef JitHashTable<RegisterScore, JitSmallPrimitiveKeyFuncs<RegisterScore>, HeuristicFn> ScoreMappingTable;

#define REGSELECT_HEURISTIC_COUNT 17

#define REGSELECT_HEURISTIC_COUNT 17

class RegisterSelection
{
public:
public:
RegisterSelection(LinearScan* linearScan);

private:
private:
RegisterScore DefaultOrder[REGSELECT_HEURISTIC_COUNT] =
{FREE, CONST_AVAILABLE, THIS_ASSIGNED, COVERS,
OWN_PREFERENCE, COVERS_RELATED, RELATED_PREFERENCE, CALLER_CALLEE,
Expand All @@ -1266,34 +1264,32 @@ class LinearScan : public LinearScanInterface

RegisterScore RegSelectionOrder[REGSELECT_HEURISTIC_COUNT] = {0};

//TODO: Add document for each field
ScoreMappingTable* mappingTable = nullptr;
// TODO: Add document for each field
ScoreMappingTable* mappingTable = nullptr;

int score = 0;
int score = 0;

Interval* currentInterval = nullptr;
RefPosition* refPosition = nullptr;


RegisterType regType = RegisterType::TYP_UNKNOWN;
LsraLocation currentLocation = MinLocation;
RefPosition* nextRefPos = nullptr;

regMaskTP candidates;
regMaskTP preferences = RBM_NONE;

regMaskTP candidates;
regMaskTP preferences = RBM_NONE;

Interval* relatedInterval = nullptr;
Interval* relatedInterval = nullptr;

regMaskTP relatedPreferences = RBM_NONE;
LsraLocation rangeEndLocation;
LsraLocation relatedLastLocation; // TODO:kpathak - need to see why this is not used after refactor?
bool preferCalleeSave = false;
RefPosition* rangeEndRefPosition;
bool preferCalleeSave = false;
RefPosition* rangeEndRefPosition;
RefPosition* lastRefPosition;
regMaskTP callerCalleePrefs = RBM_NONE;
regMaskTP callerCalleePrefs = RBM_NONE;
LsraLocation lastLocation;
RegRecord* prevRegRec = nullptr;
RegRecord* prevRegRec = nullptr;

regMaskTP prevRegBit = RBM_NONE;

Expand All @@ -1303,29 +1299,26 @@ class LinearScan : public LinearScanInterface
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 coversSet;
regMaskTP preferenceSet;
regMaskTP coversRelatedSet;
regMaskTP coversFullSet;
bool coversSetsCalculated = false;
bool found = false;
bool skipAllocation = false;
regNumber foundReg = REG_NA;
bool found = false;
bool skipAllocation = false;
regNumber foundReg = REG_NA;



// If the selected register is already assigned to the current internal
FORCEINLINE bool isAlreadyAssigned()
{
assert(found && isSingleRegister(candidates));
return (prevRegBit & preferences) == foundRegBit;
}

bool applySelection(int selectionScore, regMaskTP selectionCandidates);
bool applySingleRegSelection(int selectionScore, regMaskTP selectionCandidate);
bool applySelection(int selectionScore, regMaskTP selectionCandidates);
bool applySingleRegSelection(int selectionScore, regMaskTP selectionCandidate);
FORCEINLINE void calculateSets();

FORCEINLINE void reset(Interval* interval, RefPosition* refPosition);
Expand All @@ -1350,14 +1343,14 @@ class LinearScan : public LinearScanInterface
public:
LinearScan* linearScan = nullptr;

//TODO: Add a note that this is not a perfect method and it changes state of currentInterval or refPosition. In future, need
// TODO: Add a note that this is not a perfect method and it changes state of currentInterval or refPosition. In
// future, need
// to improve it.
regMaskTP select(Interval* currentInterval,
RefPosition* refPosition/*,
regMaskTP select(Interval* currentInterval, RefPosition* refPosition /*,
RegisterScore heuristics[],
int heuristicsCount*/);

//TODO: Mark all methods as inline
// TODO: Mark all methods as inline

// If the register is from unassigned set such that it was not already
// assigned to the current interval
Expand Down Expand Up @@ -1782,7 +1775,6 @@ class LinearScan : public LinearScanInterface
LsraLocation nextFixedRef[REG_COUNT];
void updateNextFixedRef(RegRecord* regRecord, RefPosition* nextRefPosition);


LsraLocation nextIntervalRef[REG_COUNT];

float spillCost[REG_COUNT];
Expand Down Expand Up @@ -1986,7 +1978,7 @@ class LinearScan : public LinearScanInterface
}

template <typename RSH>
bool RegSelectionHeuristics(RSH(&x) [])
bool RegSelectionHeuristics(RSH (&x)[])
{
for (int i = 0; i < 10; i++)
{
Expand Down Expand Up @@ -2556,7 +2548,6 @@ class RefPosition
#endif // DEBUG
};


#ifdef DEBUG
void dumpRegMask(regMaskTP regs);
#endif // DEBUG
Expand Down