In a bunch of use-cases we use stripSinglePredecessorArgs to eliminate this
case. There is no reason to assume that this is being done in the caller of
RCIdentity. Lets make sure that we handle this case here.
rdar://24156136
This improves the quality of code but more importantly makes it easier to ensure
that new terminators are handled in this code since all of the switches are now
covered switches.
These aren't really orthogonal concerns--you'll never have a @thick @cc(objc_method), or an @objc_block @cc(witness_method)--and we have gross decision trees all over the codebase that try to hopscotch between the subset of combinations that make sense. Stop the madness by eliminating AbstractCC and folding its states into SILFunctionTypeRepresentation. This cleans up a ton of code across the compiler.
I couldn't quite eliminate AbstractCC's information from AST function types, since SIL type lowering transiently created AnyFunctionTypes with AbstractCCs set, even though these never occur at the source level. To accommodate type lowering, allow AnyFunctionType::ExtInfo to carry a SILFunctionTypeRepresentation, and arrange for the overlapping representations to share raw values.
In order to avoid disturbing test output, AST and SILFunctionTypes are still printed and parsed using the existing @thin/@thick/@objc_block and @cc() attributes, which is kind of gross, but lets me stage in the real source-breaking change separately.
Swift SVN r27095
One common problem in swift code is the "reforming enum problem". What
happens here is that we have some enum %0 : $Optional<T> and we break it
apart and reform it as a new enum as in the following:
bb9:
...
switch_enum %0 : $Optional<T>, #Optional.None: bb10,
#Optional.Some: bb11
bb10:
%1 = enum $Optional<U>, #Optional.None
br bb12(%1 : $Optional<U>)
bb11:
%2 = some_cast_to_u %0 : ...
%3 = enum $Optional<U>, #Optional.Some, %2 : $U
br bb12(%3 : $Optional<U>)
bb12(%4 : $Optional<U>):
retain_value %0 : $Optional<T> // id %5
release_value %4 : $Optional<U> // id %6
We really would like to know that a retain on %4 is equivalent to a
retain on %0 so we can eliminate the retain, release pair. To be able to
do that safely, we need to know that along all paths %0 and %4 either:
1. Both refer to the same RCIdentity directly. An example of this is the
edge from bb11 -> bb12).
2. Both refer to the "null" RCIdentity (i.e. do not have a payload). An
example of this is the edge from bb10 -> bb12.
Only in such cases is it safe to match up %5, %6 and eliminate them. If
this is not true along all paths like in the following:
bb9:
...
cond_br %foo, bb10, bb11
bb10:
%1 = enum $Optional<U>, #Optional.None
br bb12(%1 : $Optional<U>)
bb11:
%2 = some_cast_to_u %0 : ...
%3 = enum $Optional<U>, #Optional.Some, %2 : $U
br bb12(%3 : $Optional<U>)
bb12(%4 : $Optional<U>):
retain_value %0 : $Optional<T> // id %5
release_value %4 : $Optional<U> // id %6
then we may have that %0 is always non-payloaded coming into bb12. Then
by matching up %0 and %4, if we go from bb9 -> bb11, we will lose a
retain.
Perf Changes:
TITLE..................OLD...........NEW...........NEW/OLD
LevenshteinDistance....1398195.00....1177397.00....0.84
Memset.................26541.00......23701.00......0.89
CaptureProp............5603.00.......5031.00.......0.90
ImageProc..............1281.00.......1196.00.......0.93
InsertionSort..........109828.00.....104129.00.....0.95
StringWalk.............6813.00.......7456.00.......1.09
Chars..................27182.00......30443.00......1.12
The StringWalk, Chars are both reproducible for me. When I turn back on parts of
the recursion (I took the recursion out to make this change more conservative),
the Chars regression goes away, but the StringWalk stays. I have not had a
chance to look at what is going on with StringWalk.
rdar://19724405
Swift SVN r25339
SILFunction::hasSelfArgument() returns true if the SILFunction has a
calling convention with self.
SILArgument::isSelf() returns true if the SILArgument is the last
argument of the first BB of a function for which
SILFunction::hasSelfArgument() is true.
Swift SVN r22378
SILArgument::getIncomingValues() takes in an out array parameter and attempts to
gather up all values from the SILArguments parents predecessors whose value the
SILArgument could take on.
This will let me refactor the single predecessor handling code to also handle
multiple predecessors in a simple way.
Swift SVN r21864