@@ -772,9 +772,13 @@ void Compiler::fgLiveVarAnalysis()
772
772
// keepAliveVars - Tracked locals that must be kept alive everywhere in the block
773
773
// call - The call node in question.
774
774
//
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)
776
779
{
777
780
assert (call != nullptr );
781
+ GenTreeLclVarCommon* definedLcl = nullptr ;
778
782
779
783
// If this is a tail-call via helper, and we have any unmanaged p/invoke calls in
780
784
// 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
834
838
}
835
839
}
836
840
837
- GenTreeLclVarCommon* definedLcl = gtCallGetDefinedRetBufLclAddr (call);
841
+ definedLcl = gtCallGetDefinedRetBufLclAddr (call);
838
842
if (definedLcl != nullptr )
839
843
{
840
844
fgComputeLifeLocal (life, keepAliveVars, definedLcl);
841
845
}
846
+
847
+ return definedLcl;
842
848
}
843
849
844
850
// ------------------------------------------------------------------------
@@ -1171,54 +1177,63 @@ void Compiler::fgComputeLife(VARSET_TP& life,
1171
1177
AGAIN:
1172
1178
assert (tree->OperGet () != GT_QMARK);
1173
1179
1180
+ bool isUse = false ;
1181
+ bool doAgain = false ;
1182
+ bool storeRemoved = false ;
1183
+ LclVarDsc* varDsc = nullptr ;
1184
+
1174
1185
if (tree->IsCall ())
1175
1186
{
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
+ }
1177
1193
}
1178
1194
else if (tree->OperIsNonPhiLocal ())
1179
1195
{
1196
+ isUse = (tree->gtFlags & GTF_VAR_USEASG) != 0 ;
1180
1197
bool isDeadStore = fgComputeLifeLocal (life, keepAliveVars, tree);
1181
1198
if (isDeadStore)
1182
1199
{
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 ());
1187
1201
1188
1202
if (fgRemoveDeadStore (&tree, varDsc, life, &doAgain, pStmtInfoDirty, &storeRemoved DEBUGARG (treeModf)))
1189
1203
{
1190
1204
assert (!doAgain);
1191
1205
break ;
1192
1206
}
1207
+ }
1208
+ }
1193
1209
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++)
1195
1223
{
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 )
1204
1226
{
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 );
1213
1228
}
1214
1229
}
1215
-
1216
- if (doAgain)
1217
- {
1218
- goto AGAIN;
1219
- }
1220
1230
}
1221
1231
}
1232
+
1233
+ if (doAgain)
1234
+ {
1235
+ goto AGAIN;
1236
+ }
1222
1237
}
1223
1238
}
1224
1239
0 commit comments