-
Notifications
You must be signed in to change notification settings - Fork 2.7k
[WIP] Support Write-Thru of EH variables in LSRA #26087
Conversation
coreclr/src/System.Private.CoreLib/shared/System/Threading/ExecutionContext.cs Lines 140 to 200 in 740752c
Currently it takes second copies of variables so it can enregister them as the EH they pass over otherwise forces everything to stack. |
ad88281
to
492d6c9
Compare
@benaadams can you cross-link the PR/issue where you were working on this? And are there other examples you know of? |
This was the original change #15629 that moved from using the #20628 introduced a generic copy of I looked to simplify it in #21908 by moving the
The two
Also every Those are the 3 methods which have mitigations that I'm aware of. They make the code quite messy; and since it always currently has to spill to stack; the number of reads/uses has to out number the writes to be of benefit. However, these functions are both ubiquitously used and also in most async and ThreadPool hot paths that it made it worth it. It would be great to simplify the code to just use a single local for each variable rather than 3 (pre-EH, cross-EH, post-EH); and the Jit could potentially generate better asm from it? |
@benaadams - thanks for the pointers! Once I've got this actually working across the board I'll have a look at those.
Yes, that's true even within the register allocator. I've added some heuristics, but I suspect they'll need further tuning. |
0b5d2f6
to
820a1fb
Compare
Initial results aren't 100% promising. Although there's an overall code-size reduction (x64 pmi diffs of frameworks and benchmarks), the results are definitely mixed:
Looking at There are several factors at play.
So I'll plan to investigate whether I can come up with better heuristics to deal with the first issue at least. |
I think removing the mitigations would look like: c9d005a |
5d95742
to
56af71f
Compare
cf074bb
to
2449e9e
Compare
0c3f17e
to
851a089
Compare
@dotnet/jit-contrib |
96eb629
to
4caebbd
Compare
c67306d
to
bb037ab
Compare
Thank you for your contribution. As announced in dotnet/coreclr#27549 this repository will be moving to dotnet/runtime on November 13. If you would like to continue working on this PR after this date, the easiest way to move the change to dotnet/runtime is:
|
Mark EH variables (those that are live in or out of exception regions) only as lvLiveInOutOfHndlr, not necessarily lvDoNotEnregister During register allocation, mark these as write-thru, and mark all defs as write-thru, ensuring that the stack value is always valid. Mark those defs with GTF_SPILLED (this the "reload" flag and is not currently used for pure defs) to indicate that it should be kept in the register. Mark blocks that enter EH regions as having no predecessor, and set the location of all live-in vars to be on the stack. Change genFnPrologCalleeRegArgs to store EH vars also to the stack if they have a register assignment. Tune callee-save heuristics for EH vars. Remove/modify mitigations
… they always go to memory. - Never split a block if the only resolution moves are for EH vars. - Add a test case to enable diff tracking for #21973
Modify weight for EH vars in LIR Take into account how many callee save regs there are
766aad8
to
f96f1cf
Compare
Thank you for your contribution. As announced in #27549 the dotnet/runtime repository will be used going forward for changes to this code base. Closing this PR as no more changes will be accepted into master for this repository. If you’d like to continue working on this change please move it to dotnet/runtime. |
Mark EH variables (those that are live in or out of exception regions) only as lvLiveInOutOfHndlr, not necessarily lvDoNotEnregister
During register allocation, mark these as write-thru, and mark all defs as write-thru, ensuring that the stack value is always valid.
Mark those defs with GTF_SPILLED (this the "reload" flag and is not currently used for pure defs) to indicate that it should be kept in the register.
Mark blocks that enter EH regions as having no predecessor, and set the location of all live-in vars to be on the stack.
Change genFnPrologCalleeRegArgs to store EH vars also to the stack if they have a register assignment.