@@ -551,7 +551,8 @@ void SsaBuilder::InsertPhi(BasicBlock* block, unsigned lclNum)
551551}
552552
553553// ------------------------------------------------------------------------
554- // AddPhiArg: Add a new GT_PHI_ARG node to an existing GT_PHI node.
554+ // AddPhiArg: Ensure an existing GT_PHI node contains an appropriate PhiArg
555+ // for an ssa def arriving via pred
555556//
556557// Arguments:
557558// block - The block that contains the statement
@@ -563,14 +564,32 @@ void SsaBuilder::InsertPhi(BasicBlock* block, unsigned lclNum)
563564void SsaBuilder::AddPhiArg (
564565 BasicBlock* block, Statement* stmt, GenTreePhi* phi, unsigned lclNum, unsigned ssaNum, BasicBlock* pred)
565566{
566- #ifdef DEBUG
567- // Make sure it isn't already present: we should only add each definition once.
567+ // If there's already a phi arg for this pred, it had better have
568+ // matching ssaNum, unless this block is a handler entry.
569+ //
570+ const bool isHandlerEntry = m_pCompiler->bbIsHandlerBeg (block);
571+
568572 for (GenTreePhi::Use& use : phi->Uses ())
569573 {
570- assert (use.GetNode ()->AsPhiArg ()->GetSsaNum () != ssaNum);
574+ GenTreePhiArg* const phiArg = use.GetNode ()->AsPhiArg ();
575+
576+ if (phiArg->gtPredBB == pred)
577+ {
578+ if (phiArg->GetSsaNum () == ssaNum)
579+ {
580+ // We already have this (pred, ssaNum) phiArg
581+ return ;
582+ }
583+
584+ // Add another ssaNum for this pred?
585+ // Should only be possible at handler entries.
586+ //
587+ noway_assert (isHandlerEntry);
588+ }
571589 }
572- #endif // DEBUG
573590
591+ // Didn't find a match, add a new phi arg
592+ //
574593 var_types type = m_pCompiler->lvaGetDesc (lclNum)->TypeGet ();
575594
576595 GenTree* phiArg = new (m_pCompiler, GT_PHI_ARG) GenTreePhiArg (type, lclNum, ssaNum, pred);
@@ -1186,29 +1205,12 @@ void SsaBuilder::AddPhiArgsToSuccessors(BasicBlock* block)
11861205 break ;
11871206 }
11881207
1189- GenTree* tree = stmt->GetRootNode ();
1190- GenTreePhi* phi = tree->gtGetOp2 ()->AsPhi ();
1191-
1192- unsigned lclNum = tree->AsOp ()->gtOp1 ->AsLclVar ()->GetLclNum ();
1193- unsigned ssaNum = m_renameStack.Top (lclNum);
1194- // Search the arglist for an existing definition for ssaNum.
1195- // (Can we assert that its the head of the list? This should only happen when we add
1196- // during renaming for a definition that occurs within a try, and then that's the last
1197- // value of the var within that basic block.)
1208+ GenTree* tree = stmt->GetRootNode ();
1209+ GenTreePhi* phi = tree->gtGetOp2 ()->AsPhi ();
1210+ unsigned lclNum = tree->AsOp ()->gtOp1 ->AsLclVar ()->GetLclNum ();
1211+ unsigned ssaNum = m_renameStack.Top (lclNum);
11981212
1199- bool found = false ;
1200- for (GenTreePhi::Use& use : phi->Uses ())
1201- {
1202- if (use.GetNode ()->AsPhiArg ()->GetSsaNum () == ssaNum)
1203- {
1204- found = true ;
1205- break ;
1206- }
1207- }
1208- if (!found)
1209- {
1210- AddPhiArg (succ, stmt, phi, lclNum, ssaNum, block);
1211- }
1213+ AddPhiArg (succ, stmt, phi, lclNum, ssaNum, block);
12121214 }
12131215
12141216 // Now handle memory.
@@ -1333,24 +1335,10 @@ void SsaBuilder::AddPhiArgsToSuccessors(BasicBlock* block)
13331335 continue ;
13341336 }
13351337
1336- GenTreePhi* phi = tree->gtGetOp2 ()->AsPhi ();
1337-
1338- unsigned ssaNum = m_renameStack.Top (lclNum);
1338+ GenTreePhi* phi = tree->gtGetOp2 ()->AsPhi ();
1339+ unsigned ssaNum = m_renameStack.Top (lclNum);
13391340
1340- // See if this ssaNum is already an arg to the phi.
1341- bool alreadyArg = false ;
1342- for (GenTreePhi::Use& use : phi->Uses ())
1343- {
1344- if (use.GetNode ()->AsPhiArg ()->GetSsaNum () == ssaNum)
1345- {
1346- alreadyArg = true ;
1347- break ;
1348- }
1349- }
1350- if (!alreadyArg)
1351- {
1352- AddPhiArg (handlerStart, stmt, phi, lclNum, ssaNum, block);
1353- }
1341+ AddPhiArg (handlerStart, stmt, phi, lclNum, ssaNum, block);
13541342 }
13551343
13561344 // Now handle memory.
0 commit comments