// Liveness phase will remove unnecessary initializations.
if (info.compInitMem || compSuppressedZeroInit)
{
- unsigned varNum;
- LclVarDsc* varDsc;
- for (varNum = 0, varDsc = lvaTable; varNum < lvaCount; varNum++, varDsc++)
+ for (unsigned varNum = 0; varNum < lvaCount; varNum++)
{
#if FEATURE_FIXED_OUT_ARGS
if (varNum == lvaOutgoingArgSpaceVar)
continue;
}
#endif // FEATURE_FIXED_OUT_ARGS
- if (!varDsc->lvIsParam)
+
+ LclVarDsc* varDsc = lvaGetDesc(varNum);
+
+ if (varDsc->lvIsParam)
{
- var_types lclType = varDsc->TypeGet();
- bool isUserLocal = (varNum < info.compLocalsCount);
- bool structWithGCFields = ((lclType == TYP_STRUCT) && varDsc->GetLayout()->HasGCPtr());
- bool hadSuppressedInit = varDsc->lvSuppressedZeroInit;
- if ((info.compInitMem && (isUserLocal || structWithGCFields)) || hadSuppressedInit)
+ continue;
+ }
+
+#if FEATURE_IMPLICIT_BYREFS
+ if (varDsc->lvPromoted)
+ {
+ LclVarDsc* firstField = lvaGetDesc(varDsc->lvFieldLclStart);
+ if (firstField->lvParentLcl != varNum)
{
- GenTree* lcl = gtNewLclvNode(varNum, lclType);
- GenTree* init = nullptr;
- if (varTypeIsStruct(lclType))
- {
- init = gtNewBlkOpNode(lcl, gtNewIconNode(0));
- init = fgMorphInitBlock(init);
- }
- else
- {
- GenTree* zero = gtNewZeroConNode(lclType);
- init = gtNewAssignNode(lcl, zero);
- }
- Statement* initStmt = gtNewStmt(init, callDI);
- fgInsertStmtBefore(block, lastStmt, initStmt);
+ // Local copy for implicit byref promotion that was undone. Do
+ // not introduce new references to it, all uses have been
+ // morphed to access the parameter.
+ CLANG_FORMAT_COMMENT_ANCHOR;
+
+#ifdef DEBUG
+ LclVarDsc* param = lvaGetDesc(firstField->lvParentLcl);
+ assert(param->lvIsImplicitByRef && !param->lvPromoted);
+ assert(param->lvFieldLclStart == varNum);
+#endif
+ continue;
+ }
+ }
+#endif
+
+ var_types lclType = varDsc->TypeGet();
+ bool isUserLocal = (varNum < info.compLocalsCount);
+ bool structWithGCFields = ((lclType == TYP_STRUCT) && varDsc->GetLayout()->HasGCPtr());
+ bool hadSuppressedInit = varDsc->lvSuppressedZeroInit;
+ if ((info.compInitMem && (isUserLocal || structWithGCFields)) || hadSuppressedInit)
+ {
+ GenTree* lcl = gtNewLclvNode(varNum, lclType);
+ GenTree* init = nullptr;
+ if (varTypeIsStruct(lclType))
+ {
+ init = gtNewBlkOpNode(lcl, gtNewIconNode(0));
+ init = fgMorphInitBlock(init);
+ }
+ else
+ {
+ GenTree* zero = gtNewZeroConNode(lclType);
+ init = gtNewAssignNode(lcl, zero);
}
+ Statement* initStmt = gtNewStmt(init, callDI);
+ fgInsertStmtBefore(block, lastStmt, initStmt);
}
}
}