Skip to content

JIT: Disable old promotion for structs with significant padding #104438

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 0 additions & 8 deletions src/coreclr/jit/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -604,12 +604,6 @@ class LclVarDsc
unsigned char lvIsStructField : 1; // Is this local var a field of a promoted struct local?
unsigned char lvContainsHoles : 1; // Is this a promoted struct whose fields do not cover the struct local?

// True for a promoted struct that has significant padding in it.
// Significant padding is any data in the struct that is not covered by a
// promoted field and that the EE told us we need to preserve on block
// copies/inits.
unsigned char lvAnySignificantPadding : 1;

unsigned char lvIsMultiRegArg : 1; // true if this is a multireg LclVar struct used in an argument context
unsigned char lvIsMultiRegRet : 1; // true if this is a multireg LclVar struct assigned from a multireg call

Expand Down Expand Up @@ -4209,7 +4203,6 @@ class Compiler
CORINFO_CLASS_HANDLE typeHnd;
bool canPromote;
bool containsHoles;
bool anySignificantPadding;
bool fieldsSorted;
unsigned char fieldCnt;
lvaStructFieldInfo fields[MAX_NumOfFieldsInPromotableStruct];
Expand All @@ -4218,7 +4211,6 @@ class Compiler
: typeHnd(typeHnd)
, canPromote(false)
, containsHoles(false)
, anySignificantPadding(false)
, fieldsSorted(false)
, fieldCnt(0)
{
Expand Down
33 changes: 14 additions & 19 deletions src/coreclr/jit/lclvars.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2371,9 +2371,15 @@ bool Compiler::StructPromotionHelper::CanPromoteStructType(CORINFO_CLASS_HANDLE
if (fieldsSize != treeNodes[0].size)
{
structPromotionInfo.containsHoles = true;
}

structPromotionInfo.anySignificantPadding = treeNodes[0].hasSignificantPadding && structPromotionInfo.containsHoles;
if (treeNodes[0].hasSignificantPadding)
{
// Struct has significant data not covered by fields we would promote;
// this would typically result in dependent promotion, so leave this
// struct to physical promotion.
return false;
}
}

// Cool, this struct is promotable.

Expand Down Expand Up @@ -2716,11 +2722,6 @@ bool Compiler::StructPromotionHelper::ShouldPromoteStructVar(unsigned lclNum)
structPromotionInfo.fieldCnt, varDsc->lvFieldAccessed);
shouldPromote = false;
}
else if (varDsc->lvIsMultiRegRet && structPromotionInfo.anySignificantPadding)
{
JITDUMP("Not promoting multi-reg returned struct local V%02u with significant padding.\n", lclNum);
shouldPromote = false;
}
#if defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64)
else if ((structPromotionInfo.fieldCnt == 2) && (varTypeIsFloating(structPromotionInfo.fields[0].fldType) ||
varTypeIsFloating(structPromotionInfo.fields[1].fldType)))
Expand All @@ -2739,13 +2740,8 @@ bool Compiler::StructPromotionHelper::ShouldPromoteStructVar(unsigned lclNum)
// multiple registers?
if (compiler->lvaIsMultiregStruct(varDsc, compiler->info.compIsVarArgs))
{
if (structPromotionInfo.anySignificantPadding)
{
JITDUMP("Not promoting multi-reg struct local V%02u with significant padding.\n", lclNum);
shouldPromote = false;
}
else if ((structPromotionInfo.fieldCnt != 2) &&
!((structPromotionInfo.fieldCnt == 1) && varTypeIsSIMD(structPromotionInfo.fields[0].fldType)))
if ((structPromotionInfo.fieldCnt != 2) &&
!((structPromotionInfo.fieldCnt == 1) && varTypeIsSIMD(structPromotionInfo.fields[0].fldType)))
{
JITDUMP("Not promoting multireg struct local V%02u, because lvIsParam is true, #fields != 2 and it's "
"not a single SIMD.\n",
Expand Down Expand Up @@ -2834,11 +2830,10 @@ void Compiler::StructPromotionHelper::PromoteStructVar(unsigned lclNum)
assert(varDsc->GetLayout()->GetClassHandle() == structPromotionInfo.typeHnd);
assert(structPromotionInfo.canPromote);

varDsc->lvFieldCnt = structPromotionInfo.fieldCnt;
varDsc->lvFieldLclStart = compiler->lvaCount;
varDsc->lvPromoted = true;
varDsc->lvContainsHoles = structPromotionInfo.containsHoles;
varDsc->lvAnySignificantPadding = structPromotionInfo.anySignificantPadding;
varDsc->lvFieldCnt = structPromotionInfo.fieldCnt;
varDsc->lvFieldLclStart = compiler->lvaCount;
varDsc->lvPromoted = true;
varDsc->lvContainsHoles = structPromotionInfo.containsHoles;

#ifdef DEBUG
// Don't stress this in LCL_FLD stress.
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/liveness.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1024,7 +1024,7 @@ bool Compiler::fgComputeLifeUntrackedLocal(VARSET_TP& life,
{
// Do not consider this store dead if the parent local variable is an address exposed local or
// if the struct has any significant padding we must retain the value of.
return !varDsc.IsAddressExposed() && !varDsc.lvAnySignificantPadding;
return !varDsc.IsAddressExposed();
}

return false;
Expand Down
11 changes: 5 additions & 6 deletions src/coreclr/jit/morph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14728,12 +14728,11 @@ PhaseStatus Compiler::fgRetypeImplicitByRefArgs()
}

// Copy the struct promotion annotations to the new temp.
LclVarDsc* newVarDsc = lvaGetDesc(newLclNum);
newVarDsc->lvPromoted = true;
newVarDsc->lvFieldLclStart = varDsc->lvFieldLclStart;
newVarDsc->lvFieldCnt = varDsc->lvFieldCnt;
newVarDsc->lvContainsHoles = varDsc->lvContainsHoles;
newVarDsc->lvAnySignificantPadding = varDsc->lvAnySignificantPadding;
LclVarDsc* newVarDsc = lvaGetDesc(newLclNum);
newVarDsc->lvPromoted = true;
newVarDsc->lvFieldLclStart = varDsc->lvFieldLclStart;
newVarDsc->lvFieldCnt = varDsc->lvFieldCnt;
newVarDsc->lvContainsHoles = varDsc->lvContainsHoles;
#ifdef DEBUG
newVarDsc->lvKeepType = true;
#endif // DEBUG
Expand Down
22 changes: 0 additions & 22 deletions src/coreclr/jit/morphblock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -359,12 +359,6 @@ void MorphInitBlockHelper::TryInitFieldByField()
return;
}

if (destLclVar->lvAnySignificantPadding)
{
JITDUMP(" dest has significant padding.\n");
return;
}

if (m_dstLclOffset != 0)
{
JITDUMP(" dest not at a zero offset.\n");
Expand Down Expand Up @@ -775,22 +769,6 @@ void MorphCopyBlockHelper::MorphStructCases()
requiresCopyBlock = true;
}

// Can we use field by field copy for the dest?
if (m_dstDoFldStore && m_dstVarDsc->lvAnySignificantPadding)
{
JITDUMP(" dest has significant padding");
// C++ style CopyBlock with holes
requiresCopyBlock = true;
}

// Can we use field by field copy for the src?
if (m_srcDoFldStore && m_srcVarDsc->lvAnySignificantPadding)
{
JITDUMP(" src has significant padding");
// C++ style CopyBlock with holes
requiresCopyBlock = true;
}

#if defined(TARGET_ARM)
if (m_store->OperIsIndir() && m_store->AsIndir()->IsUnaligned())
{
Expand Down
Loading