Commits

Michael Gottesman committed 4cb9eb72f49
[rc-id] Ensure that the reforming enum analysis properly handles no-payload incoming values. 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