Specifically, improved debug info retention in:
* tryReplaceRedundantInstructionPair,
* splitAggregateLoad,
* TempLValueElimination,
* Mem2Reg,
* ConstantFolding.
The changes to Mem2Reg allow debug info to be retained in the case tested by
self-nostorage.swift in -O builds, so we have just enabled -O in that file
instead of writing a new test for it.
We attempted to add a case to salvageDebugInfo for unchecked_enum_data, but it
caused crashes in Linux CI that we were not able to reproduce.
Since the time that lifetimes in `alloc_stack [lexical]` began to be
represented after promotion by `move_value [lexical]`s, the
`endOwnedLexicalLifetimeBeforeInst` is just an assertion. In the
future, lifetimes of values never destroyed that leak into dead end
blocks should be completed by OSSACompleteLifetime. For now, just
delete this code.
The lifetimes of the values stored into these locations may need to be
completed: if a trivial case of a non-trivial enum is written to the
location, its lifetime must be completed.
rdar://158139991
Enum types may have incomplete lifetimes in address form for trivial case values. When promoted to value form, they will end up with incomplete ossa lifetimes.
Because we know that the incomplete enum values are trivial enum cases we complete their lifetimes with `end_lifetime` instead of `destroy_value`.
This is especially important for Embedded Swift where we are not allowed to insert destroys which were not there before.
Fixes a compiler crash in Embedded Swift caused by de-virtualizing such an inserted destroy and ending up with a non-specialized generic function.
rdar://158807801
In OSSA, the result of an `unchecked_bitwise_cast` must immediately be
copied or `unchecked_bitwise_cast`'d again. In particular, it is not
permitted to borrow it. For example, the result can't be borrowed for
the purpose of performinig additional projections (`struct_extract`,
`tuple_extract`) on the borrowed value. Consequently, we cannot promote
an address if such a promotion would result in such a pattern. That
means we can't promote an address `%addr` which is used like
`struct_element_addr(unchecked_addr_cast(%addr))` or
`tuple_element_addr(unchecked_addr_cast(%addr))`. We can still promote
`unchecked_addr_cast(unchecked_addr_cast(%addr))`.
In ownership-lowered SIL, this doesn't apply and we can still promote
address with such projections.
rdar://153693915
StackAllocationPromoter::pruneAllocStackUsage substitutes loads/stores of alloc_stack
with values. For some reason isLoadFromStack was bailing out for load_borrows with
reborrows leaving them to be fixed up by fixBranchesAndUses which uses live in value
from predecessors for substitution which is obviosly incorrect the block containing
the load_borrow has a store before it.
Fixes rdar://145834542
When we have a non trivial enum lexical stack location, and we store a
none value, after mem2reg we can end up with an ownership error
because of the leaking move_value [lexical].
This change avoids creating move_value [lexical] for such stores.
Do the same when we have store_borrow of none values, even though there
is no ownership error in this case, handle it like store for consistency
Although I don't plan to bring over new assertions wholesale
into the current qualification branch, it's entirely possible
that various minor changes in main will use the new assertions;
having this basic support in the release branch will simplify that.
(This is why I'm adding the includes as a separate pass from
rewriting the individual assertions)
For years, optimizer engineers have been hitting a common bug caused by passes
assuming all SILValues have a parent function only to be surprised by SILUndef.
Generally we see SILUndef not that often so we see this come up later in
testing. This patch eliminates that problem by making SILUndef uniqued at the
function level instead of the module level. This ensures that it makes sense for
SILUndef to have a parent function, eliminating this possibility since we can
define an API to get its parent function.
rdar://123484595
Mem2Reg may materialize the unique instance of empty types when
promoting an address of that empty type. Previously, it was required
that the top-most type in the aggregate be empty. This failed to handle
the case where a projection of empty type from a non-empty aggregate was
promoted.
For example:
```
%addr = alloc_stack $((), C)
%empty_addr = tuple_element_addr $addr : $*((), C), 0
%addr = load %empty_addr : $*()
```
where `C` is some non-empty type.
Here, that case is handled by using `undef` for each non-empty field in
the projected-from aggregate.
In the example,
```
%empty = tuple ()
%tuple = tuple (%empty : $(), undef : $C)
%empty_again = tuple_extract %tuple : $((), C), 0
```
rdar://122417297
We allow none values to be stored to a non-trivial enum.
For such store_borrow, `LiveValues::forValues` used
an Owned storage type, but endLexicalLifetime expected Guaranteed
storage type, leading to a compiler crash.
For store_borrow, use the LiveValues::forGuaranteed and for store
use LiveValues::forOwned to avoid this.
Fixes rdar://114390472
To eliminate copies which become newly spurious, Mem2Reg canonicalizes
the lifetimes of values that are stored and of newly introduced phis
after rewriting.
It's possible, however, for the values that are stored to be deleted
during canonicalization if a value and its copy are both stored to the
address. Such values must not be canonicalized. So check whether
values have been erased before canonicalizing them.
rdar://113762355
Corrected the comments describing what the
`promoteSingleBlockAllocation` and `promoteMultiBlockAllocation`
functions do since they were no longer accurate.
Previously there were the functions `promoteSingleAllocation` and
`removeSingleBlockAllocation`. The distinction between these based on
the name alone is a bit subtle. Shortened the name of
`promoteSingleAllocation` to `promoteAllocation`.
Reformatting everything now that we have `llvm` namespaces. I've
separated this from the main commit to help manage merge-conflicts and
for making it a bit easier to read the mega-patch.