treeStmtLstPtr csdTreeList; // list of matching tree nodes: head
treeStmtLstPtr csdTreeLast; // list of matching tree nodes: tail
+
+ ValueNum defConservativeVN; // if all def occurrences share the same conservative value
+ // number, this will reflect it; otherwise, NoVN.
};
static const size_t s_optCSEhashSize;
/* This is a CSE def */
+ if (desc->csdDefCount == 0)
+ {
+ // This is the first def visited, so copy its conservative VN
+ desc->defConservativeVN = tree->gtVNPair.GetConservative();
+ }
+ else if (tree->gtVNPair.GetConservative() != desc->defConservativeVN)
+ {
+ // This candidate has defs with differing conservative VNs
+ desc->defConservativeVN = ValueNumStore::NoVN;
+ }
+
desc->csdDefCount += 1;
desc->csdDefWtCnt += stmw;
m_addCSEcount++; // Record that we created a new LclVar for use as a CSE temp
m_pCompiler->optCSEcount++;
+ ValueNum defConservativeVN = successfulCandidate->CseDsc()->defConservativeVN;
+
/* Walk all references to this CSE, adding an assignment
to the CSE temp to all defs and changing all refs to
a simple use of the CSE temp.
//
cse = m_pCompiler->gtNewLclvNode(cseLclVarNum, cseLclVarTyp);
cse->gtVNPair = exp->gtVNPair; // assign the proper Value Numbers
+ if (defConservativeVN != ValueNumStore::NoVN)
+ {
+ // All defs of this CSE share the same conservative VN, and we are rewriting this
+ // use to fetch the same value with no reload, so we can safely propagate that
+ // conservative VN to this use. This can help range check elimination later on.
+ cse->gtVNPair.SetConservative(defConservativeVN);
+ }
#ifdef DEBUG
cse->gtDebugFlags |= GTF_DEBUG_VAR_CSE_REF;
#endif // DEBUG