DCE may enqueue a value for lifetime completion and later on erase the
instruction that defines that value. When erasing an instruction, erase
each of its results from the collection of values to complete.
rdar://141560546
For a function to have complete lifetimes, the lifetime of every def in
the function which is backwards-reachable from a dead-end block must be
completed.
Previously, every def in every block which appears in the post-order of
the function's blocks is completed. This was not enough: defs in
"unreachable blocks" (i.e. those which aren't forwards-reachable from
the function entry) must be completed too, and such blocks do not appear
in the function's post-order.
Here, defs in unreachable blocks are be completed too. Such defs must
also be completed in relative post-order. To do this, roots for the
non-entry post-orders must be found.
rdar://141197164
Don't form a set of unreachable blocks, we only need to check whether
any given block is unreachable, which can be done via
`ReachableBlocks::isVisited`.
While hoisting check_subscript call in ossa, isNativeTypeChecked call is also hoisted.
The array value used in the isNativeTypeChecked may not be available if it's lifetime
had ended before. Proactively set the array value of the isNativeTypeChecked call to
the array value in the check_subscript call.
There are not pre-specialized parts of the stdlib in embedded mode.
Fixes a compiler crash.
Unfortunately I con't have a test case for this.
https://github.com/swiftlang/swift/issues/78167
Canonicalize a `fix_lifetime` from an address to a `load` + `fix_lifetime`:
```
%1 = alloc_stack $T
...
fix_lifetime %1
```
->
```
%1 = alloc_stack $T
...
%2 = load %1
fix_lifetime %2
```
This transformation is done for `alloc_stack` and `store_borrow` (which always has an `alloc_stack` operand).
The benefit of this transformation is that it enables other optimizations, like mem2reg.
This peephole optimization was already done in SILCombine, but it didn't handle store_borrow.
A good opportunity to make an instruction simplification out of it.
This is part of fixing regressions when enabling OSSA modules:
rdar://140229560
This is needed after running the SSAUpdater for an existing OSSA value, because the updater can
insert unnecessary phis in the middle of the original liverange which breaks up the original
liverange into smaller ones:
```
%1 = def_of_owned_value
%2 = begin_borrow %1
...
br bb2(%1)
bb2(%3 : @owned $T): // inserted by SSAUpdater
...
end_borrow %2 // use after end-of-lifetime!
destroy_value %3
```
It's not needed to run this utility if SSAUpdater is used to create a _new_ OSSA liverange.
* Remove dead `load_borrow` instructions (replaces the old peephole optimization in SILCombine)
* If the `load_borrow` is followed by a `copy_value`, combine both into a `load [copy]`