-
Notifications
You must be signed in to change notification settings - Fork 10.5k
SILCombine: optimize casts of existential boxes. #33179
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
SILCombine: optimize casts of existential boxes. #33179
Conversation
@swift-ci test |
@swift-ci benchmark |
@fredriss do you have any concerns regarding the implication for debugging (see my comment in the description)? |
Performance: -O
Code size: -OPerformance: -Osize
Code size: -OsizePerformance: -OnoneCode 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
|
Build failed |
Build failed |
61d8bbd
to
303a1bd
Compare
@swift-ci test |
1 similar comment
@swift-ci test |
Build failed |
Build failed |
303a1bd
to
99e96e3
Compare
The "Result" type is expected to have no overhead when used. This requires the member functions to be inlinable. Which is probably okay for library evolution, because it's unlikely that those methods change in an incompatible way.
Optimize the unconditional_checked_cast_addr in this pattern: %box = alloc_existential_box $Error, $ConcreteError %a = project_existential_box $ConcreteError in %b : $Error store %value to %a : $*ConcreteError %err = alloc_stack $Error store %box to %err : $*Error %dest = alloc_stack $ConcreteError unconditional_checked_cast_addr Error in %err : $*Error to ConcreteError in %dest : $*ConcreteError to: ... retain_value %value : $ConcreteError destroy_addr %err : $*Error store %value to %dest $*ConcreteError This lets the alloc_existential_box become dead and it can be removed in following optimizations. The same optimization is also done for conditional_checked_cast_addr. There is also an implication for debugging: Each "throw" in the code calls the runtime function swift_willThrow. The function is used by the debugger to set a breakpoint and also add hooks. This optimization can completely eliminate a "throw", including the runtime call. So, with optimized code, the user might not see the program to break at a throw, whereas in the source code it is actually throwing. On the other hand, eliminating the existential box is a significant performance win and we don't guarantee any debugging behavior for optimized code anyway. So I think this is a reasonable trade-off. I added an option "-Xllvm -keep-will-throw-call" to keep the runtime call which can be used if someone want's to reliably break on "throw" in optimized builds. rdar://problem/66055678
99e96e3
to
662f03e
Compare
@swift-ci test |
1 similar comment
@swift-ci test |
Optimize the unconditional_checked_cast_addr in this pattern:
to:
This lets the alloc_existential_box become dead and it can be removed in following optimizations.
The same optimization is also done for conditional_checked_cast_addr.
There is also an implication for debugging:
Each "throw" in the code calls the runtime function swift_willThrow. The function is used by the debugger to set a breakpoint and also add hooks.
This optimization can completely eliminate a "throw", including the runtime call.
So, with optimized code, the user might not see the program to break at a throw, whereas in the source code it is actually throwing.
On the other hand, eliminating the existential box is a significant performance win and we don't guarantee any debugging behavior for optimized code anyway. So I think this is a reasonable trade-off.
I added an option "-Xllvm -keep-will-throw-call" to keep the runtime call which can be used if someone want's to reliably break on "throw" in optimized builds.
To make this optimization work smoothly with the Result type from the library, I had to make the Result methods inlinable. For a use case see the SILOptimizer/existential_box_elimination.swift test file.
rdar://problem/66055678