Which consists of
* removing redundant `address_to_pointer`-`pointer_to_address` pairs
* optimize `index_raw_pointer` of a manually computed stride to `index_addr`
* remove or increase the alignment based on a "assumeAlignment" builtin
This is a big code cleanup but also has some functional differences for the `address_to_pointer`-`pointer_to_address` pair removal:
* It's not done if the resulting SIL would result in a (detectable) use-after-dealloc_stack memory lifetime failure.
* It's not done if `copy_value`s must be inserted or borrow-scopes must be extended to comply with ownership rules (this was the task of the OwnershipRAUWHelper).
Inserting copies is bad anyway.
Extending borrow-scopes would only be required if the original lifetime of the pointer extends a borrow scope - which shouldn't happen in save code. Therefore this is a very rare case which is not worth handling.
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