Commit Graph

10 Commits

Author SHA1 Message Date
Erik Eckstein dd4f3073ca DestroyHoisting: add a complexity limit for very large functions
For very large functions this optimization can run into noticeable quadratic behavior.
Therefore, ignore functions with more than 100000 SIL instructions.
This limit is large enough to not affect most of real-world SIL functions.
2026-03-16 16:12:28 +01:00
Erik Eckstein 4755aa828e DestroyHoisting: correct handling of destroy_value [dead_end]
Make sure to create `destroy_value` with correct dead_end flags.
Especially, in a dead-end region where the original value's lifetime was ended with a `destroy_value [dead_end]`, the optimization must not re-create a destroy without the dead_end flag.

^ Conflicts:
^	test/SILOptimizer/destroy-hoisting.sil
2026-01-22 17:41:21 +01:00
Erik Eckstein a85c34452a DestroyHoisting: don't bail for lexical liveranges
We don't need to check for lexical liveranges anymore because we now have "fixed" liveranges throughout the optimizer pipeline (https://github.com/swiftlang/swift/pull/85334).
2026-01-12 14:05:47 +01:00
Erik Eckstein 610539a85f SIL: streamline Operand Sequence APIs
* remove `filterUsers(ofType:)`, because it's a duplication of `users(ofType:)`
* rename `filterUses(ofType:)` -> `filter(usersOfType:)`
* rename `ignoreUses(ofType:)` -> `ignore(usersOfType:)`
* rename `getSingleUser` -> `singleUser`
* implement `singleUse` with `Sequence.singleElement`
* implement `ignoreDebugUses` with `ignore(usersOfType:)`

This is a follow-up of https://github.com/swiftlang/swift/pull/83728/commits/eb1d5f484c9f4dae73a3779191bfdf917fd07a49.
2025-10-16 10:12:33 +02:00
Andrew Trick eb1d5f484c [NFC] SwiftCompilerSources: add a correctly named filterUsers API
Rename existing filterUsers to filterUses.
2025-08-14 09:08:11 -07:00
Meghana Gupta cd684a3200 Bailout of DestroyHoisting if there were no hoistable destroys
Otherwise, DestroyHoisting attemps to compute interior liveness
and inserts destoys at the ends. CanonicalizeOSSALifetimes is
designed to do this and not DestroyHoisting.
2025-03-07 10:40:42 -08:00
Andrew Trick e280c52825 Fix DestroyHoisting: don't ignore pointer escapes.
A pointer escape means the liveness is incomplete. Don't hoist destroys with
incomplete liveness.
2025-02-26 02:13:05 -08:00
Andrew Trick 353bef7904 Fix DestroyHoisting to visit all interior uses.
Set the visitInnerUses flag. This is only a quick, partial fix.

InteriorUseWalker does not generate complete liveness for two reasons

1. pointer escapes. The client must always check for escapes before assuming
complete liveness.

2. dead end blocks. Until we have complete OSSA lifetimes, the algorithm for
handling nested borrows is incorrect. The visitInnerUses flag works around this
problem, but it isn't well tested and I'm not sure it's properly records escapes yet.
2025-02-26 00:40:12 -08:00
Erik Eckstein 9b2dfbb741 DestroyHoisting: visit begin_borrows which don't have an end_borrow in dead-end blocks.
This makes sure that incomplete lifetimes are handled correctly.

Fixes an ownership violation.
rdar://144065326
2025-02-04 12:59:40 +01:00
Erik Eckstein 5be781a9a0 Optimizer: add a new destroy-hoisting optimization
It hoists `destroy_value` instructions  without shrinking an object's lifetime.
This is done if it can be proved that another copy of a value (either in an SSA value or in memory) keeps the referenced object(s) alive until the original position of the `destroy_value`.
```
  %1 = copy_value %0
  ...
  last_use_of %0
  // other instructions
  destroy_value %0       // %1 is still alive here
```
->
```
  %1 = copy_value %0
  ...
  last_use_of %0
  destroy_value %0
  // other instructions
```

The benefit of this optimization is that it can enable copy-propagation by moving destroys above deinit barries and access scopes.
2024-12-10 16:28:11 +01:00