summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Andreenko <seandree@microsoft.com>2018-11-05 09:03:43 -0800
committerGitHub <noreply@github.com>2018-11-05 09:03:43 -0800
commit0ce06bbbc113ed67970d3af33a5f7292e5180ff5 (patch)
tree91faef923bae094f4dbd67b70018d86f442eac01
parent8780dc610b07d2e2921814e27351c8589b158ba9 (diff)
downloadcoreclr-0ce06bbbc113ed67970d3af33a5f7292e5180ff5.tar.gz
coreclr-0ce06bbbc113ed67970d3af33a5f7292e5180ff5.tar.bz2
coreclr-0ce06bbbc113ed67970d3af33a5f7292e5180ff5.zip
Fix perf regression in master. (#20762)
* Fix comments. We count implict byref argument occurrences for all lclVars not only for promoted. * Fix the regression. Return the old behaiour where both parent and promoted lclVar have updated ref counters. * rename `UpdateImplicitByRefCounter` to `UpdateEarlyRefCountForImplicitByRef` * Fix comment.
-rw-r--r--src/jit/morph.cpp44
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)