summaryrefslogtreecommitdiff
path: root/src/jit/liveness.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/jit/liveness.cpp')
-rw-r--r--src/jit/liveness.cpp121
1 files changed, 54 insertions, 67 deletions
diff --git a/src/jit/liveness.cpp b/src/jit/liveness.cpp
index fe40390cb3..94df0df554 100644
--- a/src/jit/liveness.cpp
+++ b/src/jit/liveness.cpp
@@ -88,7 +88,7 @@ void Compiler::fgMarkUseDef(GenTreeLclVarCommon* tree)
if (promotionType != PROMOTION_TYPE_NONE)
{
- VARSET_TP VARSET_INIT_NOCOPY(bitMask, VarSetOps::MakeEmpty(this));
+ VARSET_TP bitMask(VarSetOps::MakeEmpty(this));
for (unsigned i = varDsc->lvFieldLclStart; i < varDsc->lvFieldLclStart + varDsc->lvFieldCnt; ++i)
{
@@ -189,7 +189,7 @@ void Compiler::fgLocalVarLivenessInit()
/* If we're not optimizing at all, things are simple */
if (opts.MinOpts())
{
- VARSET_TP VARSET_INIT_NOCOPY(allOnes, VarSetOps::MakeFull(this));
+ VARSET_TP allOnes(VarSetOps::MakeFull(this));
for (unsigned i = 0; i < lvaTrackedCount; i++)
{
VarSetOps::Assign(this, lvaVarIntf[i], allOnes);
@@ -431,7 +431,7 @@ void Compiler::fgPerBlockLocalVarLiveness()
unsigned lclNum;
LclVarDsc* varDsc;
- VARSET_TP VARSET_INIT_NOCOPY(liveAll, VarSetOps::MakeEmpty(this));
+ VARSET_TP liveAll(VarSetOps::MakeEmpty(this));
/* We simply make everything live everywhere */
@@ -549,7 +549,7 @@ void Compiler::fgPerBlockLocalVarLiveness()
#ifdef DEBUG
if (verbose)
{
- VARSET_TP VARSET_INIT_NOCOPY(allVars, VarSetOps::Union(this, fgCurUseSet, fgCurDefSet));
+ VARSET_TP allVars(VarSetOps::Union(this, fgCurUseSet, fgCurDefSet));
printf("BB%02u", block->bbNum);
printf(" USE(%d)=", VarSetOps::Count(this, fgCurUseSet));
lvaDispVarSet(fgCurUseSet, allVars);
@@ -712,7 +712,7 @@ void Compiler::fgExtendDbgScopes()
}
#endif // DEBUG
- VARSET_TP VARSET_INIT_NOCOPY(inScope, VarSetOps::MakeEmpty(this));
+ VARSET_TP inScope(VarSetOps::MakeEmpty(this));
// Mark all tracked LocalVars live over their scope - walk the blocks
// keeping track of the current life, and assign it to the blocks.
@@ -762,7 +762,7 @@ void Compiler::fgExtendDbgScopes()
}
#endif // DEBUG
- VARSET_TP VARSET_INIT_NOCOPY(inScope, VarSetOps::MakeEmpty(this));
+ VARSET_TP inScope(VarSetOps::MakeEmpty(this));
compProcessScopesUntil(0, &inScope, &Compiler::fgBeginScopeLife, &Compiler::fgEndScopeLife);
IL_OFFSET lastEndOffs = 0;
@@ -865,7 +865,7 @@ void Compiler::fgExtendDbgLifetimes()
assert(fgFirstBBisScratch());
- VARSET_TP VARSET_INIT_NOCOPY(trackedArgs, VarSetOps::MakeEmpty(this));
+ VARSET_TP trackedArgs(VarSetOps::MakeEmpty(this));
for (unsigned argNum = 0; argNum < info.compArgsCount; argNum++)
{
@@ -892,7 +892,7 @@ void Compiler::fgExtendDbgLifetimes()
}
// Don't unmark struct locals, either.
- VARSET_TP VARSET_INIT_NOCOPY(noUnmarkVars, trackedArgs);
+ VARSET_TP noUnmarkVars(trackedArgs);
for (unsigned i = 0; i < lvaCount; i++)
{
@@ -911,7 +911,7 @@ void Compiler::fgExtendDbgLifetimes()
* garbage until they are initialized by the IL code.
*/
- VARSET_TP VARSET_INIT_NOCOPY(initVars, VarSetOps::MakeEmpty(this)); // Vars which are artificially made alive
+ VARSET_TP initVars(VarSetOps::MakeEmpty(this)); // Vars which are artificially made alive
for (BasicBlock* block = fgFirstBB; block; block = block->bbNext)
{
@@ -1086,7 +1086,7 @@ VARSET_VALRET_TP Compiler::fgGetHandlerLiveVars(BasicBlock* block)
noway_assert(block);
noway_assert(ehBlockHasExnFlowDsc(block));
- VARSET_TP VARSET_INIT_NOCOPY(liveVars, VarSetOps::MakeEmpty(this));
+ VARSET_TP liveVars(VarSetOps::MakeEmpty(this));
EHblkDsc* HBtab = ehGetBlockExnFlowDsc(block);
do
@@ -1200,7 +1200,7 @@ class LiveVarAnalysis
if (m_compiler->ehBlockHasExnFlowDsc(block))
{
- VARSET_TP VARSET_INIT_NOCOPY(liveVars, m_compiler->fgGetHandlerLiveVars(block));
+ const VARSET_TP& liveVars(m_compiler->fgGetHandlerLiveVars(block));
VarSetOps::UnionD(m_compiler, m_liveIn, liveVars);
VarSetOps::UnionD(m_compiler, m_liveOut, liveVars);
@@ -1365,7 +1365,7 @@ bool Compiler::fgMarkIntf(VARSET_VALARG_TP varSet1, VARSET_VALARG_TP varSet2)
if (VarSetOps::IsMember(this, varSet1, refIndex))
{
// Calculate the set of new interference to add
- VARSET_TP VARSET_INIT_NOCOPY(newIntf, VarSetOps::Diff(this, varSet2, lvaVarIntf[refIndex]));
+ VARSET_TP newIntf(VarSetOps::Diff(this, varSet2, lvaVarIntf[refIndex]));
if (!VarSetOps::IsEmpty(this, newIntf))
{
addedIntf = true;
@@ -1377,7 +1377,7 @@ bool Compiler::fgMarkIntf(VARSET_VALARG_TP varSet1, VARSET_VALARG_TP varSet2)
if (VarSetOps::IsMember(this, varSet2, refIndex))
{
// Calculate the set of new interference to add
- VARSET_TP VARSET_INIT_NOCOPY(newIntf, VarSetOps::Diff(this, varSet1, lvaVarIntf[refIndex]));
+ VARSET_TP newIntf(VarSetOps::Diff(this, varSet1, lvaVarIntf[refIndex]));
if (!VarSetOps::IsEmpty(this, newIntf))
{
addedIntf = true;
@@ -1415,7 +1415,7 @@ bool Compiler::fgMarkIntf(VARSET_VALARG_TP varSet)
while (iter.NextElem(&refIndex))
{
// Calculate the set of new interference to add
- VARSET_TP VARSET_INIT_NOCOPY(newIntf, VarSetOps::Diff(this, varSet, lvaVarIntf[refIndex]));
+ VARSET_TP newIntf(VarSetOps::Diff(this, varSet, lvaVarIntf[refIndex]));
if (!VarSetOps::IsEmpty(this, newIntf))
{
addedIntf = true;
@@ -1435,13 +1435,13 @@ bool Compiler::fgMarkIntf(VARSET_VALARG_TP varSet)
VARSET_VALRET_TP Compiler::fgUpdateLiveSet(VARSET_VALARG_TP liveSet, GenTreePtr tree)
{
- VARSET_TP VARSET_INIT(this, newLiveSet, liveSet);
+ VARSET_TP newLiveSet(VarSetOps::MakeCopy(this, liveSet));
assert(fgLocalVarLivenessDone == true);
GenTreePtr lclVarTree = tree; // After the tests below, "lclVarTree" will be the local variable.
if (tree->gtOper == GT_LCL_VAR || tree->gtOper == GT_LCL_FLD || tree->gtOper == GT_REG_VAR ||
(lclVarTree = fgIsIndirOfAddrOfLocal(tree)) != nullptr)
{
- VARSET_TP VARSET_INIT_NOCOPY(varBits, fgGetVarBits(lclVarTree));
+ const VARSET_TP& varBits(fgGetVarBits(lclVarTree));
if (!VarSetOps::IsEmpty(this, varBits))
{
@@ -1512,7 +1512,7 @@ void Compiler::fgComputeLifeCall(VARSET_TP& life, GenTreeCall* call)
if (frameVarDsc->lvTracked)
{
- VARSET_TP VARSET_INIT_NOCOPY(varBit, VarSetOps::MakeSingleton(this, frameVarDsc->lvVarIndex));
+ VARSET_TP varBit(VarSetOps::MakeSingleton(this, frameVarDsc->lvVarIndex));
VarSetOps::AddElemD(this, life, frameVarDsc->lvVarIndex);
@@ -1564,7 +1564,7 @@ void Compiler::fgComputeLifeCall(VARSET_TP& life, GenTreeCall* call)
// Record an interference with the other live variables
//
- VARSET_TP VARSET_INIT_NOCOPY(varBit, VarSetOps::MakeSingleton(this, varIndex));
+ VARSET_TP varBit(VarSetOps::MakeSingleton(this, varIndex));
fgMarkIntf(life, varBit);
}
}
@@ -1626,7 +1626,7 @@ void Compiler::fgComputeLifeCall(VARSET_TP& life, GenTreeCall* call)
// `true` if the local var node corresponds to a dead store; `false`
// otherwise.
//
-bool Compiler::fgComputeLifeLocal(VARSET_TP& life, VARSET_TP& keepAliveVars, GenTree* lclVarNode, GenTree* node)
+bool Compiler::fgComputeLifeLocal(VARSET_TP& life, VARSET_VALARG_TP keepAliveVars, GenTree* lclVarNode, GenTree* node)
{
unsigned lclNum = lclVarNode->gtLclVarCommon.gtLclNum;
@@ -1815,19 +1815,17 @@ bool Compiler::fgComputeLifeLocal(VARSET_TP& life, VARSET_TP& keepAliveVars, Gen
*/
#ifndef LEGACY_BACKEND
-VARSET_VALRET_TP Compiler::fgComputeLife(VARSET_VALARG_TP lifeArg,
- GenTreePtr startNode,
- GenTreePtr endNode,
- VARSET_VALARG_TP volatileVars,
- bool* pStmtInfoDirty DEBUGARG(bool* treeModf))
+void Compiler::fgComputeLife(VARSET_TP& life,
+ GenTreePtr startNode,
+ GenTreePtr endNode,
+ VARSET_VALARG_TP volatileVars,
+ bool* pStmtInfoDirty DEBUGARG(bool* treeModf))
{
GenTreePtr tree;
unsigned lclNum;
- VARSET_TP VARSET_INIT(this, life, lifeArg); // lifeArg is const ref; copy to allow modification.
-
- VARSET_TP VARSET_INIT(this, keepAliveVars, volatileVars);
- VarSetOps::UnionD(this, keepAliveVars, compCurBB->bbScope); // Don't kill vars in scope
+ // Don't kill vars in scope
+ VARSET_TP keepAliveVars(VarSetOps::Union(this, volatileVars, compCurBB->bbScope));
noway_assert(VarSetOps::IsSubset(this, keepAliveVars, life));
noway_assert(compCurStmt->gtOper == GT_STMT);
@@ -1865,17 +1863,12 @@ VARSET_VALRET_TP Compiler::fgComputeLife(VARSET_VALARG_TP lifeArg,
}
}
}
-
- // Return the set of live variables out of this statement
- return life;
}
-VARSET_VALRET_TP Compiler::fgComputeLifeLIR(VARSET_VALARG_TP lifeArg, BasicBlock* block, VARSET_VALARG_TP volatileVars)
+void Compiler::fgComputeLifeLIR(VARSET_TP& life, BasicBlock* block, VARSET_VALARG_TP volatileVars)
{
- VARSET_TP VARSET_INIT(this, life, lifeArg); // lifeArg is const ref; copy to allow modification.
-
- VARSET_TP VARSET_INIT(this, keepAliveVars, volatileVars);
- VarSetOps::UnionD(this, keepAliveVars, block->bbScope); // Don't kill vars in scope
+ // Don't kill volatile vars and vars in scope.
+ VARSET_TP keepAliveVars(VarSetOps::Union(this, volatileVars, block->bbScope));
noway_assert(VarSetOps::IsSubset(this, keepAliveVars, life));
@@ -1883,9 +1876,8 @@ VARSET_VALRET_TP Compiler::fgComputeLifeLIR(VARSET_VALARG_TP lifeArg, BasicBlock
GenTree* firstNonPhiNode = blockRange.FirstNonPhiNode();
if (firstNonPhiNode == nullptr)
{
- return life;
+ return;
}
-
for (GenTree *node = blockRange.LastNode(), *next = nullptr, *end = firstNonPhiNode->gtPrev; node != end;
node = next)
{
@@ -1904,8 +1896,6 @@ VARSET_VALRET_TP Compiler::fgComputeLifeLIR(VARSET_VALARG_TP lifeArg, BasicBlock
}
}
}
-
- return life;
}
#else // LEGACY_BACKEND
@@ -1915,11 +1905,11 @@ VARSET_VALRET_TP Compiler::fgComputeLifeLIR(VARSET_VALARG_TP lifeArg, BasicBlock
#pragma warning(disable : 21000) // Suppress PREFast warning about overly large function
#endif
-VARSET_VALRET_TP Compiler::fgComputeLife(VARSET_VALARG_TP lifeArg,
- GenTreePtr startNode,
- GenTreePtr endNode,
- VARSET_VALARG_TP volatileVars,
- bool* pStmtInfoDirty DEBUGARG(bool* treeModf))
+void Compiler::fgComputeLife(VARSET_TP& life,
+ GenTreePtr startNode,
+ GenTreePtr endNode,
+ VARSET_VALARG_TP volatileVars,
+ bool* pStmtInfoDirty DEBUGARG(bool* treeModf))
{
GenTreePtr tree;
unsigned lclNum;
@@ -1928,15 +1918,12 @@ VARSET_VALRET_TP Compiler::fgComputeLife(VARSET_VALARG_TP lifeArg,
GenTreePtr nextColonExit = 0; // gtQMark->gtOp.gtOp2 while walking the 'else' branch.
// gtQMark->gtOp.gtOp1 while walking the 'then' branch
- VARSET_TP VARSET_INIT(this, life, lifeArg); // lifeArg is const ref; copy to allow modification.
-
// TBD: This used to be an initialization to VARSET_NOT_ACCEPTABLE. Try to figure out what's going on here.
- VARSET_TP VARSET_INIT_NOCOPY(entryLiveSet, VarSetOps::MakeFull(this)); // liveness when we see gtQMark
- VARSET_TP VARSET_INIT_NOCOPY(gtColonLiveSet, VarSetOps::MakeFull(this)); // liveness when we see gtColon
+ VARSET_TP entryLiveSet(VarSetOps::MakeFull(this)); // liveness when we see gtQMark
+ VARSET_TP gtColonLiveSet(VarSetOps::MakeFull(this)); // liveness when we see gtColon
GenTreePtr gtColon = NULL;
- VARSET_TP VARSET_INIT(this, keepAliveVars, volatileVars);
- VarSetOps::UnionD(this, keepAliveVars, compCurBB->bbScope); /* Dont kill vars in scope */
+ VARSET_TP keepAliveVars(VarSetOps::Union(this, volatileVars, compCurBB->bbScope)); /* Dont kill vars in scope */
noway_assert(VarSetOps::Equal(this, VarSetOps::Intersection(this, keepAliveVars, life), keepAliveVars));
noway_assert(compCurStmt->gtOper == GT_STMT);
@@ -2089,7 +2076,7 @@ VARSET_VALRET_TP Compiler::fgComputeLife(VARSET_VALARG_TP lifeArg,
gtReverseCond(tree);
// Remember to also swap the live sets of the two branches.
- VARSET_TP VARSET_INIT_NOCOPY(tmpVS, gtQMark->gtQmark.gtElseLiveSet);
+ const VARSET_TP& tmpVS(gtQMark->gtQmark.gtElseLiveSet);
VarSetOps::AssignNoCopy(this, gtQMark->gtQmark.gtElseLiveSet, gtQMark->gtQmark.gtThenLiveSet);
VarSetOps::AssignNoCopy(this, gtQMark->gtQmark.gtThenLiveSet, tmpVS);
@@ -2217,8 +2204,7 @@ VARSET_VALRET_TP Compiler::fgComputeLife(VARSET_VALARG_TP lifeArg,
noway_assert(nextColonExit &&
(nextColonExit == gtQMark->gtOp.gtOp1 || nextColonExit == gtQMark->gtOp.gtOp2));
- VarSetOps::AssignNoCopy(this, life, fgComputeLife(life, tree, nextColonExit, volatileVars,
- pStmtInfoDirty DEBUGARG(treeModf)));
+ fgComputeLife(life, tree, nextColonExit, volatileVars, pStmtInfoDirty DEBUGARG(treeModf));
/* Continue with exit node (the last node in the enclosing colon branch) */
@@ -2248,8 +2234,6 @@ VARSET_VALRET_TP Compiler::fgComputeLife(VARSET_VALARG_TP lifeArg,
}
/* Return the set of live variables out of this statement */
-
- return life;
}
#ifdef _PREFAST_
@@ -2346,8 +2330,11 @@ bool Compiler::fgTryRemoveDeadLIRStore(LIR::Range& blockRange, GenTree* node, Ge
//
// Returns: true if we should skip the rest of the statement, false if we should continue
-bool Compiler::fgRemoveDeadStore(
- GenTree** pTree, LclVarDsc* varDsc, VARSET_TP life, bool* doAgain, bool* pStmtInfoDirty DEBUGARG(bool* treeModf))
+bool Compiler::fgRemoveDeadStore(GenTree** pTree,
+ LclVarDsc* varDsc,
+ VARSET_VALARG_TP life,
+ bool* doAgain,
+ bool* pStmtInfoDirty DEBUGARG(bool* treeModf))
{
assert(!compRationalIRForm);
@@ -2786,9 +2773,9 @@ void Compiler::fgInterBlockLocalVarLiveness()
*/
BasicBlock* block;
- VARSET_TP VARSET_INIT_NOCOPY(exceptVars, VarSetOps::MakeEmpty(this)); // vars live on entry to a handler
- VARSET_TP VARSET_INIT_NOCOPY(finallyVars, VarSetOps::MakeEmpty(this)); // vars live on exit of a 'finally' block
- VARSET_TP VARSET_INIT_NOCOPY(filterVars, VarSetOps::MakeEmpty(this)); // vars live on exit from a 'filter'
+ VARSET_TP exceptVars(VarSetOps::MakeEmpty(this)); // vars live on entry to a handler
+ VARSET_TP finallyVars(VarSetOps::MakeEmpty(this)); // vars live on exit of a 'finally' block
+ VARSET_TP filterVars(VarSetOps::MakeEmpty(this)); // vars live on exit from a 'filter'
for (block = fgFirstBB; block; block = block->bbNext)
{
@@ -2904,7 +2891,7 @@ void Compiler::fgInterBlockLocalVarLiveness()
/* Remember those vars live on entry to exception handlers */
/* if we are part of a try block */
- VARSET_TP VARSET_INIT_NOCOPY(volatileVars, VarSetOps::MakeEmpty(this));
+ VARSET_TP volatileVars(VarSetOps::MakeEmpty(this));
if (ehBlockHasExnFlowDsc(block))
{
@@ -2916,7 +2903,7 @@ void Compiler::fgInterBlockLocalVarLiveness()
/* Start with the variables live on exit from the block */
- VARSET_TP VARSET_INIT(this, life, block->bbLiveOut);
+ VARSET_TP life(VarSetOps::MakeCopy(this, block->bbLiveOut));
/* Mark any interference we might have at the end of the block */
@@ -2951,8 +2938,8 @@ void Compiler::fgInterBlockLocalVarLiveness()
/* Compute the liveness for each tree node in the statement */
bool stmtInfoDirty = false;
- VarSetOps::AssignNoCopy(this, life, fgComputeLife(life, compCurStmt->gtStmt.gtStmtExpr, nullptr,
- volatileVars, &stmtInfoDirty DEBUGARG(&treeModf)));
+ fgComputeLife(life, compCurStmt->gtStmt.gtStmtExpr, nullptr, volatileVars,
+ &stmtInfoDirty DEBUGARG(&treeModf));
if (stmtInfoDirty)
{
@@ -2975,7 +2962,7 @@ void Compiler::fgInterBlockLocalVarLiveness()
#ifdef LEGACY_BACKEND
unreached();
#else // !LEGACY_BACKEND
- VarSetOps::AssignNoCopy(this, life, fgComputeLifeLIR(life, block, volatileVars));
+ fgComputeLifeLIR(life, block, volatileVars);
#endif // !LEGACY_BACKEND
}
@@ -3016,7 +3003,7 @@ void Compiler::fgInterBlockLocalVarLiveness()
void Compiler::fgDispBBLiveness(BasicBlock* block)
{
- VARSET_TP VARSET_INIT_NOCOPY(allVars, VarSetOps::Union(this, block->bbLiveIn, block->bbLiveOut));
+ VARSET_TP allVars(VarSetOps::Union(this, block->bbLiveIn, block->bbLiveOut));
printf("BB%02u", block->bbNum);
printf(" IN (%d)=", VarSetOps::Count(this, block->bbLiveIn));
lvaDispVarSet(block->bbLiveIn, allVars);