Conversation
| ArrayStack<GenTree*>& parents, | ||
| CORINFO_METHOD_HANDLE callHnd, | ||
| void RewriteNodeAsCall(GenTree** use, | ||
| Compiler::GenTreeStack& parents, |
There was a problem hiding this comment.
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.
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 |
AndyAyersMS
left a comment
There was a problem hiding this comment.
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.
There is similar handle searching logic in gtGetClassHandle -- perhaps factor this out as a helper method?
There was a problem hiding this comment.
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.
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.
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.
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.
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. |
| break; | ||
| // Rewrite these as GT_IND. | ||
| assert(node->TypeGet() == TYP_STRUCT || !use.User()->OperIsInitBlkOp()); | ||
| RewriteSIMDOperand(use, false); |
There was a problem hiding this comment.
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.
AndyAyersMS
left a comment
There was a problem hiding this comment.
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 |
|
@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.
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_REFonGT_OBJif it is locallvRegStructon promoted SIMD fields