summaryrefslogtreecommitdiff
path: root/src/jit/lclvars.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/jit/lclvars.cpp')
-rw-r--r--src/jit/lclvars.cpp184
1 files changed, 43 insertions, 141 deletions
diff --git a/src/jit/lclvars.cpp b/src/jit/lclvars.cpp
index ea1976008a..9e83d11776 100644
--- a/src/jit/lclvars.cpp
+++ b/src/jit/lclvars.cpp
@@ -441,7 +441,6 @@ void Compiler::lvaInitThisPtr(InitVarDscInfo* varDscInfo)
#if FEATURE_MULTIREG_ARGS
varDsc->lvOtherArgReg = REG_NA;
#endif
- varDsc->setPrefReg(varDsc->lvArgReg, this);
varDsc->lvOnFrame = true; // The final home for this incoming register might be our local stack frame
#ifdef DEBUG
@@ -488,7 +487,6 @@ void Compiler::lvaInitRetBuffArg(InitVarDscInfo* varDscInfo)
#if FEATURE_MULTIREG_ARGS
varDsc->lvOtherArgReg = REG_NA;
#endif
- varDsc->setPrefReg(varDsc->lvArgReg, this);
varDsc->lvOnFrame = true; // The final home for this incoming register might be our local stack frame
info.compRetBuffDefStack = 0;
@@ -842,7 +840,6 @@ void Compiler::lvaInitUserArgs(InitVarDscInfo* varDscInfo)
if (secondEightByteType != TYP_UNDEF)
{
varDsc->lvOtherArgReg = genMapRegArgNumToRegNum(secondAllocatedRegArgNum, secondEightByteType);
- varDsc->addPrefReg(genRegMask(varDsc->lvOtherArgReg), this);
}
#else // ARM32 or ARM64
varDsc->lvArgReg = genMapRegArgNumToRegNum(firstAllocatedRegArgNum, TYP_I_IMPL);
@@ -850,7 +847,6 @@ void Compiler::lvaInitUserArgs(InitVarDscInfo* varDscInfo)
if (cSlots == 2)
{
varDsc->lvOtherArgReg = genMapRegArgNumToRegNum(firstAllocatedRegArgNum + 1, TYP_I_IMPL);
- varDsc->addPrefReg(genRegMask(varDsc->lvOtherArgReg), this);
}
#endif // _TARGET_ARM64_
#endif // defined(UNIX_AMD64_ABI)
@@ -861,13 +857,10 @@ void Compiler::lvaInitUserArgs(InitVarDscInfo* varDscInfo)
varDsc->lvArgReg = genMapRegArgNumToRegNum(firstAllocatedRegArgNum, argType);
}
- varDsc->setPrefReg(varDsc->lvArgReg, this);
-
#ifdef _TARGET_ARM_
if (varDsc->TypeGet() == TYP_LONG)
{
varDsc->lvOtherReg = genMapRegArgNumToRegNum(firstAllocatedRegArgNum + 1, TYP_INT);
- varDsc->addPrefReg(genRegMask(varDsc->lvOtherReg), this);
}
#endif // _TARGET_ARM_
@@ -1065,7 +1058,6 @@ void Compiler::lvaInitGenericsCtxt(InitVarDscInfo* varDscInfo)
#if FEATURE_MULTIREG_ARGS
varDsc->lvOtherArgReg = REG_NA;
#endif
- varDsc->setPrefReg(varDsc->lvArgReg, this);
varDsc->lvOnFrame = true; // The final home for this incoming register might be our local stack frame
varDscInfo->intRegArgNum++;
@@ -1132,7 +1124,6 @@ void Compiler::lvaInitVarArgsHandle(InitVarDscInfo* varDscInfo)
#if FEATURE_MULTIREG_ARGS
varDsc->lvOtherArgReg = REG_NA;
#endif
- varDsc->setPrefReg(varDsc->lvArgReg, this);
varDsc->lvOnFrame = true; // The final home for this incoming register might be our local stack frame
#ifdef _TARGET_ARM_
// This has to be spilled right in front of the real arguments and we have
@@ -2011,7 +2002,6 @@ void Compiler::lvaPromoteStructVar(unsigned lclNum, lvaStructPromotionInfo* Stru
{
fieldVarDsc->lvIsRegArg = true;
fieldVarDsc->lvArgReg = varDsc->lvArgReg;
- fieldVarDsc->setPrefReg(varDsc->lvArgReg, this); // Set the preferred register
#if FEATURE_MULTIREG_ARGS && defined(FEATURE_SIMD)
if (varTypeIsSIMD(fieldVarDsc) && !lvaIsImplicitByRefLocal(lclNum))
{
@@ -2024,7 +2014,6 @@ void Compiler::lvaPromoteStructVar(unsigned lclNum, lvaStructPromotionInfo* Stru
}
#endif // FEATURE_MULTIREG_ARGS && defined(FEATURE_SIMD)
- lvaMarkRefsWeight = BB_UNITY_WEIGHT; // incRefCnts can use this compiler global variable
fieldVarDsc->incRefCnts(BB_UNITY_WEIGHT, this,
RCS_EARLY); // increment the ref count for prolog initialization
}
@@ -2989,7 +2978,6 @@ void Compiler::lvaIncRefCnts(GenTree* tree)
* Return positive if dsc2 has a higher ref count
* Return negative if dsc1 has a higher ref count
* Return zero if the ref counts are the same
- * lvPrefReg is only used to break ties
*/
/* static */
@@ -3049,24 +3037,17 @@ int __cdecl Compiler::RefCntCmp(const void* op1, const void* op2)
/* We have equal ref counts and weighted ref counts */
/* Break the tie by: */
- /* Increasing the weight by 2 if we have exactly one bit set in lvPrefReg */
- /* Increasing the weight by 1 if we have more than one bit set in lvPrefReg */
+ /* Increasing the weight by 2 if we are a register arg */
/* Increasing the weight by 0.5 if we are a GC type */
/* Increasing the weight by 0.5 if we were enregistered in the previous pass */
if (weight1)
{
- if (dsc1->lvPrefReg)
+ if (dsc1->lvIsRegArg)
{
- if ((dsc1->lvPrefReg & ~RBM_BYTE_REG_FLAG) && genMaxOneBit((unsigned)dsc1->lvPrefReg))
- {
- weight1 += 2 * BB_UNITY_WEIGHT;
- }
- else
- {
- weight1 += 1 * BB_UNITY_WEIGHT;
- }
+ weight2 += 2 * BB_UNITY_WEIGHT;
}
+
if (varTypeIsGC(dsc1->TypeGet()))
{
weight1 += BB_UNITY_WEIGHT / 2;
@@ -3080,17 +3061,11 @@ int __cdecl Compiler::RefCntCmp(const void* op1, const void* op2)
if (weight2)
{
- if (dsc2->lvPrefReg)
+ if (dsc2->lvIsRegArg)
{
- if ((dsc2->lvPrefReg & ~RBM_BYTE_REG_FLAG) && genMaxOneBit((unsigned)dsc2->lvPrefReg))
- {
- weight2 += 2 * BB_UNITY_WEIGHT;
- }
- else
- {
- weight2 += 1 * BB_UNITY_WEIGHT;
- }
+ weight2 += 2 * BB_UNITY_WEIGHT;
}
+
if (varTypeIsGC(dsc2->TypeGet()))
{
weight2 += BB_UNITY_WEIGHT / 2;
@@ -3170,31 +3145,14 @@ int __cdecl Compiler::WtdRefCntCmp(const void* op1, const void* op2)
}
#endif
- /* Increase the weight by 2 if we have exactly one bit set in lvPrefReg */
- /* Increase the weight by 1 if we have more than one bit set in lvPrefReg */
-
- if (weight1 && dsc1->lvPrefReg)
+ if (weight1 && dsc1->lvIsRegArg)
{
- if ((dsc1->lvPrefReg & ~RBM_BYTE_REG_FLAG) && genMaxOneBit((unsigned)dsc1->lvPrefReg))
- {
- weight1 += 2 * BB_UNITY_WEIGHT;
- }
- else
- {
- weight1 += 1 * BB_UNITY_WEIGHT;
- }
+ weight1 += 2 * BB_UNITY_WEIGHT;
}
- if (weight2 && dsc2->lvPrefReg)
+ if (weight2 && dsc2->lvIsRegArg)
{
- if ((dsc2->lvPrefReg & ~RBM_BYTE_REG_FLAG) && genMaxOneBit((unsigned)dsc2->lvPrefReg))
- {
- weight2 += 2 * BB_UNITY_WEIGHT;
- }
- else
- {
- weight2 += 1 * BB_UNITY_WEIGHT;
- }
+ weight2 += 2 * BB_UNITY_WEIGHT;
}
if (weight2 > weight1)
@@ -3299,13 +3257,6 @@ void Compiler::lvaDumpRefCounts()
gtDispLclVar((unsigned)(lvaRefSorted[lclNum] - lvaTable));
printf(" [%6s]: refCnt = %4u, refCntWtd = %6s", varTypeName(lvaRefSorted[lclNum]->TypeGet()), refCnt,
refCntWtd2str(refCntWtd));
-
- regMaskSmall pref = lvaRefSorted[lclNum]->lvPrefReg;
- if (pref)
- {
- printf(" pref ");
- dspRegMask(pref);
- }
printf("\n");
}
@@ -3670,13 +3621,21 @@ var_types LclVarDsc::lvaArgType()
return type;
}
-/*****************************************************************************
- *
- * This is called by lvaMarkLclRefsCallback() to do variable ref marking
- */
+//------------------------------------------------------------------------
+// lvaMarkLclRefs: increment local var references counts and more
+//
+// Arguments:
+// tree - some node in a tree
+// block - block that the tree node belongs to
+// stmt - stmt that the tree node belongs to
+//
+// Notes:
+// Invoked via the MarkLocalVarsVisitor
-void Compiler::lvaMarkLclRefs(GenTree* tree)
+void Compiler::lvaMarkLclRefs(GenTree* tree, BasicBlock* block, GenTreeStmt* stmt)
{
+ const BasicBlock::weight_t weight = block->getBBWeight(this);
+
/* Is this a call to unmanaged code ? */
if (tree->gtOper == GT_CALL && tree->gtFlags & GTF_CALL_UNMANAGED)
{
@@ -3691,8 +3650,8 @@ void Compiler::lvaMarkLclRefs(GenTree* tree)
LclVarDsc* varDsc = lvaTable + lclNum;
/* Increment the ref counts twice */
- varDsc->incRefCnts(lvaMarkRefsWeight, this);
- varDsc->incRefCnts(lvaMarkRefsWeight, this);
+ varDsc->incRefCnts(weight, this);
+ varDsc->incRefCnts(weight, this);
}
}
@@ -3703,25 +3662,6 @@ void Compiler::lvaMarkLclRefs(GenTree* tree)
GenTree* op1 = tree->gtOp.gtOp1;
GenTree* op2 = tree->gtOp.gtOp2;
- /* Set target register for RHS local if assignment is of a "small" type */
-
- if (varTypeIsByte(tree->gtType))
- {
- unsigned lclNum;
- LclVarDsc* varDsc = nullptr;
-
- if (op2->gtOper == GT_LCL_VAR)
- {
- lclNum = op2->gtLclVarCommon.gtLclNum;
- noway_assert(lclNum < lvaCount);
- varDsc = &lvaTable[lclNum];
- }
-#if CPU_HAS_BYTE_REGS
- if (varDsc)
- varDsc->addPrefReg(RBM_BYTE_REG_FLAG, this);
-#endif
- }
-
#if OPT_BOOL_OPS
/* Is this an assignment to a local variable? */
@@ -3774,27 +3714,6 @@ void Compiler::lvaMarkLclRefs(GenTree* tree)
#endif
}
-#ifdef _TARGET_XARCH_
- /* Special case: integer shift node by a variable amount */
-
- if (tree->OperIsShiftOrRotate())
- {
- if (tree->gtType == TYP_INT)
- {
- GenTree* op2 = tree->gtOp.gtOp2;
-
- if (op2->gtOper == GT_LCL_VAR)
- {
- unsigned lclNum = op2->gtLclVarCommon.gtLclNum;
- assert(lclNum < lvaCount);
- lvaTable[lclNum].setPrefReg(REG_ECX, this);
- }
- }
-
- return;
- }
-#endif
-
if ((tree->gtOper != GT_LCL_VAR) && (tree->gtOper != GT_LCL_FLD))
{
return;
@@ -3810,7 +3729,7 @@ void Compiler::lvaMarkLclRefs(GenTree* tree)
/* Increment the reference counts */
- varDsc->incRefCnts(lvaMarkRefsWeight, this);
+ varDsc->incRefCnts(weight, this);
if (lvaVarAddrExposed(lclNum))
{
@@ -3828,7 +3747,7 @@ void Compiler::lvaMarkLclRefs(GenTree* tree)
}
#if ASSERTION_PROP
- if (fgDomsComputed && IsDominatedByExceptionalEntry(lvaMarkRefsCurBlock))
+ if (fgDomsComputed && IsDominatedByExceptionalEntry(block))
{
SetVolatileHint(varDsc);
}
@@ -3857,7 +3776,7 @@ void Compiler::lvaMarkLclRefs(GenTree* tree)
else
{
varDsc->lvSingleDef = true;
- varDsc->lvDefStmt = lvaMarkRefsCurStmt;
+ varDsc->lvDefStmt = stmt;
}
}
else // otherwise this is a ref of our variable
@@ -3867,7 +3786,7 @@ void Compiler::lvaMarkLclRefs(GenTree* tree)
// Lazy initialization
BlockSetOps::AssignNoCopy(this, varDsc->lvRefBlks, BlockSetOps::MakeEmpty(this));
}
- BlockSetOps::AddElemD(this, varDsc->lvRefBlks, lvaMarkRefsCurBlock->bbNum);
+ BlockSetOps::AddElemD(this, varDsc->lvRefBlks, block->bbNum);
}
}
#endif // ASSERTION_PROP
@@ -3947,53 +3866,36 @@ void Compiler::lvaMarkLocalVars(BasicBlock* block)
{
class MarkLocalVarsVisitor final : public GenTreeVisitor<MarkLocalVarsVisitor>
{
+ private:
+ BasicBlock* m_block;
+ GenTreeStmt* m_stmt;
+
public:
enum
{
DoPreOrder = true,
};
- MarkLocalVarsVisitor(Compiler* compiler) : GenTreeVisitor<MarkLocalVarsVisitor>(compiler)
+ MarkLocalVarsVisitor(Compiler* compiler, BasicBlock* block, GenTreeStmt* stmt)
+ : GenTreeVisitor<MarkLocalVarsVisitor>(compiler), m_block(block), m_stmt(stmt)
{
}
Compiler::fgWalkResult PreOrderVisit(GenTree** use, GenTree* user)
{
- m_compiler->lvaMarkLclRefs(*use);
+ m_compiler->lvaMarkLclRefs(*use, m_block, m_stmt);
return WALK_CONTINUE;
}
};
-#if ASSERTION_PROP
- lvaMarkRefsCurBlock = block;
-#endif
- lvaMarkRefsWeight = block->getBBWeight(this);
-
-#ifdef DEBUG
- if (verbose)
- {
- printf("\n*** marking local variables in block BB%02u (weight=%s)\n", block->bbNum,
- refCntWtd2str(lvaMarkRefsWeight));
- }
-#endif
+ JITDUMP("\n*** marking local variables in block BB%02u (weight=%s)\n", block->bbNum,
+ refCntWtd2str(block->getBBWeight(this)));
- MarkLocalVarsVisitor visitor(this);
- for (GenTree* tree = block->FirstNonPhiDef(); tree; tree = tree->gtNext)
+ for (GenTreeStmt* stmt = block->FirstNonPhiDef(); stmt != nullptr; stmt = stmt->getNextStmt())
{
- assert(tree->gtOper == GT_STMT);
-
-#if ASSERTION_PROP
- lvaMarkRefsCurStmt = tree;
-#endif
-
-#ifdef DEBUG
- if (verbose)
- {
- gtDispTree(tree);
- }
-#endif
-
- visitor.WalkTree(&tree->gtStmt.gtStmtExpr, nullptr);
+ MarkLocalVarsVisitor visitor(this, block, stmt);
+ DISPTREE(stmt);
+ visitor.WalkTree(&stmt->gtStmtExpr, nullptr);
}
}