-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[temp-rvalue] Handle promoting alloc_stack that are destroyed via a load [take] in ossa. #30088
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[temp-rvalue] Handle promoting alloc_stack that are destroyed via a load [take] in ossa. #30088
Conversation
@eeckstein I need to add a few more tests (I want to add one that shows load [take] not being converted to load [copy]) here but the implementation is complete. |
@swift-ci benchmark |
@swift-ci smoke test |
Found the problem. The problem was that when I have a copy_addr that doesn't take the source, if I try to eliminate a load [take] (and thus convert the load [take] to be a load [copy]), I need to hoist the load [copy] to be where the copy_addr is since otherwise, in between where the copy_addr was and the load [take], the original value may be destroyed. |
…oad [take] in ossa. There are a few interesting things here: 1. All of this code is conditionalized implicitly on ossa by us checking for load [take]. If we are in non-ossa, then we will have unqualified loads and this code path will be skipped. I left in the old test that made sure we did not support this in non-ossa code for this purpose. 2. We treat the load [take] like a destroy_addr. Thus the current method of providing safety via using lifetime analysis to show all "destroys" form a minimal post-dominating set for the copy_addr. 3. We do not allow for load [take] on sub-element initializations. The reason why is that SILGen initializes temporaries completely in memory and generally destroys addresses completely as well. Given that is the pattern we are looking for, we just reduce the state space by banning this pattern. 4. If we have a copy_addr [init], then we not only change the load [take] to have the original source address as an argument, but we also change the load [take] to a load [copy] so we don't lose the +1. Additionally, we have to hoist the load [copy] to the copy_addr [init] site to ensure that we do not insert a use-after-free from the retain happening too late. I am doing this to clean up some simple temp rvalue patterns in SIL before semantic arc opts runs. This ensures that we are more likely to have a load operation come from a more meaningful semantic entity (for instance a let field of a guaranteed class) and thus allow us to convert a load [copy] to a load_borrow. I am also going to add support in subsequent commits for eliminating alloc_stack that are stored into as well (another pattern I am seeing).
ba18825
to
3a725c3
Compare
@swift-ci test |
1 similar comment
@swift-ci test |
@swift-ci benchmark |
1 similar comment
@swift-ci benchmark |
@swift-ci test |
@swift-ci benchmark |
1 similar comment
@swift-ci benchmark |
Build failed |
Performance: -O
Code size: -OPerformance: -Osize
Code size: -OsizePerformance: -Onone
Code size: -swiftlibsHow to read the dataThe tables contain differences in performance which are larger than 8% and differences in code size which are larger than 1%.If you see any unexpected regressions, you should consider fixing the Noise: Sometimes the performance results (not code size!) contain false Hardware Overview
|
@swift-ci benchmark |
Performance: -O
Code size: -OPerformance: -Osize
Code size: -OsizePerformance: -Onone
Code size: -swiftlibsHow to read the dataThe tables contain differences in performance which are larger than 8% and differences in code size which are larger than 1%.If you see any unexpected regressions, you should consider fixing the Noise: Sometimes the performance results (not code size!) contain false Hardware Overview
|
@swift-ci build toolchain |
1 similar comment
@swift-ci build toolchain |
Linux Toolchain (Ubuntu 16.04) Install command |
macOS Toolchain Install command |
Seems like noise. |
There are a few interesting things here:
All of this code is conditionalized implicitly on ossa by us checking for
load [take]. If we are in non-ossa, then we will have unqualified loads and this
code path will be skipped. I left in the old test that made sure we did not
support this in non-ossa code for this purpose.
We treat the load [take] like a destroy_addr. Thus the current method of
providing safety via using lifetime analysis to show all "destroys" form a
minimal post-dominating set for the copy_addr.
We do not allow for load [take] on sub-element initializations. The reason
why is that SILGen initializes temporaries completely in memory and generally
destroys addresses completely as well. Given that is the pattern we are looking
for, we just reduce the state space by banning this pattern.
If we have a copy_addr [init], then we not only change the load [take] to
have the original source address as an argument, but we also change the load
[take] to a load [copy] so we don't lose the +1.
I am doing this to clean up some simple temp rvalue patterns in SIL before
semantic arc opts runs. This ensures that we are more likely to have a load
operation come from a more meaningful semantic entity (for instance a let field
of a guaranteed class) and thus allow us to convert a load [copy] to a
load_borrow.
I am also going to add support in subsequent commits for eliminating alloc_stack
that are stored into as well (another pattern I am seeing).
Replace this paragraph with a description of your changes and rationale. Provide links to external references/discussions if appropriate.
Resolves SR-NNNN.