The LoadableByAddress pass rewrites alloc_stack instructions when their element
type changes (e.g., a function parameter convention changes from @guaranteed to
@in_guaranteed for large/opaque types). However, it was passing the original
SILDebugVariable info through unchanged. When the VarInfo has an explicit Type
field set this creates a mismatch between the SSA type and the debug type,
causing a SIL verifier failure.
In this patch, I just change the pass to update the alloc_stack as
appropriate. I verified that this cannot happen with debug_value since we do not
store the extra type info in it if we have an object typed thing. Since
loadable_by_address only changes objects -> addresses, it can never happen.
rdar://164268891
rdar://167713693
The LoadableByAddress pass recognizes large loadable types in borrow accessors and returns them by @guaranteed_address.
This prevents stack allocations and unnecessary copies.
Co-authored-by: Meghana Gupta <meghana_gupta@apple.com>
Computing the explosion schema for large types can be expensive.
E.g the following example would spend multiple seconds to compute the
explosion scheme for the array type. It is not worth adding the
complexity to have a special case explosion schema that handles types
like that since exploding a value like that is going to be detrimental.
```
struct Test {
private var values: [0xfffffff of [UInt32]] =
InlineArray(repeating: [])
}
```
rdar://165202495
For example the pattern:
```
%e = load %1 : SomeEnum
switch_enum %e
```
The switch_enum_addr should reuse the load's address operand instead of
creating a new location for the SSA value of %e.
While we are there also don't create a new stack location for extracting payload
in a switch_enum_addr case target basic block if that extracted payload is not
used. That is if the basic block arguments in all switch target blocks are
unused in the switch_enum version.
```
switch_enum %enum, case #Optional.some!enumelt: bb1,
case #Optional.none!enumelt: bb2
bb2(%payload : $Payload):
// unused %payload value
```
rdar://156602951
We insert end_cow_mutation_addr for lifetime dependent values dependent on mutable addresses.
end_cow_mutation_addr can be simplified to end_cow_mutation after other optimizations like inlining, specialization etc
This PR adds an instruction simplification to transform end_cow_mutation_addr to end_cow_mutation.
This can enable array optimizations which look for end_cow_mutation.
This is a value operation that can work just fine on lowered types,
so there's no need to carry along a formal type. Make the value/address
duality clearer, and enforce it in the verifier.
Create two versions of the following functions:
isConsumedParameter
isGuaranteedParameter
SILParameterInfo::isConsumed
SILParameterInfo::isGuaranteed
SILArgumentConvention::isOwnedConvention
SILArgumentConvention::isGuaranteedConvention
These changes will be needed when we add a new convention for
non-trivial C++ types as the functions will return different answers
depending on whether they are called for the caller or the callee. This
commit doesn't change any functionality.
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)
It needs to match with the (large loadable) lowered closure type in the rest of
the program: Large types in the signature need to be passed indirectly.
rdar://127367321
An unchecked_trivial_bit_cast can go from a bigger type to a smaller
type. Therefore we must allocate stack storage for the operand type
rather than the result type. Otherwise, we can end up storing bigger
values into smaller storage -- not good.
rdar://128086028
LoadableByAddress was losing debug info, including at -Onone.
When converting a load-store pair to a copy_addr, the debug info
attached to the load was not salvaged.
Additionally, the wrong scope was being attached to other debug
values.
They can lower to a set of i64 registers we consider small but exploded
to (manifested as SSA) registers they will cause significant code bloat.
rdar://125265576
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
Functions with c convention can have large direct arguments that are not
re-written by the LoadableByAddress pass before they get to reg2Mem
optimization.
https://github.com/apple/swift/issues/71757
In preparation for inserting mark_dependence instructions for lifetime
dependencies early, immediately after SILGen. That will simplify the
implementation of borrowed arguments.
Marking them unresolved is needed to make OSSA verification
conservative until lifetime dependence diagnostics runs.