-
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
Allow enregistering more structs args #39326
Conversation
234c49f
to
444c139
Compare
This results in improvements primarily for Arm targets. Here are the crossgen diffs for frameworks & benchmarks (using altjits for x64UX, Arm and Arm64):
The regressions result primarily from register allocation issues (we don't prefer callee-save for floating point registers, so promoting a floating point field is not always profitable if it's live across a call). |
@dotnet/jit-contrib PTAL |
444c139
to
56ca049
Compare
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.
It looks like a risky change, but I understand that it is better to get it into the Prev rather that an RC.
I have a few small question and hope you could run stress tests before the merge.
LGTM in case I don't wake up before the snap.
src/coreclr/src/jit/lclvars.cpp
Outdated
{ | ||
canPromote = false; | ||
} | ||
#ifdef UNIX_AMD64_ABI | ||
#if defined(FEATURE_SIMD) && defined(TARGET_ARMARCH) | ||
// Don't promote a struct with a struct field unless it is the only field or an opaque SIMD type. |
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.
Nit: This is a perfect logical expression, but took me some time to check all cases. Maybe it could be rephrased a little bit? Maybe "A struct field that is not an opaque SIMD type blocks promotion if it it is not the only field." or delete the comment here and put it near !compiler->isOpaqueSIMDType(structPromotionInfo.fields[i].fldTypeHnd)
saying that `opaque SIMD fields can be promoted'.
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.
This comment was reworded, hopefully it's more clear now.
if (varTypeIsStruct(structPromotionInfo.fields[i].fldType) && | ||
!compiler->isOpaqueSIMDType(structPromotionInfo.fields[i].fldTypeHnd)) | ||
{ | ||
canPromote = false; |
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.
Does not it create aljit issues similar to #38980?
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.
It may, though I haven't run into them. That, however, is an altjit-specific issue so I don't think it should hold up this PR.
src/coreclr/src/jit/lclvars.cpp
Outdated
// | ||
// Arguments: | ||
// lclNode - the GT_LCL_VAR node. | ||
// varDsc - the local variable |
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.
// varDsc - the local variable | |
// varDsc - the local variable descriptor? |
src/coreclr/src/jit/lclvars.cpp
Outdated
else if (varDsc->lvIsStructField) | ||
{ | ||
noway_assert(varDsc->lvParentLcl < lvaCount); | ||
lvaTable[varDsc->lvParentLcl].lvStkOffs = varDsc->lvStkOffs; |
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.
Do we leave it set to BAD_STK_OFFS
after this change?
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.
No, this was duplicative; the field offsets are set in the promoted struct case, and don't need to be set again when they are encountered.
src/coreclr/src/jit/morph.cpp
Outdated
@@ -17401,6 +17405,9 @@ void Compiler::fgPromoteStructs() | |||
lvaStructPromotionInfo structPromotionInfo; | |||
bool tooManyLocalsReported = false; | |||
|
|||
// Clear the structPromotionHelper, since it is conservative about looking up SIMD info. |
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.
I think I am not following it. Could you please explain? structPromotionHelper
has structPromotionInfo
that is a private temporary buffer that we use to keep information about the last analyzed type. We access it only in TryPromoteStructVar
and nowhere else.
Where could we access structPromotionHelper->structPromotionInfo.typeHnd
that is cleared here?
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 cache is used by the inliner, during which it is conservative about looking up SIMD info. I clarified the comment a bit.
{ | ||
int nextArgNum = argNum + i; | ||
regNumber nextRegNum = | ||
genMapRegArgNumToRegNum(nextArgNum, regArgTab[nextArgNum].getRegType(compiler)); |
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.
Nit: extract regArgTab[nextArgNum]
to avoid the line break and use it in the next line as well.
cf4f903
to
b67b73d
Compare
7fbf6b0
to
a05526c
Compare
@dotnet/jit-contrib PTAL Prior to the latest push, I ran jitStressRegs, and there were some test build failures. There were no actual test failures, but having rebased, once the normal CI tests complete I'll run jitStressRegs again and hopefully the test build will succeed. |
ping @dotnet/jit-contrib |
Does this fix the lack of enregistration/promotion in It would show up in PMI diffs, I think (for arm64). |
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.
LGTM
@@ -17503,6 +17511,11 @@ void Compiler::fgPromoteStructs() | |||
lvaStructPromotionInfo structPromotionInfo; | |||
bool tooManyLocalsReported = false; | |||
|
|||
// Clear the structPromotionHelper, since it is used during inlining, at which point it | |||
// may be conservative about looking up SIMD info. | |||
// We don't want to preserve those conservative decisions for the actual struct promotion. |
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.
Thanks for the explanation and the comment, I would probably rephrase it as: since it is used during importation for inlining decisions.
the place that uses it before we call struct promotion is:
runtime/src/coreclr/src/jit/importer.cpp
Lines 18651 to 18658 in 334bd84
// Note if the callee's class is a promotable struct | |
if ((info.compClassAttr & CORINFO_FLG_VALUECLASS) != 0) | |
{ | |
assert(structPromotionHelper != nullptr); | |
if (structPromotionHelper->CanPromoteStructType(info.compClassHnd)) | |
{ | |
inlineResult->Note(InlineObservation::CALLEE_CLASS_PROMOTABLE); | |
} |
@AndyAyersMS - this doesn't fix the Here are the diffs:
I'll have a look at |
Allow HFAs and other structs with matching fields and registers. Contributes to dotnet#37924
a05526c
to
134dd48
Compare
It turns out that these changes only support enregistering HFAs for Arm64; other multi-reg structs aren't promoted. I have a change that handles them, but will submit a separate PR for that. |
Allow HFAs and other structs with matching fields and registers.
Fix #37924