diff options
Diffstat (limited to 'src/jit/liveness.cpp')
-rw-r--r-- | src/jit/liveness.cpp | 121 |
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); |