-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Restrict CopyForwarding (and destroy hoisting) to OSSA SIL. #34841
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
Conversation
The premise of CopyForwarding was that memory locations have their own ownership lifetime. We knew this was unmaintainable at the time, and that was the original incentive for SIL opaque values, aided by OSSA. In the meantime, we've been relying on SILGen producing reasonable SIL patterns. Unfortunately, the CopyForwarding pass is still with us while we make major changes to SIL ownership patterns and agressively optimize ownership. That introduces risk. Ultimately, the entire CopyForwarding pass should be redesigned for OSSA-only and destroy hoisting should be a simple OSSA utility where most of the work is done by AccessPath::collectUses. But in the meantime, we should remove the source of risk by limiting the CopyForwarding pass to OSSA. Any performance regressions will be recovered as OSSA moves later in the pipeline. After that, opaque values will improve even more over the current state by handling generic SIL using the more powerful CopyPropagation pass. Fixes rdar://71584600 (miscompile in CopyForwarding's release hoisting) Here's an example of the kind of SIL the CopyForwarding does not anticipate (although it only actually miscompiles in much more obscure scenarios, which is why it's so dangerous): bb0(%0 : $AnyObject): %alloc1 = alloc_stack $AnyObject store %0 to %objaddr : $*AnyObject %ref = load %objaddr : $*AnyObject %alloc2 = alloc_stack $ObjWrapper # The in-memory reference is destroyed before retaining the loaded ref. copy_addr [take] %alloc1 to [initialization] %alloc2 : $*ObjWrapper retain_value %ref : $AnyObject
@swift-ci test |
@swift-ci benchmark |
Performance: -O
Code size: -O
Performance: -Osize
Code size: -Osize
Performance: -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.
lgtm!
Build failed |
I've been seeing this failure a lot recently: |
@swift-ci smoke test and merge |
The premise of CopyForwarding was that memory locations have their own
ownership lifetime. We knew this was unmaintainable at the time, and
that was the original incentive for SIL opaque values, aided by
OSSA. In the meantime, we've been relying on SILGen producing
reasonable SIL patterns. Unfortunately, the CopyForwarding pass is
still with us while we make major changes to SIL ownership patterns
and agressively optimize ownership. That introduces risk.
Ultimately, the entire CopyForwarding pass should be redesigned for
OSSA-only and destroy hoisting should be a simple OSSA utility where
most of the work is done by AccessPath::collectUses.
But in the meantime, we should remove the source of risk by limiting
the CopyForwarding pass to OSSA. Any performance regressions will be
recovered as OSSA moves later in the pipeline. After that, opaque
values will improve even more over the current state by handling
generic SIL using the more powerful CopyPropagation pass.
Fixes rdar://71584600 (miscompile in CopyForwarding's release hoisting)
Here's an example of the kind of SIL the CopyForwarding does not
anticipate (although it only actually miscompiles in much more obscure
scenarios, which is why it's so dangerous):
bb0(%0 : $AnyObject):
%alloc1 = alloc_stack $AnyObject
store %0 to %objaddr : $*AnyObject
%ref = load %objaddr : $*AnyObject
%alloc2 = alloc_stack $ObjWrapper
The in-memory reference is destroyed before retaining the loaded ref.
copy_addr [take] %alloc1 to [initialization] %alloc2 : $*ObjWrapper
retain_value %ref : $AnyObject