Unlike non-ossa, ossa's switch_enum accepts an argument for the default case
When all other cases are unreachable, replace the default block's phi with
the switch_enum's operand and transform the switch_enum to a branch.
Fixes rdar://139441002
DCE inserts end_borrow at phi operands when a guaranteed phi becomes dead.
This should be done for reborrows which end the lifetime of the incoming value.
The existing check was not accurate and ended up inserting end_borrow for forwarded values as well.
Fixes rdar://139283745
This ended up in creating a lot of Array functions, even if a program didn't use Array at all.
Now, only add specialization attributes if a function is already there.
Otherwise remember the attributes and add them to a function once it is created.
MandatoryPerformanceOptimizations already did most of the vtable specialization work.
So it makes sense to remove the VTableSpecializerPass completely and do everything in MandatoryPerformanceOptimizations.
If a single native value is bridged multiple times, it cannot be
consumed without other changes. One option would be to copy it. The
other option is taken here: sink the destroy of the native value to
after the apply and have the outlined function take the value
guaranteed.
rdar://134198292
The old analysis pass doesn't take into account profile data, nor does
it consider post-dominance. It primarily dealt with _fastPath/_slowPath.
A block that is dominated by a cold block is itself cold. That's true
whether it's forwards or backwards dominance.
We can also consider a call to any `Never` returning function as a
cold-exit, though the block(s) leading up to that call may be executed
frequently because of concurrency. For now, I'm ignoring the concurrency
case and assuming it's cold. To make use of this "no return" prediction,
use the `-enable-noreturn-prediction` flag, which is currently off by
default.
Unknown uses of raw pointers should not result in bailing out when an
address is lexical--the destroy of the address will already not be
hoisted over any instructions which may access pointers. If the address
is not lexical however (such as any address when lexical lifetimes are
disabled), that rationale does not apply, so unknown uses of raw
pointers must cause hoisting to bail.
rdar://133969821
If constant folding a switch_enum ends up in branching to a no-payload case, the enum value still needs to be destroyed to satisfy the ownership verifier.
https://github.com/swiftlang/swift/issues/74903
rdar://131726690
The main changes are:
*) Rewrite everything in swift. So far, parts of memory-behavior analysis were already implemented in swift. Now everything is done in swift and lives in `AliasAnalysis.swift`. This is a big code simplification.
*) Support many more instructions in the memory-behavior analysis - especially OSSA instructions, like `begin_borrow`, `end_borrow`, `store_borrow`, `load_borrow`. The computation of end_borrow effects is now much more precise. Also, partial_apply is now handled more precisely.
*) Simplify and reduce type-based alias analysis (TBAA). The complexity of the old TBAA comes from old days where the language and SIL didn't have strict aliasing and exclusivity rules (e.g. for inout arguments). Now TBAA is only needed for code using unsafe pointers. The new TBAA handles this - and not more. Note that TBAA for classes is already done in `AccessBase.isDistinct`.
*) Handle aliasing in `begin_access [modify]` scopes. We already supported truly immutable scopes like `begin_access [read]` or `ref_element_addr [immutable]`. For `begin_access [modify]` we know that there are no other reads or writes to the access-address within the scope.
*) Don't cache memory-behavior results. It turned out that the hit-miss rate was pretty bad (~ 1:7). The overhead of the cache lookup took as long as recomputing the memory behavior.
Fixes a crash in case of an inner class (with no generic parameters), which is nested inside another generic type, like
```
struct G<T> {
class Inner {}
}
```
rdar://131311511