This repository was archived by the owner on Jan 23, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 4.9k
Stack<T> optimization of (Try)Peek, (Try)Pop and Push #26086
Merged
Merged
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
c124114
Stack.Pop RCE
gfoidl 0123330
Applied same optimizations as for Pop on Peek, TryPeek, TryPop, Push
gfoidl e7308d8
Revert change for Push
gfoidl d2f5b2c
Stack.Push with hot-/cold-path (PushWithResize)
gfoidl f337882
Addressed PR feedback
gfoidl b0bfd83
Array-copy in Peek is not necessary, JIT can do the same
gfoidl 0a2e11e
Reverted b0bfd83
gfoidl 084acb7
Addressed PR feedback
gfoidl File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Is this copy really necessary?
Uh oh!
There was an error while loading. Please reload this page.
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.
With the copy
T[] array = _arrayit gets:Without the copy and
it gets:
So basically the same code. Hence the copy can be avoided.
It seems as the JIT elides bound checks even on field access. Is this new? (and is this safe?)
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's safe in the sense that the JIT generates correct code. Note that there's only one field load in the generated code. CSE removed the second one so in effect it did the same optimization that you did manually.
The fact that the range check is actually removed might be relatively new, in the past the JIT did not propagate existing analysis information to variables created by CSE and this usually prevented further optimizations. Some improvements in this area were done in dotnet/coreclr#9615
In general I'd recommend avoiding multiple field loads when arrays are involved, CSE may not be able to always eliminate redundant loads and even if it does there may still be cases where it doesn't work as well as manual optimization.
Still, in trivial cases such as
Peekit should work fine and thus there's little reason to complicate the code.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 great reply. 👍
I'll update the PR for 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.
For reference in
TryPeekthis JIT-optimization doesn't apply:With Copy
Without Copy
Uh oh!
There was an error while loading. Please reload this page.
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.
Hmm, interesting. The range check seems to have been eliminated but there are 2 loads of the
_arrayfield. That doesn't seem right, I'll have to look into 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.
I'm not yet sure what's going on but the generated code is definitely incorrect. Created https://github.com/dotnet/coreclr/issues/15671