-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
Improve struct inits. #52292
Improve struct inits. #52292
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3120,6 +3120,7 @@ void Lowering::LowerStoreLocCommon(GenTreeLclVarCommon* lclStore) | |
} | ||
if ((lclStore->TypeGet() == TYP_STRUCT) && !srcIsMultiReg && (src->OperGet() != GT_PHI)) | ||
{ | ||
bool convertToStoreObj; | ||
if (src->OperGet() == GT_CALL) | ||
{ | ||
GenTreeCall* call = src->AsCall(); | ||
|
@@ -3165,8 +3166,58 @@ void Lowering::LowerStoreLocCommon(GenTreeLclVarCommon* lclStore) | |
return; | ||
} | ||
#endif // !WINDOWS_AMD64_ABI | ||
convertToStoreObj = false; | ||
} | ||
else if (!src->OperIs(GT_LCL_VAR) || (varDsc->GetLayout()->GetRegisterType() == TYP_UNDEF)) | ||
else if (!varDsc->IsEnregisterable()) | ||
{ | ||
convertToStoreObj = true; | ||
} | ||
else if (src->OperIs(GT_CNS_INT)) | ||
{ | ||
assert(src->IsIntegralConst(0) && "expected an INIT_VAL for non-zero init."); | ||
var_types regType = varDsc->GetRegisterType(); | ||
#ifdef FEATURE_SIMD | ||
if (varTypeIsSIMD(regType)) | ||
{ | ||
if (!varDsc->lvDoNotEnregister) | ||
{ | ||
CorInfoType simdBaseJitType = comp->getBaseJitTypeOfSIMDLocal(lclStore); | ||
if (simdBaseJitType == CORINFO_TYPE_UNDEF) | ||
{ | ||
// Lie about the type if we don't know/have it. | ||
simdBaseJitType = CORINFO_TYPE_FLOAT; | ||
} | ||
GenTreeSIMD* simdTree = | ||
comp->gtNewSIMDNode(regType, src, SIMDIntrinsicInit, simdBaseJitType, varDsc->lvExactSize); | ||
BlockRange().InsertAfter(src, simdTree); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shouldn't we There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice catch, thank you! It fixes a todo that I added because now we have SIMD16 instead of SIMD12. |
||
src = simdTree; | ||
lclStore->gtOp1 = src; | ||
convertToStoreObj = false; | ||
} | ||
else | ||
{ | ||
// the local is already known to be on stack, cheaper to initialize 0 there then use simd regs. | ||
// TODO-CQ: keep STORE_LCL and convert to non-simd after LSRA. | ||
convertToStoreObj = true; | ||
} | ||
} | ||
else | ||
#endif // FEATURE_SIMD | ||
{ | ||
convertToStoreObj = false; | ||
} | ||
} | ||
else if (!src->OperIs(GT_LCL_VAR)) | ||
{ | ||
convertToStoreObj = true; | ||
} | ||
else | ||
{ | ||
assert(src->OperIs(GT_LCL_VAR)); | ||
convertToStoreObj = false; | ||
} | ||
|
||
if (convertToStoreObj) | ||
{ | ||
GenTreeLclVar* addr = comp->gtNewLclVarAddrNode(lclStore->GetLclNum(), TYP_BYREF); | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -398,23 +398,25 @@ void Rationalizer::RewriteAssignment(LIR::Use& use) | |
#ifdef FEATURE_SIMD | ||
if (varTypeIsSIMD(location) && assignment->OperIsInitBlkOp()) | ||
{ | ||
if (location->OperGet() == GT_LCL_VAR) | ||
if (location->OperIs(GT_LCL_VAR)) | ||
{ | ||
var_types simdType = location->TypeGet(); | ||
GenTree* initVal = assignment->AsOp()->gtOp2; | ||
CorInfoType simdBaseJitType = comp->getBaseJitTypeOfSIMDLocal(location); | ||
if (simdBaseJitType != CORINFO_TYPE_UNDEF) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we have never had
from a tree like:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is possible, but we handle this in register allocation by lying about the type: if (simdNode->GetSimdBaseJitType() == CORINFO_TYPE_UNDEF)
{
// There are a few scenarios where we can get a LCL_VAR which
// doesn't know the underlying baseType. In that scenario, we
// will just lie and say it is a float. Codegen doesn't actually
// care what the type is but this avoids an assert that would
// otherwise be fired from the more general checks that happen.
simdNode->SetSimdBaseJitType(CORINFO_TYPE_FLOAT);
} Namely there are a variety of scenarios where the base type might not get copied around for things like SIMD locals and where we lose the class handle and type information. Ideally, we would preserve this 100% of the time, since its needed by things like CSE, but we don't today. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The potential issue was: These lyings could be also deleted now (will push a change soon), maybe it will require to add There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Is an interesting tree. In my testing (wrote a checker that looks for all There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. oh, this code exists here to catch what morph did not for some reason, for example: repro-7984.zip
to see the dump, it will show you that in this case the issue is in fgMorphBlock that does not call morphTree for the trees that it creates, @kunalspathak recently pointed me to another issue caused by the same source.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I believe you 😄. Good luck!
Thanks! |
||
if (simdBaseJitType == CORINFO_TYPE_UNDEF) | ||
{ | ||
GenTreeSIMD* simdTree = new (comp, GT_SIMD) | ||
GenTreeSIMD(simdType, initVal, SIMDIntrinsicInit, simdBaseJitType, genTypeSize(simdType)); | ||
assignment->AsOp()->gtOp2 = simdTree; | ||
value = simdTree; | ||
initVal->gtNext = simdTree; | ||
simdTree->gtPrev = initVal; | ||
|
||
simdTree->gtNext = location; | ||
location->gtPrev = simdTree; | ||
// Lie about the type if we don't know/have it. | ||
simdBaseJitType = CORINFO_TYPE_FLOAT; | ||
} | ||
GenTreeSIMD* simdTree = | ||
comp->gtNewSIMDNode(simdType, initVal, SIMDIntrinsicInit, simdBaseJitType, genTypeSize(simdType)); | ||
assignment->AsOp()->gtOp2 = simdTree; | ||
value = simdTree; | ||
initVal->gtNext = simdTree; | ||
simdTree->gtPrev = initVal; | ||
|
||
simdTree->gtNext = location; | ||
location->gtPrev = simdTree; | ||
} | ||
} | ||
#endif // FEATURE_SIMD | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the main goal of this change is to keep
ASG(LCL_VAR, 0)
asSTORE_LCL_VAR(0)
without taking the address of the lcl.