Files
swift-mirror/test/SILOptimizer/definite_init_tuple.sil
Slava Pestov 50963451b8 DI: Handle instructions that initialize multiple tuple elements
DI had trouble with this pattern:

  %s = struct_element_addr ...
  %t0 = tuple_element_addr %s, 0
  %t1 = tuple_element_addr %s, 1
  %f = function_ref ...
  apply %f(%t0, %t1)

This is because the NonLoadUses map only stored a single use of a
tuple element per instruction, preventing instructions such as
'apply' from being able to use multiple tuple elements.

In other cases where this comes up, such as with 'assign' and
'copy_addr', DI scalarizes the tuple operation by projecting
each component, however clearly this can't be easily done with
an 'apply'.

Instead, we can get DI out of the business of scalarization, at
least for instructions which are known to perform an unconditional
initialization.

We do this by changing the NonLoadUses map to store a vector of
DIMemoryUse IDs instead of a single value.
2020-10-10 23:00:03 -04:00

27 lines
1.1 KiB
Plaintext

// RUN: %target-sil-opt -enable-sil-verify-all %s -definite-init -raw-sil-inst-lowering
import Builtin
import Swift
import SwiftShims
struct S<T> {
var x: (T, T)
}
sil [ossa] @$s19definite_init_tuple1SV1xx_xtvpfi : $@convention(thin) <T> () -> (@out T, @out T)
sil [ossa] @$s19definite_init_tuple1SVACyxGycfC : $@convention(method) <T> (@thin S<T>.Type) -> @out S<T> {
bb0(%0 : $*S<T>, %1 : $@thin S<T>.Type):
%2 = alloc_box $<τ_0_0> { var S<τ_0_0> } <T>, var, name "self"
%3 = mark_uninitialized [rootself] %2 : $<τ_0_0> { var S<τ_0_0> } <T>
%4 = project_box %3 : $<τ_0_0> { var S<τ_0_0> } <T>, 0
%5 = struct_element_addr %4 : $*S<T>, #S.x
%6 = function_ref @$s19definite_init_tuple1SV1xx_xtvpfi : $@convention(thin) <τ_0_0> () -> (@out τ_0_0, @out τ_0_0)
%7 = tuple_element_addr %5 : $*(T, T), 0
%8 = tuple_element_addr %5 : $*(T, T), 1
%9 = apply %6<T>(%7, %8) : $@convention(thin) <τ_0_0> () -> (@out τ_0_0, @out τ_0_0)
copy_addr %4 to [initialization] %0 : $*S<T>
destroy_value %3 : $<τ_0_0> { var S<τ_0_0> } <T>
%12 = tuple ()
return %12 : $()
}