Skip to content

Commit

Permalink
Optimize buildIntervals()
Browse files Browse the repository at this point in the history
  • Loading branch information
kunalspathak committed Apr 26, 2023
1 parent bf7b68d commit 24dd4c8
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 19 deletions.
2 changes: 2 additions & 0 deletions src/coreclr/jit/lsra.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1298,7 +1298,9 @@ PhaseStatus LinearScan::doLinearScan()
#ifdef TARGET_ARM64
nextConsecutiveRefPositionMap = nullptr;
#endif

buildIntervals();

DBEXEC(VERBOSE, TupleStyleDump(LSRA_DUMP_REFPOS));
compiler->EndPhase(PHASE_LINEAR_SCAN_BUILD);

Expand Down
4 changes: 3 additions & 1 deletion src/coreclr/jit/lsra.h
Original file line number Diff line number Diff line change
Expand Up @@ -642,7 +642,9 @@ class LinearScan : public LinearScanInterface
virtual void recordVarLocationsAtStartOfBB(BasicBlock* bb);

// This does the dataflow analysis and builds the intervals
void buildIntervals();
template <bool localVarsEnregistered>
void buildIntervals();
void buildIntervals();

// This is where the actual assignment is done
#ifdef TARGET_ARM64
Expand Down
61 changes: 43 additions & 18 deletions src/coreclr/jit/lsrabuild.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2131,6 +2131,23 @@ void LinearScan::updateRegStateForArg(LclVarDsc* argDsc)
// which we will do register allocation.
//
void LinearScan::buildIntervals()
{
if (enregisterLocalVars)
{
buildIntervals<true>();
}
else
{
buildIntervals<false>();
}
}

//------------------------------------------------------------------------
// buildIntervals: The main entry point for building the data structures over
// which we will do register allocation.
//
template <bool localVarsEnregistered>
void LinearScan::buildIntervals()
{
BasicBlock* block;

Expand Down Expand Up @@ -2331,7 +2348,7 @@ void LinearScan::buildIntervals()
blockInfo[block->bbNum].predBBNum = predBlock->bbNum;
}

if (enregisterLocalVars)
if (localVarsEnregistered)
{
VarSetOps::AssignNoCopy(compiler, currentLiveVars,
VarSetOps::Intersection(compiler, registerCandidateVars, block->bbLiveIn));
Expand Down Expand Up @@ -2464,32 +2481,29 @@ void LinearScan::buildIntervals()
currentLoc += 2;
}

#if FEATURE_PARTIAL_SIMD_CALLEE_SAVE
// At the end of each block, create upperVectorRestores for any largeVectorVars that may be
// partiallySpilled (during the build phase all intervals will be marked isPartiallySpilled if
// they *may) be partially spilled at any point.
if (enregisterLocalVars)
if (localVarsEnregistered)
{
#if FEATURE_PARTIAL_SIMD_CALLEE_SAVE
// At the end of each block, create upperVectorRestores for any largeVectorVars that may be
// partiallySpilled (during the build phase all intervals will be marked isPartiallySpilled if
// they *may) be partially spilled at any point.
VarSetOps::Iter largeVectorVarsIter(compiler, largeVectorVars);
unsigned largeVectorVarIndex = 0;
while (largeVectorVarsIter.NextElem(&largeVectorVarIndex))
{
Interval* lclVarInterval = getIntervalForLocalVar(largeVectorVarIndex);
buildUpperVectorRestoreRefPosition(lclVarInterval, currentLoc, nullptr, false);
}
}
#endif // FEATURE_PARTIAL_SIMD_CALLEE_SAVE

// Note: the visited set is cleared in LinearScan::doLinearScan()
markBlockVisited(block);
if (!defList.IsEmpty())
{
INDEBUG(dumpDefList());
assert(!"Expected empty defList at end of block");
}
// Note: the visited set is cleared in LinearScan::doLinearScan()
markBlockVisited(block);
if (!defList.IsEmpty())
{
INDEBUG(dumpDefList());
assert(!"Expected empty defList at end of block");
}

if (enregisterLocalVars)
{
// Insert exposed uses for a lclVar that is live-out of 'block' but not live-in to the
// next block, or any unvisited successors.
// This will address lclVars that are live on a backedge, as well as those that are kept
Expand Down Expand Up @@ -2557,7 +2571,8 @@ void LinearScan::buildIntervals()
LclVarDsc* const varDsc = compiler->lvaGetDesc(varNum);
assert(isCandidateVar(varDsc));
RefPosition* const lastRP = getIntervalForLocalVar(varIndex)->lastRefPosition;
// We should be able to assert that lastRP is non-null if it is live-out, but sometimes liveness lies.
// We should be able to assert that lastRP is non-null if it is live-out, but sometimes liveness
// lies.
if ((lastRP != nullptr) && (lastRP->bbNum == block->bbNum))
{
lastRP->lastUse = false;
Expand All @@ -2577,11 +2592,21 @@ void LinearScan::buildIntervals()
}
#endif // DEBUG
}
else
{
// Note: the visited set is cleared in LinearScan::doLinearScan()
markBlockVisited(block);
if (!defList.IsEmpty())
{
INDEBUG(dumpDefList());
assert(!"Expected empty defList at end of block");
}
}

prevBlock = block;
}

if (enregisterLocalVars)
if (localVarsEnregistered)
{
if (compiler->lvaKeepAliveAndReportThis())
{
Expand Down

0 comments on commit 24dd4c8

Please sign in to comment.