Uh oh!
There was an error while loading. Please reload this page.
JIT: Add a primitive to split statements at a specified tree - #83005
Conversation
ghost
commented
Mar 5, 2023
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch, @kunalspathak Issue Detailsnull
|
BruceForstall
commented
Mar 8, 2023
It seems totally reasonable to add this as one of the JIT stress modes if it is incorporated into the JIT. Could we use gtSplitTree to remove all GT_COMMA by hoisting the op1 to its own statement? There are probably lots of optimizations that are doing tree-based pattern matching including commas that would generate worse code (or fail) as a result, but maybe as a stress mode? |
jakobbotsch
commented
Mar 8, 2023
Yes, I think I will end up PR'ing this primitive separately from #81635, and it seems like a good idea to have these stress modes. Indeed it can be used to remove all COMMA nodes, that would also be an interesting stress mode, I'll add it once this is in a more workable state. |
jakobbotsch
commented
Mar 9, 2023
/azp run Fuzzlyn |
|
Azure Pipelines successfully started running 1 pipeline(s). |
Also fix LIR links traversed initialization
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
jakobbotsch
commented
Mar 10, 2023
/azp run runtime-coreclr jitstress, runtime-coreclr libraries-jitstress |
|
Azure Pipelines successfully started running 2 pipeline(s). |
jakobbotsch
commented
Mar 11, 2023
/azp run runtime-coreclr jitstress, runtime-coreclr libraries-jitstress |
|
Azure Pipelines successfully started running 2 pipeline(s). |
In case you are curious, here are the diffs if we remove all commas before the optimization phases: The interference checking done by |
BruceForstall
commented
Mar 11, 2023
As expected... bad :-) If optimizations used SSA instead of tree-based pattern matching, maybe it wouldn't be so bad. |
jakobbotsch
commented
Mar 11, 2023
| if (gtSplitTree(block, stmt, tree, &newStmt, &use)) | ||
| { | ||
| while ((newStmt != nullptr) && (newStmt != stmt)) | ||
| { | ||
| fgMorphStmtBlockOps(block, newStmt); | ||
| newStmt = newStmt->GetNextStmt(); | ||
| } | ||
| fgMorphStmtBlockOps(block, stmt); | ||
| gtUpdateStmtSideEffects(stmt); | ||
| } |
There was a problem hiding this comment.
@EgorBo Your PR will need to do something similar like this, but note that calling fgMorphStmtBlockOps can invalidate the use, so it should be done only after you've replaced it with the new local.
| bool answerOnBoundExceeded /*= true*/) | ||
| { | ||
| const __int64 maxLinks = 1000000000; | ||
| const __int64 maxLinks = 100000000; |
There was a problem hiding this comment.
I thought this limit was a bit on the high side before.
EgorBo
left a comment
There was a problem hiding this comment.
Thanks! I've been following changes in this PR so LGTM
jakobbotsch
commented
Jul 27, 2023
I realized while working on #89560 that the comma removal is more conservative than necessary -- it introduces a local for the comma's op2, which is unnecessary. With that fixed the diffs look like https://gist.github.com/jakobbotsch/dd2ea6d7b94d9dbf80283191d98e2dd0, so it goes from "very bad" to "still very bad, but only half as very bad". |
EgorBo
commented
Jul 27, 2023
Removal of commas changes N009 ( 12, 14) [000008] ---XG------▌RETURN float $205N008 ( 11, 13) [000007] ---XG------└──▌HWINTRINSIC float float GetElement <l:$2c3, c:$2c2>
N002 ( 3, 2) [000001] ---XG------├──▌IND simd8 <l:$240, c:$241>
N001 ( 1, 1) [000000] -----------│└──▌LCL_VAR byref V00this u:1 (last use) $80N007 ( 7, 10) [000006] ---X-------└──▌COMMA int $280N005 ( 6, 9) [000005] ---X-------├──▌BOUNDS_CHECK_ArgRng void $203N003 ( 1, 1) [000004] -----------│├──▌LCL_VAR int V01 arg1 u:1 $c0
N004 ( 1, 1) [000003] -----------│└──▌CNS_INT int 2 $44N006 ( 1, 1) [000002] -----------└──▌LCL_VAR int V01 arg1 u:1 (last use) $c0into ------------BB01 [000..00D) (return), preds={} succs={}
*****BB01STMT00001 ( 0x000[E-] ... ??? )
N003 ( 7, 5) [000009] DA-XG------▌STORE_LCL_VAR simd8 V03 rat0 N002 ( 3, 2) [000001] ---XG------└──▌IND simd8 <l:$240, c:$241>
N001 ( 1, 1) [000000] -----------└──▌LCL_VAR byref V00this u:1 (last use) $80*****BB01STMT00002 ( ??? ... ??? )
N003 ( 6, 9) [000005] ---X-------▌BOUNDS_CHECK_ArgRng void $203N001 ( 1, 1) [000004] -----------├──▌LCL_VAR int V01 arg1 u:1 $c0
N002 ( 1, 1) [000003] -----------└──▌CNS_INT int 2 $44*****BB01STMT00000 ( 0x000[E-] ... 0x00C )
N004 ( 6, 5) [000008] ----G------▌RETURN float $205N003 ( 5, 4) [000007] ----G------└──▌HWINTRINSIC float float GetElement <l:$2c3, c:$2c2>
N001 ( 3, 2) [000010] -----------├──▌LCL_VAR simd8 V03 rat0 N002 ( 1, 1) [000002] -----------└──▌LCL_VAR int V01 arg1 u:1 (last use) $c0It actually looks like Edit: opened #89565 for this. |

Add a
gtSplitTreethat can split a statement at an arbitrary tree: this creates new statements before the statement such that the original statement now executes the input tree as the very first non-invariant node.This can be used for example to introduce control flow at an arbitrary point within a tree.