diff --git a/src/coreclr/jit/copyprop.cpp b/src/coreclr/jit/copyprop.cpp index bfc6d04094ab4..68b5651a7cb8e 100644 --- a/src/coreclr/jit/copyprop.cpp +++ b/src/coreclr/jit/copyprop.cpp @@ -312,7 +312,7 @@ void Compiler::optCopyPropPushDef(GenTreeOp* asg, { assert((lclNode->gtFlags & GTF_VAR_DEF) != 0); - // Quirk: do not collect defs from PHIs. Preserves previous behavior. + // TODO-CQ: design better heuristics for propagation and remove this condition. if (!asg->IsPhiDefn()) { ssaDefNum = GetSsaNumForLocalVarDef(lclNode); @@ -480,10 +480,27 @@ void Compiler::optVnCopyProp() // TODO-Cleanup: Move this function from Compiler to this class. m_compiler->optBlockCopyPropPopStacks(block, &m_curSsaName); } + + void PropagateCopies() + { + WalkTree(); + +#ifdef DEBUG + // Verify the definitions remaining are only those we pushed for parameters. + for (LclNumToLiveDefsMap::KeyIterator iter = m_curSsaName.Begin(); !iter.Equal(m_curSsaName.End()); ++iter) + { + unsigned lclNum = iter.Get(); + assert(m_compiler->lvaGetDesc(lclNum)->lvIsParam || (lclNum == m_compiler->info.compThisArg)); + + CopyPropSsaDefStack* defStack = iter.GetValue(); + assert(defStack->Height() == 1); + } +#endif // DEBUG + } }; CopyPropDomTreeVisitor visitor(this); - visitor.WalkTree(); + visitor.PropagateCopies(); // Tracked variable count increases after CopyProp, so don't keep a shorter array around. // Destroy (release) the varset.