diff options
-rw-r--r-- | src/jit/morph.cpp | 44 |
1 files changed, 34 insertions, 10 deletions
diff --git a/src/jit/morph.cpp b/src/jit/morph.cpp index 1f6de01574..6bd251a3ce 100644 --- a/src/jit/morph.cpp +++ b/src/jit/morph.cpp @@ -17996,7 +17996,7 @@ public: #endif // DEBUG } - // Morph promoted struct fields and count promoted implict byref argument occurrences. + // Morph promoted struct fields and count implict byref argument occurrences. // Also create and push the value produced by the visited node. This is done here // rather than in PostOrderVisit because it makes it easy to handle nodes with an // arbitrary number of operands - just pop values until the value corresponding @@ -18018,16 +18018,17 @@ public: { unsigned lclNum = node->AsLclVarCommon()->GetLclNum(); - if (m_compiler->lvaIsImplicitByRefLocal(lclNum)) + LclVarDsc* varDsc = m_compiler->lvaGetDesc(lclNum); + if (varDsc->lvIsStructField) { - // Keep track of the number of appearances of each promoted implicit - // byref (here during address-exposed analysis); fgMakeOutgoingStructArgCopy - // checks the ref counts for implicit byref params when deciding if it's legal - // to elide certain copies of them. - LclVarDsc* varDsc = m_compiler->lvaGetDesc(lclNum); - JITDUMP("LocalAddressVisitor incrementing ref count from %d to %d for V%02d\n", - varDsc->lvRefCnt(RCS_EARLY), varDsc->lvRefCnt(RCS_EARLY) + 1, lclNum); - varDsc->incLvRefCnt(1, RCS_EARLY); + // Promoted field, increase counter for the parent lclVar. + assert(!m_compiler->lvaIsImplicitByRefLocal(lclNum)); + unsigned parentLclNum = varDsc->lvParentLcl; + UpdateEarlyRefCountForImplicitByRef(parentLclNum); + } + else + { + UpdateEarlyRefCountForImplicitByRef(lclNum); } } @@ -18416,6 +18417,29 @@ private: m_compiler->fgMorphLocalField(node, user); INDEBUG(m_stmtModified |= node->OperIs(GT_LCL_VAR);) } + + //------------------------------------------------------------------------ + // UpdateEarlyRefCountForImplicitByRef: updates the ref count for implicit byref params. + // + // Arguments: + // lclNum - the local number to update the count for. + // + // Notes: + // fgMakeOutgoingStructArgCopy checks the ref counts for implicit byref params when it decides + // if it's legal to elide certain copies of them; + // fgRetypeImplicitByRefArgs checks the ref counts when it decides to undo promotions. + // + void UpdateEarlyRefCountForImplicitByRef(unsigned lclNum) + { + if (!m_compiler->lvaIsImplicitByRefLocal(lclNum)) + { + return; + } + LclVarDsc* varDsc = m_compiler->lvaGetDesc(lclNum); + JITDUMP("LocalAddressVisitor incrementing ref count from %d to %d for V%02d\n", varDsc->lvRefCnt(RCS_EARLY), + varDsc->lvRefCnt(RCS_EARLY) + 1, lclNum); + varDsc->incLvRefCnt(1, RCS_EARLY); + } }; void Compiler::fgAddFieldSeqForZeroOffset(GenTree* op1, FieldSeqNode* fieldSeq) |