-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[SIL] Added borrow scopes to alloc_boxes. #40793
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
[SIL] Added borrow scopes to alloc_boxes. #40793
Conversation
d411337
to
3293c8e
Compare
Because AllocBoxToStack is not able to transform every alloc_box into an alloc_stack, it's necessary to add begin_borrow [lexical] to every alloc_box in order to provide lexical scopes for those alloc_boxes which will not be transformed into alloc_stacks.
Now that alloc_boxes whose lifetimes are lexical are emitted with begin_borrow [lexical]/end_borrow, AllocBoxToStack needs to be able to see through those new borrow scopes in order to continue stack promoting the same boxes that it was able to before those lexical scopes were emitted.
3293c8e
to
f19e413
Compare
@swift-ci please benchmark |
@swift-ci please test |
Performance (x86_64): -O
Code size: -OPerformance (x86_64): -Osize
Code size: -OsizePerformance (x86_64): -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
|
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! That's a ton of tests to fix!
Build failed |
@swift-ci please test macos platform |
After swiftlang#40793, alloc_boxes all have their lifetimes protected by a lexical borrow scope. In that PR, DI had been updated to see through begin_borrow instructions from a project_box to a mark_uninitialized. It did not, however, correct the end_borrow instructions when destroy_values of mark_uninitializeds were replaced with destroy_addrs of project_boxes. That is done here. In a bit more detail, in the following context %box = alloc_box %mark_uninit = mark_uninitialized %box %lifetime = begin_borrow [lexical] %mark_uninit %proj_box = project_box %lifetime When it is not statically known whether a field is initialized, we are replacing the instruction // before destroy_value %mark_uninit // after with the following diamond // before %initialized = load cond_br %initialized, yes, no yes: destroy_addr %proj_box br bottom no: br bottom bottom: dealloc_box %box br keep_going keep_going: // after Doing so is problematic, though, because by SILGen construction the destroy_value is always preceded by an end_borrow: end_borrow %lifetime destroy_value %mark_uninit Previously, that end_borrow remained above the %initialized = load instruction in the above. That was invalid because the the newly introduced destroy_addr %proj_box was a use of the borrow scope (%proj_box is a projection of the begin_borrow) and consequently must be within the borrow scope. Note also that it would not be sufficient to simply emit the diamond before the end_borrow. The end_borrow must come before the destruction of the value whose lifetime it is protecting (%box), and the diamond contains the instruction to destroy that value (dealloc_box) in its bottom block. To resolve this issue, just move the end_borrow instruction from where it was to before the dealloc box. (This is actually done by moving it to the top of the diamond's "continue" block prior to the emission of that dealloc_box instruction.) rdar://89984216
Because AllocBoxToStack is not able to transform every alloc_box into an alloc_stack, it's necessary to add begin_borrow [lexical] to every alloc_box in order to provide lexical scopes for those alloc_boxes which will not be transformed into alloc_stacks.
Now that alloc_boxes whose lifetimes are lexical are emitted with begin_borrow [lexical]/end_borrow, AllocBoxToStack needs to be able to see through those new borrow scopes in order to continue stack promoting the same boxes that it was able to before those lexical scopes were emitted.