mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
843 lines
32 KiB
Plaintext
843 lines
32 KiB
Plaintext
// RUN: %target-sil-opt -enforce-exclusivity=none -enable-sil-verify-all -cowarray-opt %s | %FileCheck %s
|
|
|
|
// Declare this SIL to be canonical because some tests break raw SIL
|
|
// conventions. e.g. address-type block args. -enforce-exclusivity=none is also
|
|
// required to allow address-type block args in canonical SIL.
|
|
sil_stage canonical
|
|
|
|
import Builtin
|
|
import Swift
|
|
|
|
/////////////
|
|
// Utility //
|
|
/////////////
|
|
|
|
struct ArrayIntBuffer {
|
|
var storage : Builtin.NativeObject
|
|
}
|
|
|
|
struct MyArray<T> {
|
|
var buffer : ArrayIntBuffer
|
|
}
|
|
|
|
struct MyStruct {
|
|
}
|
|
|
|
class MyArrayContainer<T> {
|
|
var array: MyArray<T>
|
|
|
|
init()
|
|
deinit
|
|
}
|
|
|
|
struct Container {
|
|
var array: MyArray<MyStruct>
|
|
}
|
|
|
|
struct ContainerContainer {
|
|
var container: Container
|
|
}
|
|
|
|
class MyArrayStorage {
|
|
@_hasStorage var header: Int
|
|
|
|
init()
|
|
deinit
|
|
}
|
|
|
|
sil [_semantics "array.make_mutable"] @array_make_mutable : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
sil [_semantics "array.end_mutation"] @array_end_mutation : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
sil [_semantics "array.get_count"] @guaranteed_array_get_count : $@convention(method) (@guaranteed MyArray<MyStruct>) -> Int
|
|
sil [_semantics "array.get_capacity"] @guaranteed_array_get_capacity : $@convention(method) (@guaranteed MyArray<MyStruct>) -> Int
|
|
sil [_semantics "array.mutate_unknown"] @array_unknown_mutate : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
|
|
// An unknown user
|
|
sil @unknown : $@convention(thin) () -> ()
|
|
|
|
///////////
|
|
// Tests //
|
|
///////////
|
|
|
|
// CHECK-LABEL: sil @simple_hoist
|
|
// CHECK: bb0([[ARRAY:%[0-9]+]]
|
|
// CHECK: [[MM:%[0-9]+]] = function_ref @array_make_mutable
|
|
// CHECK: apply [[MM]]([[ARRAY]]
|
|
// CHECK: [[EM:%[0-9]+]] = function_ref @array_end_mutation
|
|
// CHECK: apply [[EM]]([[ARRAY]]
|
|
// CHECK: bb1:
|
|
// CHECK: apply [[MM]]([[ARRAY]]
|
|
// CHECK: apply [[EM]]([[ARRAY]]
|
|
// CHECK: } // end sil function 'simple_hoist'
|
|
sil @simple_hoist : $@convention(thin) (@inout MyArray<MyStruct>, @inout Builtin.Int1) -> () {
|
|
bb0(%0 : $*MyArray<MyStruct>, %1 : $*Builtin.Int1):
|
|
debug_value %0 : $*MyArray<MyStruct>, expr op_deref
|
|
%2 = load %0 : $*MyArray<MyStruct>
|
|
br bb1
|
|
|
|
bb1:
|
|
%5 = function_ref @array_make_mutable : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
%6 = apply %5(%0) : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
%7 = function_ref @array_end_mutation : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
%8 = apply %7(%0) : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
cond_br undef, bb1, bb2
|
|
|
|
bb2:
|
|
%r = tuple()
|
|
return %r : $()
|
|
}
|
|
|
|
|
|
// CHECK-LABEL: sil @hoist_ignoring_paired_retain_release_and_hoist
|
|
// CHECK: bb0([[ARRAY:%[0-9]+]]
|
|
// CHECK: [[MM:%[0-9]+]] = function_ref @array_make_mutable
|
|
// CHECK: apply [[MM]]([[ARRAY]]
|
|
// CHECK: [[EM:%[0-9]+]] = function_ref @array_end_mutation
|
|
// CHECK: apply [[EM]]([[ARRAY]]
|
|
// CHECK: bb1:
|
|
// CHECK: retain
|
|
// CHECK: release
|
|
// CHECK: apply [[MM]]([[ARRAY]]
|
|
// CHECK: apply [[EM]]([[ARRAY]]
|
|
// CHECK: cond_br {{.*}}, bb1
|
|
// CHECK: } // end sil function 'hoist_ignoring_paired_retain_release_and_hoist'
|
|
sil @hoist_ignoring_paired_retain_release_and_hoist : $@convention(thin) (@inout MyArray<MyStruct>, @inout Builtin.Int1) -> () {
|
|
bb0(%0 : $*MyArray<MyStruct>, %1 : $*Builtin.Int1):
|
|
%2 = load %0 : $*MyArray<MyStruct>
|
|
br bb1
|
|
|
|
bb1:
|
|
retain_value %2 : $MyArray<MyStruct>
|
|
%3 = load %1 : $*Builtin.Int1
|
|
%4 = load %0 : $*MyArray<MyStruct>
|
|
release_value %2 : $MyArray<MyStruct>
|
|
%5 = function_ref @array_make_mutable : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
%6 = apply %5(%0) : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
%7 = function_ref @array_end_mutation : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
%8 = apply %7(%0) : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
cond_br %3, bb1, bb2
|
|
|
|
bb2:
|
|
%r = tuple()
|
|
return %r : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @hoist_blocked_by_unpaired_retain_release_1
|
|
// CHECK: bb0(
|
|
// CHECK-NOT: apply
|
|
// CHECK: bb1:
|
|
// CHECK: retain_value
|
|
// CHECK: [[MM:%.*]] = function_ref @array_make_mutable
|
|
// CHECK: apply [[MM]]
|
|
// CHECK: cond_br {{.*}}, bb1
|
|
sil @hoist_blocked_by_unpaired_retain_release_1 : $@convention(thin) (@inout MyArray<MyStruct>, @inout Builtin.Int1) -> () {
|
|
bb0(%0 : $*MyArray<MyStruct>, %1 : $*Builtin.Int1):
|
|
%2 = load %0 : $*MyArray<MyStruct>
|
|
br bb1
|
|
|
|
bb1:
|
|
retain_value %2 : $MyArray<MyStruct>
|
|
%3 = load %1 : $*Builtin.Int1
|
|
%4 = load %0 : $*MyArray<MyStruct>
|
|
%5 = function_ref @array_make_mutable : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
%6 = apply %5(%0) : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
%7 = function_ref @array_end_mutation : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
%8 = apply %7(%0) : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
cond_br %3, bb1, bb2
|
|
|
|
bb2:
|
|
%r = tuple()
|
|
return %r : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @hoist_blocked_by_unpaired_retain_release_2
|
|
// CHECK: bb0(
|
|
// CHECK-NOT: apply
|
|
// CHECK: bb1:
|
|
// CHECK: retain_value
|
|
// CHECK: [[MM:%.*]] = function_ref @array_make_mutable
|
|
// CHECK: apply [[MM]]
|
|
// CHECK: cond_br {{.*}}, bb1
|
|
sil @hoist_blocked_by_unpaired_retain_release_2 : $@convention(thin) (@inout MyArray<MyStruct>, @inout Builtin.Int1) -> () {
|
|
bb0(%0 : $*MyArray<MyStruct>, %1 : $*Builtin.Int1):
|
|
br bb1
|
|
|
|
bb1:
|
|
%10 = load %0 : $*MyArray<MyStruct>
|
|
%11 = load %0 : $*MyArray<MyStruct>
|
|
%12 = struct_extract %10 : $MyArray<MyStruct>, #MyArray.buffer
|
|
%13 = struct_extract %11 : $MyArray<MyStruct>, #MyArray.buffer
|
|
retain_value %12 : $ArrayIntBuffer
|
|
retain_value %13 : $ArrayIntBuffer
|
|
release_value %13 : $ArrayIntBuffer
|
|
%3 = load %1 : $*Builtin.Int1
|
|
%4 = load %0 : $*MyArray<MyStruct>
|
|
%5 = function_ref @array_make_mutable : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
%6 = apply %5(%0) : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
%7 = function_ref @array_end_mutation : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
%8 = apply %7(%0) : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
cond_br %3, bb1, bb2
|
|
|
|
bb2:
|
|
%r = tuple()
|
|
return %r : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @hoist_not_blocked_by_unpaired_release
|
|
// CHECK: bb0([[ARRAY:%[0-9]+]]
|
|
// CHECK: [[MM:%[0-9]+]] = function_ref @array_make_mutable
|
|
// CHECK: apply [[MM]]([[ARRAY]]
|
|
// CHECK: [[EM:%[0-9]+]] = function_ref @array_end_mutation
|
|
// CHECK: apply [[EM]]([[ARRAY]]
|
|
// CHECK: bb1:
|
|
// CHECK: load
|
|
// CHECK: load
|
|
// CHECK: release
|
|
// CHECK: apply [[MM]]([[ARRAY]]
|
|
// CHECK: apply [[EM]]([[ARRAY]]
|
|
// CHECK: } // end sil function 'hoist_not_blocked_by_unpaired_release'
|
|
sil @hoist_not_blocked_by_unpaired_release : $@convention(thin) (@inout MyArray<MyStruct>, @inout Builtin.Int1) -> () {
|
|
bb0(%0 : $*MyArray<MyStruct>, %1 : $*Builtin.Int1):
|
|
%2 = load %0 : $*MyArray<MyStruct>
|
|
br bb1
|
|
|
|
bb1:
|
|
%3 = load %1 : $*Builtin.Int1
|
|
%4 = load %0 : $*MyArray<MyStruct>
|
|
release_value %2 : $MyArray<MyStruct>
|
|
%5 = function_ref @array_make_mutable : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
%6 = apply %5(%0) : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
%7 = function_ref @array_end_mutation : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
%8 = apply %7(%0) : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
cond_br %3, bb1, bb2
|
|
|
|
bb2:
|
|
%r = tuple()
|
|
return %r : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @dont_hoist_if_executed_conditionally
|
|
// CHECK: bb0({{.*}}):
|
|
// CHECK-NOT: apply
|
|
// CHECK: bb1({{.*}}):
|
|
// CHECK: bb2:
|
|
// CHECK: apply
|
|
// CHECK: bb3:
|
|
sil @dont_hoist_if_executed_conditionally : $@convention(thin) (@inout MyArray<MyStruct>, @inout Builtin.Int1) -> MyArray<MyStruct> {
|
|
bb0(%0 : $*MyArray<MyStruct>, %1 : $*Builtin.Int1):
|
|
debug_value %0 : $*MyArray<MyStruct>, expr op_deref
|
|
%2 = load %0 : $*MyArray<MyStruct>
|
|
br bb1(%2 : $MyArray<MyStruct>)
|
|
|
|
bb1(%p1 : $MyArray<MyStruct>):
|
|
cond_br undef, bb2, bb3
|
|
|
|
bb2:
|
|
// If this block is never taken, then hoisting to bb0 would change the value of %p3.
|
|
%5 = function_ref @array_make_mutable : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
%6 = apply %5(%0) : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
%7 = function_ref @array_end_mutation : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
%8 = apply %7(%0) : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
%9 = load %0 : $*MyArray<MyStruct>
|
|
br bb4(%9 : $MyArray<MyStruct>)
|
|
|
|
bb3:
|
|
br bb4(%p1 : $MyArray<MyStruct>)
|
|
|
|
bb4(%p2 : $MyArray<MyStruct>):
|
|
cond_br undef, bb1(%p2 : $MyArray<MyStruct>), bb5(%p2 : $MyArray<MyStruct>)
|
|
|
|
bb5(%p3 : $MyArray<MyStruct>):
|
|
return %p3 : $MyArray<MyStruct>
|
|
}
|
|
|
|
// CHECK-LABEL: sil @cow_should_ignore_mark_dependence_addrproj_use : $@convention(thin) (@inout MyArray<MyStruct>, @inout Builtin.Int1) -> () {
|
|
// CHECK: bb0([[ARRAY:%[0-9]+]]
|
|
// CHECK: [[MM:%[0-9]+]] = function_ref @array_make_mutable
|
|
// CHECK: apply [[MM]]([[ARRAY]]
|
|
// CHECK: [[EM:%[0-9]+]] = function_ref @array_end_mutation
|
|
// CHECK: apply [[EM]]([[ARRAY]]
|
|
// CHECK: bb1:
|
|
// CHECK: retain
|
|
// CHECK: load
|
|
// CHECK: load
|
|
// CHECK: release
|
|
// CHECK: apply [[MM]]([[ARRAY]]
|
|
// CHECK: apply [[EM]]([[ARRAY]]
|
|
// CHECK: mark_dependence
|
|
// CHECK: } // end sil function 'cow_should_ignore_mark_dependence_addrproj_use'
|
|
sil @cow_should_ignore_mark_dependence_addrproj_use : $@convention(thin) (@inout MyArray<MyStruct>, @inout Builtin.Int1) -> () {
|
|
bb0(%0 : $*MyArray<MyStruct>, %1 : $*Builtin.Int1):
|
|
%999 = struct_element_addr %0 : $*MyArray<MyStruct>, #MyArray.buffer
|
|
%9999 = struct_element_addr %999 : $*ArrayIntBuffer, #ArrayIntBuffer.storage
|
|
%99999 = load %9999 : $*Builtin.NativeObject
|
|
%2 = load %0 : $*MyArray<MyStruct>
|
|
br bb1
|
|
|
|
bb1:
|
|
retain_value %2 : $MyArray<MyStruct>
|
|
%3 = load %1 : $*Builtin.Int1
|
|
%4 = load %0 : $*MyArray<MyStruct>
|
|
release_value %2 : $MyArray<MyStruct>
|
|
%5 = function_ref @array_make_mutable : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
%6 = apply %5(%0) : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
%7 = function_ref @array_end_mutation : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
%8 = apply %7(%0) : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
mark_dependence %1 : $*Builtin.Int1 on %99999 : $Builtin.NativeObject
|
|
cond_br %3, bb1, bb2
|
|
|
|
bb2:
|
|
%r = tuple()
|
|
return %r : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @cow_should_ignore_mark_dependence_value : $@convention(thin) (@inout MyArray<MyStruct>, @inout Builtin.Int1) -> () {
|
|
// CHECK: bb0([[ARRAY:%[0-9]+]]
|
|
// CHECK: [[MM:%[0-9]+]] = function_ref @array_make_mutable
|
|
// CHECK: apply [[MM]]([[ARRAY]]
|
|
// CHECK: [[EM:%[0-9]+]] = function_ref @array_end_mutation
|
|
// CHECK: apply [[EM]]([[ARRAY]]
|
|
// CHECK: bb1:
|
|
// CHECK: retain
|
|
// CHECK: load
|
|
// CHECK: load
|
|
// CHECK: release
|
|
// CHECK: apply [[MM]]([[ARRAY]]
|
|
// CHECK: apply [[EM]]([[ARRAY]]
|
|
// CHECK: mark_dependence
|
|
// CHECK: } // end sil function 'cow_should_ignore_mark_dependence_value'
|
|
sil @cow_should_ignore_mark_dependence_value : $@convention(thin) (@inout MyArray<MyStruct>, @inout Builtin.Int1) -> () {
|
|
bb0(%0 : $*MyArray<MyStruct>, %1 : $*Builtin.Int1):
|
|
%2 = load %0 : $*MyArray<MyStruct>
|
|
br bb1
|
|
|
|
bb1:
|
|
retain_value %2 : $MyArray<MyStruct>
|
|
%3 = load %1 : $*Builtin.Int1
|
|
%4 = load %0 : $*MyArray<MyStruct>
|
|
release_value %2 : $MyArray<MyStruct>
|
|
%5 = function_ref @array_make_mutable : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
%6 = apply %5(%0) : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
%7 = function_ref @array_end_mutation : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
%8 = apply %7(%0) : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
mark_dependence %1 : $*Builtin.Int1 on %2 : $MyArray<MyStruct>
|
|
cond_br %3, bb1, bb2
|
|
|
|
bb2:
|
|
%r = tuple()
|
|
return %r : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @cow_should_ignore_enum : $@convention(thin) (@inout MyArray<MyStruct>, @inout Builtin.Int1) -> () {
|
|
// CHECK: bb0([[ARRAY:%[0-9]+]]
|
|
// CHECK: [[MM:%[0-9]+]] = function_ref @array_make_mutable
|
|
// CHECK: apply [[MM]]([[ARRAY]]
|
|
// CHECK: [[EM:%[0-9]+]] = function_ref @array_end_mutation
|
|
// CHECK: apply [[EM]]([[ARRAY]]
|
|
// CHECK: bb1:
|
|
// CHECK: retain
|
|
// CHECK: load
|
|
// CHECK: load
|
|
// CHECK: release
|
|
// CHECK: apply [[MM]]([[ARRAY]]
|
|
// CHECK: enum
|
|
// CHECK: mark_dependence
|
|
// CHECK: apply [[EM]]([[ARRAY]]
|
|
// CHECK: } // end sil function 'cow_should_ignore_enum'
|
|
sil @cow_should_ignore_enum : $@convention(thin) (@inout MyArray<MyStruct>, @inout Builtin.Int1) -> () {
|
|
bb0(%0 : $*MyArray<MyStruct>, %1 : $*Builtin.Int1):
|
|
%2 = load %0 : $*MyArray<MyStruct>
|
|
br bb1
|
|
|
|
bb1:
|
|
retain_value %2 : $MyArray<MyStruct>
|
|
%3 = load %1 : $*Builtin.Int1
|
|
%4 = load %0 : $*MyArray<MyStruct>
|
|
release_value %2 : $MyArray<MyStruct>
|
|
%5 = function_ref @array_make_mutable : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
%6 = apply %5(%0) : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
%e = enum $Optional<MyArray<MyStruct>>, #Optional.some!enumelt, %2 : $MyArray<MyStruct>
|
|
mark_dependence %1 : $*Builtin.Int1 on %e : $Optional<MyArray<MyStruct>>
|
|
%7 = function_ref @array_end_mutation : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
%8 = apply %7(%0) : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
cond_br %3, bb1, bb2
|
|
|
|
bb2:
|
|
%r = tuple()
|
|
return %r : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @cow_should_ignore_guaranteed_semantic_call_sequence : $@convention(thin) (@guaranteed MyArrayContainer<MyStruct>, Builtin.NativeObject) -> () {
|
|
// CHECK: bb0
|
|
// CHECK-DAG: [[MM:%[0-9]+]] = function_ref @array_make_mutable : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
// CHECK-DAG: [[EM:%[0-9]+]] = function_ref @array_end_mutation
|
|
// CHECK: apply [[MM]](
|
|
// CHECK: apply [[EM]](
|
|
// CHECK: bb1:
|
|
// CHECK: } // end sil function 'cow_should_ignore_guaranteed_semantic_call_sequence'
|
|
sil @cow_should_ignore_guaranteed_semantic_call_sequence : $@convention(thin) (@guaranteed MyArrayContainer<MyStruct>, Builtin.NativeObject) -> () {
|
|
bb0(%0 : $MyArrayContainer<MyStruct>, %00 : $Builtin.NativeObject):
|
|
%1 = ref_element_addr %0 : $MyArrayContainer<MyStruct>, #MyArrayContainer.array
|
|
%2 = load %1 : $*MyArray<MyStruct>
|
|
%3 = function_ref @guaranteed_array_get_count : $@convention(method) (@guaranteed MyArray<MyStruct>) -> Int
|
|
%4 = function_ref @guaranteed_array_get_capacity : $@convention(method) (@guaranteed MyArray<MyStruct>) -> Int
|
|
%5 = function_ref @unknown : $@convention(thin) () -> ()
|
|
%6 = function_ref @array_make_mutable : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
%7 = function_ref @array_end_mutation : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
br bb1
|
|
|
|
bb1:
|
|
// Simple case. This should hoist.
|
|
retain_value %2 : $MyArray<MyStruct>
|
|
apply %3(%2) : $@convention(method) (@guaranteed MyArray<MyStruct>) -> Int
|
|
apply %4(%2) : $@convention(method) (@guaranteed MyArray<MyStruct>) -> Int
|
|
release_value %2 : $MyArray<MyStruct>
|
|
apply %6(%1) : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
apply %7(%1) : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
cond_br undef, bb1, bb2
|
|
|
|
bb2:
|
|
br bb3
|
|
|
|
bb3:
|
|
// Failure case b/c of use in between release and call.
|
|
retain_value %2 : $MyArray<MyStruct>
|
|
apply %3(%2) : $@convention(method) (@guaranteed MyArray<MyStruct>) -> Int
|
|
apply %4(%2) : $@convention(method) (@guaranteed MyArray<MyStruct>) -> Int
|
|
fix_lifetime %0 : $MyArrayContainer<MyStruct>
|
|
release_value %2 : $MyArray<MyStruct>
|
|
apply %6(%1) : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
apply %7(%1) : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
cond_br undef, bb4, bb3
|
|
|
|
bb4:
|
|
br bb5
|
|
|
|
bb5:
|
|
// Failure case b/c of use in between calls.
|
|
retain_value %2 : $MyArray<MyStruct>
|
|
apply %3(%2) : $@convention(method) (@guaranteed MyArray<MyStruct>) -> Int
|
|
fix_lifetime %0 : $MyArrayContainer<MyStruct>
|
|
apply %4(%2) : $@convention(method) (@guaranteed MyArray<MyStruct>) -> Int
|
|
release_value %2 : $MyArray<MyStruct>
|
|
apply %6(%1) : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
apply %7(%1) : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
cond_br undef, bb5, bb6
|
|
|
|
bb6:
|
|
br bb7
|
|
|
|
bb7:
|
|
// Failure b/c use is in between apply and retain.
|
|
retain_value %2 : $MyArray<MyStruct>
|
|
fix_lifetime %0 : $MyArrayContainer<MyStruct>
|
|
apply %3(%2) : $@convention(method) (@guaranteed MyArray<MyStruct>) -> Int
|
|
apply %4(%2) : $@convention(method) (@guaranteed MyArray<MyStruct>) -> Int
|
|
release_value %2 : $MyArray<MyStruct>
|
|
apply %6(%1) : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
apply %7(%1) : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
cond_br undef, bb7, bb8
|
|
|
|
bb8:
|
|
br bb9
|
|
|
|
bb9:
|
|
// Failure b/c of release_value
|
|
retain_value %00 : $Builtin.NativeObject
|
|
retain_value %2 : $MyArray<MyStruct>
|
|
apply %3(%2) : $@convention(method) (@guaranteed MyArray<MyStruct>) -> Int
|
|
apply %4(%2) : $@convention(method) (@guaranteed MyArray<MyStruct>) -> Int
|
|
release_value %00 : $Builtin.NativeObject
|
|
release_value %2 : $MyArray<MyStruct>
|
|
apply %6(%1) : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
apply %7(%1) : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
cond_br undef, bb9, bb10
|
|
|
|
bb10:
|
|
%r = tuple()
|
|
return %r : $()
|
|
}
|
|
|
|
// CHECK: sil @cow_handle_array_address_load
|
|
// CHECK: bb0([[ARRAY:%[0-9]+]]
|
|
// CHECK: [[MM:%[0-9]+]] = function_ref @array_make_mutable
|
|
// CHECK: apply [[MM]]([[ARRAY]]
|
|
// CHECK: [[EM:%[0-9]+]] = function_ref @array_end_mutation
|
|
// CHECK: apply [[EM]]([[ARRAY]]
|
|
// CHECK: bb1:
|
|
// CHECK: load
|
|
// CHECK: retain
|
|
// CHECK: load
|
|
// CHECK: release
|
|
// CHECK: apply [[MM]]([[ARRAY]]
|
|
// CHECK: enum
|
|
// CHECK: mark_dependence
|
|
// CHECK: apply [[EM]]([[ARRAY]]
|
|
// CHECK: } // end sil function 'cow_handle_array_address_load'
|
|
sil @cow_handle_array_address_load : $@convention(thin) (@inout MyArray<MyStruct>, @inout Builtin.Int1) -> () {
|
|
bb0(%0 : $*MyArray<MyStruct>, %1 : $*Builtin.Int1):
|
|
%2 = load %0 : $*MyArray<MyStruct>
|
|
%3 = struct_element_addr %0 : $*MyArray<MyStruct>, #MyArray.buffer
|
|
%4 = struct_element_addr %3 : $*ArrayIntBuffer, #ArrayIntBuffer.storage
|
|
br bb1
|
|
|
|
bb1:
|
|
%6 = load %4 : $*Builtin.NativeObject
|
|
strong_retain %6 : $Builtin.NativeObject
|
|
%l = load %1 : $*Builtin.Int1
|
|
strong_release %6 : $Builtin.NativeObject
|
|
%10 = function_ref @array_make_mutable : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
%11 = apply %10(%0) : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
%12 = enum $Optional<MyArray<MyStruct>>, #Optional.some!enumelt, %2 : $MyArray<MyStruct>
|
|
%13 = mark_dependence %1 : $*Builtin.Int1 on %12 : $Optional<MyArray<MyStruct>>
|
|
%7 = function_ref @array_end_mutation : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
%8 = apply %7(%0) : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
cond_br %l, bb1, bb2
|
|
|
|
bb2:
|
|
%15 = tuple ()
|
|
return %15 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @cow_type_based_hoisting_retain_release_matching : $@convention(thin) (@guaranteed MyArrayContainer<MyStruct>, Builtin.NativeObject) -> () {
|
|
// CHECK: bb0
|
|
// CHECK: [[F:%.*]] = function_ref @array_make_mutable : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
// CHECK-NOT: apply [[F]](
|
|
// CHECK: bb1:
|
|
// CHECK: apply [[F]](
|
|
// CHECK: bb2:
|
|
// CHECK-NOT: apply [[F]](
|
|
// CHECK: bb3:
|
|
// CHECK: apply [[F]](
|
|
// CHECK: bb4:
|
|
|
|
sil @cow_type_based_hoisting_retain_release_matching : $@convention(thin) (@guaranteed MyArrayContainer<MyStruct>, Builtin.NativeObject) -> () {
|
|
bb0(%0 : $MyArrayContainer<MyStruct>, %00 : $Builtin.NativeObject):
|
|
%1 = ref_element_addr %0 : $MyArrayContainer<MyStruct>, #MyArrayContainer.array
|
|
%2 = load %1 : $*MyArray<MyStruct>
|
|
%3 = function_ref @guaranteed_array_get_count : $@convention(method) (@guaranteed MyArray<MyStruct>) -> Int
|
|
%4 = function_ref @guaranteed_array_get_capacity : $@convention(method) (@guaranteed MyArray<MyStruct>) -> Int
|
|
%5 = function_ref @unknown : $@convention(thin) () -> ()
|
|
%6 = function_ref @array_make_mutable : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
%7 = function_ref @array_unknown_mutate : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
%9 = function_ref @array_end_mutation : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
br bb1
|
|
|
|
bb1:
|
|
retain_value %2 : $MyArray<MyStruct>
|
|
retain_value %00 : $Builtin.NativeObject
|
|
release_value %00: $Builtin.NativeObject
|
|
apply %3(%2) : $@convention(method) (@guaranteed MyArray<MyStruct>) -> Int
|
|
apply %4(%2) : $@convention(method) (@guaranteed MyArray<MyStruct>) -> Int
|
|
release_value %2 : $MyArray<MyStruct>
|
|
apply %6(%1) : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
apply %9(%1) : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
cond_br undef, bb1, bb2
|
|
|
|
bb2:
|
|
br bb3
|
|
|
|
bb3:
|
|
retain_value %2 : $MyArray<MyStruct>
|
|
apply %7(%1) : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
apply %3(%2) : $@convention(method) (@guaranteed MyArray<MyStruct>) -> Int
|
|
apply %4(%2) : $@convention(method) (@guaranteed MyArray<MyStruct>) -> Int
|
|
release_value %2 : $MyArray<MyStruct>
|
|
apply %6(%1) : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
apply %9(%1) : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
cond_br undef, bb3, bb4
|
|
|
|
bb4:
|
|
%8 = tuple()
|
|
return %8 : $()
|
|
}
|
|
|
|
struct _MyBridgeStorage {
|
|
var rawValue : Builtin.BridgeObject
|
|
}
|
|
|
|
struct _My2dArrayBuffer<T> {
|
|
var _storage : _MyBridgeStorage
|
|
}
|
|
|
|
struct My2dArray<T> {
|
|
var _buffer : _My2dArrayBuffer<T>
|
|
}
|
|
|
|
|
|
struct MyInt {
|
|
@_hasStorage var _value: Builtin.Int64
|
|
init(_ value: Int16)
|
|
}
|
|
|
|
// CHECK-LABEL: sil @hoist_projections
|
|
// CHECK: bb0
|
|
// CHECK: [[SE:%[0-9]+]] = struct_element_addr %0
|
|
// CHECK: [[ARRAY:%[0-9]+]] = struct_element_addr [[SE]]
|
|
// CHECK: [[MM:%[0-9]+]] = function_ref @array_make_mutable
|
|
// CHECK: apply [[MM]]([[ARRAY]]
|
|
// CHECK: [[EM:%[0-9]+]] = function_ref @array_end_mutation
|
|
// CHECK: apply [[EM]]([[ARRAY]]
|
|
// CHECK: bb1:
|
|
// CHECK: bb2:
|
|
// CHECK: apply [[MM]]([[ARRAY]]
|
|
// CHECK: apply [[EM]]([[ARRAY]]
|
|
// CHECK: } // end sil function 'hoist_projections'
|
|
sil @hoist_projections : $@convention(thin) (@inout ContainerContainer, @inout Builtin.Int1) -> () {
|
|
bb0(%0 : $*ContainerContainer, %1 : $*Builtin.Int1):
|
|
br bb1
|
|
|
|
bb1:
|
|
br bb3
|
|
|
|
bb3:
|
|
%3 = struct_element_addr %0 : $*ContainerContainer, #ContainerContainer.container
|
|
%4 = struct_element_addr %3 : $*Container, #Container.array
|
|
%5 = function_ref @array_make_mutable : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
%6 = apply %5(%4) : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
%7 = function_ref @array_end_mutation : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
%8 = apply %7(%4) : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
cond_br undef, bb1, bb2
|
|
|
|
bb2:
|
|
%r = tuple()
|
|
return %r : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @hoist_non_unary_projections
|
|
// CHECK: bb0
|
|
// CHECK: [[SE:%[0-9]+]] = struct_element_addr %0
|
|
// CHECK: [[IA:%[0-9]+]] = index_addr [[SE]]
|
|
// CHECK: [[ARRAY:%[0-9]+]] = struct_element_addr [[IA]]
|
|
// CHECK: [[MM:%[0-9]+]] = function_ref @array_make_mutable
|
|
// CHECK: apply [[MM]]([[ARRAY]]
|
|
// CHECK: [[EM:%[0-9]+]] = function_ref @array_end_mutation
|
|
// CHECK: apply [[EM]]([[ARRAY]]
|
|
// CHECK: bb1:
|
|
// CHECK: bb2:
|
|
// CHECK: apply [[MM]]([[ARRAY]]
|
|
// CHECK: apply [[EM]]([[ARRAY]]
|
|
// CHECK: } // end sil function 'hoist_non_unary_projections'
|
|
sil @hoist_non_unary_projections : $@convention(thin) (@inout ContainerContainer, @inout Builtin.Int1) -> () {
|
|
bb0(%0 : $*ContainerContainer, %1 : $*Builtin.Int1):
|
|
%i = integer_literal $Builtin.Int32, 0
|
|
br bb1
|
|
|
|
bb1:
|
|
br bb2
|
|
|
|
bb2:
|
|
%3 = struct_element_addr %0 : $*ContainerContainer, #ContainerContainer.container
|
|
%3i = index_addr %3 : $*Container, %i : $Builtin.Int32
|
|
%4 = struct_element_addr %3i : $*Container, #Container.array
|
|
%5 = function_ref @array_make_mutable : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
%6 = apply %5(%4) : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
%7 = function_ref @array_end_mutation : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
%8 = apply %7(%4) : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
cond_br undef, bb1, bb3
|
|
|
|
bb3:
|
|
%r = tuple()
|
|
return %r : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @hoist_projections2
|
|
// CHECK: bb0
|
|
// CHECK: [[SE:%[0-9]+]] = struct_element_addr %0
|
|
// CHECK: [[ARRAY:%[0-9]+]] = struct_element_addr [[SE]]
|
|
// CHECK: [[MM:%[0-9]+]] = function_ref @array_make_mutable
|
|
// CHECK: apply [[MM]]([[ARRAY]]
|
|
// CHECK: [[EM:%[0-9]+]] = function_ref @array_end_mutation
|
|
// CHECK: apply [[EM]]([[ARRAY]]
|
|
// CHECK: bb1:
|
|
// CHECK: bb2:
|
|
// CHECK: apply [[MM]]([[ARRAY]]
|
|
// CHECK: apply [[EM]]
|
|
// CHECK: } // end sil function 'hoist_projections2'
|
|
sil @hoist_projections2 : $@convention(thin) (@inout ContainerContainer, @inout Builtin.Int1) -> () {
|
|
bb0(%0 : $*ContainerContainer, %1 : $*Builtin.Int1):
|
|
br bb1
|
|
|
|
bb1:
|
|
br bb3
|
|
|
|
bb3:
|
|
%2 = struct_element_addr %0 : $*ContainerContainer, #ContainerContainer.container
|
|
%4 = struct_element_addr %2 : $*Container, #Container.array
|
|
%5 = function_ref @array_make_mutable : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
%6 = apply %5(%4) : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
%7 = function_ref @array_end_mutation : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
%8 = apply %7(%4) : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
cond_br undef, bb1, bb2
|
|
|
|
bb2:
|
|
%r = tuple()
|
|
return %r : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @hoist_projections3
|
|
// CHECK: bb0
|
|
// CHECK: [[SE:%[0-9]+]] = struct_element_addr %0
|
|
// CHECK: [[ARRAY:%[0-9]+]] = struct_element_addr [[SE]]
|
|
// CHECK: [[MM:%[0-9]+]] = function_ref @array_make_mutable
|
|
// CHECK: apply [[MM]]([[ARRAY]]
|
|
// CHECK: [[EM:%[0-9]+]] = function_ref @array_end_mutation
|
|
// CHECK: apply [[EM]]([[ARRAY]]
|
|
// CHECK: bb1:
|
|
// CHECK: apply [[MM]]([[ARRAY]]
|
|
// CHECK: apply [[EM]]([[ARRAY]]
|
|
// CHECK: } // end sil function 'hoist_projections3'
|
|
sil @hoist_projections3 : $@convention(thin) (@inout ContainerContainer, @inout Builtin.Int1) -> () {
|
|
bb0(%0 : $*ContainerContainer, %1 : $*Builtin.Int1):
|
|
br bb1
|
|
|
|
bb1:
|
|
%2 = struct_element_addr %0 : $*ContainerContainer, #ContainerContainer.container
|
|
%3 = struct_element_addr %2 : $*Container, #Container.array
|
|
%5 = function_ref @array_make_mutable : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
%6 = apply %5(%3) : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
%7 = function_ref @array_end_mutation : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
%8 = apply %7(%3) : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
cond_br undef, bb1, bb2
|
|
|
|
bb2:
|
|
%r = tuple()
|
|
return %r : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @hoist_array2d
|
|
// CHECK: bb0
|
|
// CHECK-DAG: [[MM:%[0-9]+]] = function_ref @array_make_mutable
|
|
// CHECK-DAG: [[EM:%[0-9]+]] = function_ref @array_end_mutation
|
|
// CHECK: apply [[MM]](%0)
|
|
// CHECK: apply [[EM]](%0)
|
|
// CHECK: [[L:%[0-9]+]] = load %0
|
|
// CHECK: [[SE1:%[0-9]+]] = struct_extract [[L]]
|
|
// CHECK: [[SE2:%[0-9]+]] = struct_extract [[SE1]]
|
|
// CHECK: [[CAST:%[0-9]+]] = unchecked_ref_cast [[SE2]]
|
|
// CHECK: [[TA:%[0-9]+]] = ref_tail_addr [[CAST]]
|
|
// CHECK: [[ARR2:%[0-9]+]] = index_addr [[TA]]
|
|
// CHECK: apply [[MM]]([[ARR2]]
|
|
// CHECK: apply [[EM]]([[ARR2]]
|
|
// CHECK: bb1:
|
|
// CHECK: apply [[MM]](%0)
|
|
// CHECK: apply [[MM]]([[ARR2]]
|
|
// CHECK: apply [[EM]]([[ARR2]]
|
|
// CHECK: apply [[EM]](%0)
|
|
// CHECK: } // end sil function 'hoist_array2d'
|
|
sil @hoist_array2d : $@convention(thin) (@inout MyArray<MyStruct>) -> () {
|
|
bb0(%0 : $*MyArray<MyStruct>):
|
|
%2 = load %0 : $*MyArray<MyStruct>
|
|
%3 = integer_literal $Builtin.Word, 1
|
|
br bb1
|
|
|
|
bb1:
|
|
%5 = function_ref @array_make_mutable : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
%6 = apply %5(%0) : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
%7 = load %0 : $*MyArray<MyStruct>
|
|
%8 = struct_extract %7 : $MyArray<MyStruct>, #MyArray.buffer
|
|
%9 = struct_extract %8 : $ArrayIntBuffer, #ArrayIntBuffer.storage
|
|
%10 = unchecked_ref_cast %9 : $Builtin.NativeObject to $MyArrayStorage
|
|
%11 = ref_tail_addr %10 : $MyArrayStorage, $MyArray<MyStruct>
|
|
%12 = index_addr %11 : $*MyArray<MyStruct>, %3 : $Builtin.Word
|
|
%13 = apply %5(%12) : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
%14 = function_ref @array_end_mutation : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
%15 = apply %14(%12) : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
%16 = apply %14(%0) : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
cond_br undef, bb1, bb2
|
|
|
|
bb2:
|
|
%r = tuple()
|
|
return %r : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @dont_hoist_inner_mutating_outer
|
|
// CHECK: bb0
|
|
// CHECK-DAG: [[MM:%[0-9]+]] = function_ref @array_make_mutable
|
|
// CHECK: apply [[MM]](%0)
|
|
// CHECK-DAG: [[EM:%[0-9]+]] = function_ref @array_end_mutation
|
|
// CHECK: apply [[EM]](%0)
|
|
// CHECK: bb1:
|
|
// CHECK: apply [[MM]](%0)
|
|
// CHECK: [[L:%[0-9]+]] = load %0
|
|
// CHECK: [[SE1:%[0-9]+]] = struct_extract [[L]]
|
|
// CHECK: [[SE2:%[0-9]+]] = struct_extract [[SE1]]
|
|
// CHECK: [[CAST:%[0-9]+]] = unchecked_ref_cast [[SE2]]
|
|
// CHECK: [[TA:%[0-9]+]] = ref_tail_addr [[CAST]]
|
|
// CHECK: [[ARR2:%[0-9]+]] = index_addr [[TA]]
|
|
// CHECK: apply [[MM]]([[ARR2]]
|
|
// CHECK: apply [[EM]]([[ARR2]]
|
|
// CHECK: apply [[EM]](%0)
|
|
// CHECK: } // end sil function 'dont_hoist_inner_mutating_outer'
|
|
sil @dont_hoist_inner_mutating_outer : $@convention(thin) (@inout MyArray<MyStruct>) -> () {
|
|
bb0(%0 : $*MyArray<MyStruct>):
|
|
%2 = load %0 : $*MyArray<MyStruct>
|
|
%3 = integer_literal $Builtin.Word, 1
|
|
%4 = function_ref @array_unknown_mutate : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
br bb1
|
|
|
|
bb1:
|
|
%5 = function_ref @array_make_mutable : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
%6 = apply %5(%0) : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
%7 = load %0 : $*MyArray<MyStruct>
|
|
%8 = struct_extract %7 : $MyArray<MyStruct>, #MyArray.buffer
|
|
%9 = struct_extract %8 : $ArrayIntBuffer, #ArrayIntBuffer.storage
|
|
%10 = unchecked_ref_cast %9 : $Builtin.NativeObject to $MyArrayStorage
|
|
%11 = ref_tail_addr %10 : $MyArrayStorage, $MyArray<MyStruct>
|
|
%12 = index_addr %11 : $*MyArray<MyStruct>, %3 : $Builtin.Word
|
|
%13 = apply %5(%12) : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
%14 = function_ref @array_end_mutation : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
%15 = apply %14(%12) : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
%16 = apply %4(%0) : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
%17 = apply %14(%0) : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
cond_br undef, bb1, bb2
|
|
|
|
bb2:
|
|
%r = tuple()
|
|
return %r : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @dont_hoist_inner_variant_index
|
|
// CHECK: bb0
|
|
// CHECK-DAG: [[MM:%[0-9]+]] = function_ref @array_make_mutable
|
|
// CHECK: apply [[MM]](%0)
|
|
// CHECK-DAG: [[EM:%[0-9]+]] = function_ref @array_end_mutation
|
|
// CHECK: apply [[EM]](%0)
|
|
// CHECK: bb1:
|
|
// CHECK: apply [[MM]](%0)
|
|
// CHECK: [[L:%[0-9]+]] = load %0
|
|
// CHECK: [[SE1:%[0-9]+]] = struct_extract [[L]]
|
|
// CHECK: [[SE2:%[0-9]+]] = struct_extract [[SE1]]
|
|
// CHECK: [[CAST:%[0-9]+]] = unchecked_ref_cast [[SE2]]
|
|
// CHECK: [[TA:%[0-9]+]] = ref_tail_addr [[CAST]]
|
|
// CHECK: [[ARR2:%[0-9]+]] = index_addr [[TA]]
|
|
// CHECK: apply [[MM]]([[ARR2]]
|
|
// CHECK: apply [[EM]]([[ARR2]]
|
|
// CHECK: apply [[EM]](%0)
|
|
// CHECK: } // end sil function 'dont_hoist_inner_variant_index'
|
|
sil @dont_hoist_inner_variant_index : $@convention(thin) (@inout MyArray<MyStruct>, @inout Builtin.Word) -> () {
|
|
bb0(%0 : $*MyArray<MyStruct>, %1 : $*Builtin.Word):
|
|
%2 = load %0 : $*MyArray<MyStruct>
|
|
br bb1
|
|
|
|
bb1:
|
|
%4 = load %1 : $*Builtin.Word
|
|
%5 = function_ref @array_make_mutable : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
%6 = apply %5(%0) : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
%7 = load %0 : $*MyArray<MyStruct>
|
|
%8 = struct_extract %7 : $MyArray<MyStruct>, #MyArray.buffer
|
|
%9 = struct_extract %8 : $ArrayIntBuffer, #ArrayIntBuffer.storage
|
|
%10 = unchecked_ref_cast %9 : $Builtin.NativeObject to $MyArrayStorage
|
|
%11 = ref_tail_addr %10 : $MyArrayStorage, $MyArray<MyStruct>
|
|
%12 = index_addr %11 : $*MyArray<MyStruct>, %4 : $Builtin.Word
|
|
%13 = apply %5(%12) : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
%14 = function_ref @array_end_mutation : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
%15 = apply %14(%12) : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
%17 = apply %14(%0) : $@convention(method) (@inout MyArray<MyStruct>) -> ()
|
|
cond_br undef, bb1, bb2
|
|
|
|
bb2:
|
|
%r = tuple()
|
|
return %r : $()
|
|
}
|
|
|