-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Conversation
src/jit/rationalize.h
Outdated
ArrayStack<GenTree*>& parents, | ||
CORINFO_METHOD_HANDLE callHnd, | ||
void RewriteNodeAsCall(GenTree** use, | ||
Compiler::GenTreeStack& parents, |
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.
Why the 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.
Hmmm that change is presumably no longer relevant, since I can't see the need for it. At one point I believe I needed to call an existing method that took a GenTreeStack
and the compiler didn't think that ArrayStack<GenTree*>
was equivalent. In any case it probably makes sense for it to use the typedef'd 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.
I'd keep ArrayStack<GenTree*>
. It's not some convoluted template instantiation that warrants the use of a typedef and the GenTreeStack
typedef is used only in 3 places so it's best not to add more (and remove it at some point).
Any chance this can CSE the repeated use of coreclr/src/System.Private.CoreLib/shared/System/Span.Fast.cs Lines 171 to 179 in e7c6f87
|
c415cd2
to
2429f7b
Compare
👍 I really hope for this in dotnet 3.0 release. |
Working on it, and hope to get it in. |
- Enable CSE of struct values when handle is available (and add code to get the handle of HW SIMD types) - Don't require block nodes for SIMD assignments - Don't set `GTF_GLOB_REF` on `GT_OBJ` if it is local - Set `lvRegStruct` on promoted SIMD fields - Add tests for #19910 (fixed with this PR) and #3539 & #19438 (fixed with dotnet#21314) - Additional cleanup Fix #19910
2429f7b
to
3d35992
Compare
@dotnet-bot test Windows_NT arm64 Cross Checked Innerloop Build and Test |
@dotnet/jit-contrib PTAL |
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.
Still looking this over, so may have more comments later.
I'm assuming this generates a fair number of diffs, and that you've done some tuning for CSE and similar already.
Can you start characterizing the diffs?
CORINFO_FIELD_HANDLE fieldHnd = fieldSeq->m_fieldHnd; | ||
CorInfoType fieldCorType = info.compCompHnd->getFieldType(fieldHnd, &structHnd); | ||
assert(fieldCorType == CORINFO_TYPE_VALUECLASS); | ||
} |
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.
There is similar handle searching logic in gtGetClassHandle
-- perhaps factor this out as a helper method?
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.
They're really quite different, and though some logic could be sharable, the ref context seems quite different from the value-type context.
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.
Can't we just get rid of this completly? It seems preferrable to keep GT_OBJ
nodes around and extract the struct handle from those instead of attempting to recover handles from GT_IND
this way.
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 agree that we'd like to get rid of this in the long term, but this code is to deal with cases where we have already made that transformation. I'm going to look into this a bit further, so that I better understand the cases that require this.
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.
Yes, my comment was targeted at long term. Well, maybe not that long, just only after I'm done with #21705 that makes GT_OBJ
node "small" and overall cheap.
noway_assert(asgType != TYP_STRUCT); | ||
if (varTypeIsStruct(asgType)) | ||
{ | ||
destLclVarTree = fgIsIndirOfAddrOfLocal(dest); |
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.
Interesting, the OperIsBlk()
branch above uses impIsAddressInLocal
rather than fgIsIndirOfAddrOfLocal
. I suspect that using impIsAddressInLocal
there is actually incorrect but that's another story.
I did a small amount of tuning; more is probably warranted.
For x64 windows checked (frameworks + tests): Total bytes of diff: -41406 (-0.04% of base) Most of the diffs are due to not marking things as do-not-enregister and additional CSE's. The biggest impacts are in methods that use SIMD or vector types, but there are also some cases where we enregister promoted (non-SIMD) structs that were previously not enregistered. There are some regressions (of which I looked at many, but not nearly all), due to CSE'd values that cause spill, extra callee-save reg save/restore in prolog/epilog, and a case where we're doing a tail call (local was previously marked address-exposed when it was only address-taken. |
src/jit/rationalize.cpp
Outdated
break; | ||
// Rewrite these as GT_IND. | ||
assert(node->TypeGet() == TYP_STRUCT || !use.User()->OperIsInitBlkOp()); | ||
RewriteSIMDOperand(use, 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.
I think this would be clearer if the call to RewriteSIMDOperand
is wrapped in if (varTypeIsSIMD(node))
like in the GT_IND
case. And the // Rewrite these as GT_IND.
comment should be inside the if
.
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.
Done.
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.
Looked things over once again and everything I'd comment on seems covered.
@dotnet-bot test Ubuntu x64 Checked CoreFX Tests |
@dotnet-bot test Windows_NT arm Cross Checked Innerloop Build and Test |
@dotnet-bot test Windows_NT arm64 Cross Checked Innerloop Build and Test |
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
@dotnet-bot test Ubuntu arm Cross Checked crossgen_comparison Build and Test |
@dotnet/jit-contrib - any objections to merging this? I can't seem to re-trigger the "Test Pri0 Linux arm checked" that was "Cancelled" and I'm not optimistic that a re-try will address it. |
No objection... |
Cool, how can I test this? |
@mrange - now that this is merged, you can build the coreclr repo and use it. (Instructions here: https://github.com/dotnet/coreclr/blob/master/Documentation/workflow/UsingYourBuild.md) |
{ | ||
// TODO-1stClassStructs: Previously, spillGlobEffects was set to true for | ||
// GT_INITBLK and GT_COPYBLK, but this is overly conservative, and should be | ||
// revisited. (Note that it was NOT set to true for GT_COPYOBJ.) |
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 was where we were previously always spilling on a non-COPYOBJ block assignment. This was (clearly) overly conservative, but by eliminating this conservatism, I failed to add the struct case to the code in impImportBlockCode
(at the SPILL_APPEND:
label in importer.cpp) (bug #23545, fixed in PR #23570)
* [WIP] Struct & SIMD improvements - Enable CSE of struct values when handle is available (and add code to get the handle of HW SIMD types) - Don't require block nodes for SIMD assignments - Don't set `GTF_GLOB_REF` on `GT_OBJ` if it is local - Set `lvRegStruct` on promoted SIMD fields - Add tests for dotnet/coreclr#19910 (fixed with this PR) and dotnet/coreclr#3539 & dotnet/coreclr#19438 (fixed with dotnet/coreclr#21314) - Additional cleanup Fix dotnet/coreclr#19910 Commit migrated from dotnet/coreclr@3d4a1d5
GTF_GLOB_REF
onGT_OBJ
if it is locallvRegStruct
on promoted SIMD fields