@@ -772,9 +772,13 @@ void Compiler::fgLiveVarAnalysis()
772772// keepAliveVars - Tracked locals that must be kept alive everywhere in the block
773773// call - The call node in question.
774774//
775- void Compiler::fgComputeLifeCall (VARSET_TP& life, VARSET_VALARG_TP keepAliveVars, GenTreeCall* call)
775+ // Returns:
776+ // local defined by the call, if any (eg retbuf)
777+ //
778+ GenTreeLclVarCommon* Compiler::fgComputeLifeCall (VARSET_TP& life, VARSET_VALARG_TP keepAliveVars, GenTreeCall* call)
776779{
777780 assert (call != nullptr );
781+ GenTreeLclVarCommon* definedLcl = nullptr ;
778782
779783 // If this is a tail-call via helper, and we have any unmanaged p/invoke calls in
780784 // the method, then we're going to run the p/invoke epilog
@@ -834,11 +838,13 @@ void Compiler::fgComputeLifeCall(VARSET_TP& life, VARSET_VALARG_TP keepAliveVars
834838 }
835839 }
836840
837- GenTreeLclVarCommon* definedLcl = gtCallGetDefinedRetBufLclAddr (call);
841+ definedLcl = gtCallGetDefinedRetBufLclAddr (call);
838842 if (definedLcl != nullptr )
839843 {
840844 fgComputeLifeLocal (life, keepAliveVars, definedLcl);
841845 }
846+
847+ return definedLcl;
842848}
843849
844850// ------------------------------------------------------------------------
@@ -1171,54 +1177,63 @@ void Compiler::fgComputeLife(VARSET_TP& life,
11711177 AGAIN:
11721178 assert (tree->OperGet () != GT_QMARK);
11731179
1180+ bool isUse = false ;
1181+ bool doAgain = false ;
1182+ bool storeRemoved = false ;
1183+ LclVarDsc* varDsc = nullptr ;
1184+
11741185 if (tree->IsCall ())
11751186 {
1176- fgComputeLifeCall (life, keepAliveVars, tree->AsCall ());
1187+ GenTreeLclVarCommon* const definedLcl = fgComputeLifeCall (life, keepAliveVars, tree->AsCall ());
1188+ if (definedLcl != nullptr )
1189+ {
1190+ isUse = (definedLcl->gtFlags & GTF_VAR_USEASG) != 0 ;
1191+ varDsc = lvaGetDesc (definedLcl);
1192+ }
11771193 }
11781194 else if (tree->OperIsNonPhiLocal ())
11791195 {
1196+ isUse = (tree->gtFlags & GTF_VAR_USEASG) != 0 ;
11801197 bool isDeadStore = fgComputeLifeLocal (life, keepAliveVars, tree);
11811198 if (isDeadStore)
11821199 {
1183- LclVarDsc* varDsc = lvaGetDesc (tree->AsLclVarCommon ());
1184- bool isUse = (tree->gtFlags & GTF_VAR_USEASG) != 0 ;
1185- bool doAgain = false ;
1186- bool storeRemoved = false ;
1200+ varDsc = lvaGetDesc (tree->AsLclVarCommon ());
11871201
11881202 if (fgRemoveDeadStore (&tree, varDsc, life, &doAgain, pStmtInfoDirty, &storeRemoved DEBUGARG (treeModf)))
11891203 {
11901204 assert (!doAgain);
11911205 break ;
11921206 }
1207+ }
1208+ }
11931209
1194- if (isUse && !storeRemoved)
1210+ // SSA and VN treat "partial definitions" as true uses, so for this
1211+ // front-end liveness pass we must add them to the live set in case
1212+ // we failed to remove the dead store.
1213+ //
1214+ if ((varDsc != nullptr ) && isUse && !storeRemoved)
1215+ {
1216+ if (varDsc->lvTracked )
1217+ {
1218+ VarSetOps::AddElemD (this , life, varDsc->lvVarIndex );
1219+ }
1220+ if (varDsc->lvPromoted )
1221+ {
1222+ for (unsigned fieldIndex = 0 ; fieldIndex < varDsc->lvFieldCnt ; fieldIndex++)
11951223 {
1196- // SSA and VN treat "partial definitions" as true uses, so for this
1197- // front-end liveness pass we must add them to the live set in case
1198- // we failed to remove the dead store.
1199- if (varDsc->lvTracked )
1200- {
1201- VarSetOps::AddElemD (this , life, varDsc->lvVarIndex );
1202- }
1203- if (varDsc->lvPromoted )
1224+ LclVarDsc* fieldVarDsc = lvaGetDesc (varDsc->lvFieldLclStart + fieldIndex);
1225+ if (fieldVarDsc->lvTracked )
12041226 {
1205- for (unsigned fieldIndex = 0 ; fieldIndex < varDsc->lvFieldCnt ; fieldIndex++)
1206- {
1207- LclVarDsc* fieldVarDsc = lvaGetDesc (varDsc->lvFieldLclStart + fieldIndex);
1208- if (fieldVarDsc->lvTracked )
1209- {
1210- VarSetOps::AddElemD (this , life, fieldVarDsc->lvVarIndex );
1211- }
1212- }
1227+ VarSetOps::AddElemD (this , life, fieldVarDsc->lvVarIndex );
12131228 }
12141229 }
1215-
1216- if (doAgain)
1217- {
1218- goto AGAIN;
1219- }
12201230 }
12211231 }
1232+
1233+ if (doAgain)
1234+ {
1235+ goto AGAIN;
1236+ }
12221237 }
12231238}
12241239
0 commit comments