mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
There is no need to do so. And this can enable other optimizations for non-lexical alloc-stacks.
661 lines
30 KiB
Plaintext
661 lines
30 KiB
Plaintext
// RUN: %target-sil-opt -sil-print-types -enable-sil-verify-all %s -mandatory-inlining | %FileCheck %s
|
|
|
|
sil_stage raw
|
|
|
|
import Builtin
|
|
import Swift
|
|
|
|
class C {
|
|
var i: Builtin.Int64
|
|
init(i: Builtin.Int64)
|
|
}
|
|
|
|
private class C2 {
|
|
var i: Builtin.Int64 { get set }
|
|
init(i: Builtin.Int64)
|
|
}
|
|
|
|
class Klass {}
|
|
|
|
class AnotherKlass {}
|
|
|
|
sil [transparent] [ossa] @calleeWithGuaranteed : $@convention(thin) (@guaranteed C) -> Builtin.Int64 {
|
|
bb(%0 : @guaranteed $C):
|
|
%1 = ref_element_addr %0 : $C, #C.i
|
|
%2 = load [trivial] %1 : $*Builtin.Int64
|
|
return %2 : $Builtin.Int64
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @callerWithOwned : $@convention(thin) (@owned C) -> Builtin.Int64 {
|
|
// CHECK: bb0(%0 : @owned $C):
|
|
// CHECK: [[BORROW:%.*]] = begin_borrow %0 : $C
|
|
// CHECK: [[ADDR:%.*]] = ref_element_addr [[BORROW]] : $C, #C.i
|
|
// CHECK: [[VAL:%.*]] = load [trivial] [[ADDR]] : $*Builtin.Int64
|
|
// CHECK: end_borrow [[BORROW]] : $C
|
|
// CHECK: destroy_value %0 : $C
|
|
// CHECK: return [[VAL]] : $Builtin.Int64
|
|
// CHECK-LABEL: } // end sil function 'callerWithOwned'
|
|
sil [ossa] @callerWithOwned : $@convention(thin) (@owned C) -> Builtin.Int64 {
|
|
bb(%0 : @owned $C):
|
|
%fn = function_ref @calleeWithGuaranteed : $@convention(thin) (@guaranteed C) -> Builtin.Int64
|
|
%call = apply %fn(%0) : $@convention(thin) (@guaranteed C) -> Builtin.Int64
|
|
destroy_value %0 : $C
|
|
return %call : $Builtin.Int64
|
|
}
|
|
|
|
struct MyError : Error {}
|
|
|
|
sil [transparent] [ossa] @calleeWithGuaranteedThrows : $@convention(thin) (@guaranteed C) -> (Builtin.Int64, @error Error) {
|
|
bb(%0 : @guaranteed $C):
|
|
%1 = ref_element_addr %0 : $C, #C.i
|
|
%2 = load [trivial] %1 : $*Builtin.Int64
|
|
%3 = integer_literal $Builtin.Int64, 0
|
|
%5 = builtin "cmp_eq_Int64"(%2 : $Builtin.Int64, %3 : $Builtin.Int64) : $Builtin.Int1
|
|
cond_br %5, bb1, bb2
|
|
|
|
bb1:
|
|
%6 = alloc_existential_box $Error, $MyError
|
|
throw %6 : $Error
|
|
|
|
bb2:
|
|
return %2 : $Builtin.Int64
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @callerWithThrow : $@convention(thin) (@owned C) -> (Builtin.Int64, @error any Error) {
|
|
// CHECK: bb0(%0 : @owned $C):
|
|
// CHECK: [[BORROW:%.*]] = begin_borrow %0 : $C
|
|
// CHECK: [[ADDR:%.*]] = ref_element_addr [[BORROW]] : $C, #C.i
|
|
// CHECK: [[VAL:%.*]] = load [trivial] [[ADDR]] : $*Builtin.Int64
|
|
// CHECK: bb{{.*}}:
|
|
// CHECK: [[ERR:%.*]] = alloc_existential_box $any Error, $MyError
|
|
// CHECK: end_borrow [[BORROW]] : $C
|
|
// CHECK: destroy_value %0 : $C
|
|
// CHECK: throw [[ERR]] : $any Error
|
|
// CHECK: bb{{.*}}:
|
|
// CHECK: end_borrow [[BORROW]] : $C
|
|
// CHECK: destroy_value %0 : $C
|
|
// CHECK: return [[VAL]] : $Builtin.Int64
|
|
// CHECK-LABEL: } // end sil function 'callerWithThrow'
|
|
sil [ossa] @callerWithThrow : $@convention(thin) (@owned C) -> (Builtin.Int64, @error Error) {
|
|
bb(%0 : @owned $C):
|
|
%fn = function_ref @calleeWithGuaranteedThrows : $@convention(thin) (@guaranteed C) -> (Builtin.Int64, @error Error)
|
|
try_apply %fn(%0) : $@convention(thin) (@guaranteed C) -> (Builtin.Int64, @error Error), normal bb1, error bb2
|
|
|
|
bb1(%4 : $Builtin.Int64):
|
|
destroy_value %0 : $C
|
|
return %4 : $Builtin.Int64
|
|
|
|
bb2(%5 : @owned $Error):
|
|
destroy_value %0 : $C
|
|
throw %5 : $Error
|
|
}
|
|
|
|
// Partial Apply copy_value, begin_borrow
|
|
|
|
sil @nativeobject_plus : $@convention(thin) (@owned Builtin.NativeObject, @owned Builtin.NativeObject) -> @owned Builtin.NativeObject
|
|
sil @partial_apply_user : $@convention(thin) (@owned @callee_owned (@owned Builtin.NativeObject) -> @owned Builtin.NativeObject) -> ()
|
|
sil @partial_apply_user_guaranteed : $@convention(thin) (@guaranteed @callee_guaranteed (@owned Builtin.NativeObject) -> @owned Builtin.NativeObject) -> ()
|
|
|
|
sil [ossa] [transparent] @test_partial_nativeobject_baz : $@convention(thin) (@owned Builtin.NativeObject, @owned Builtin.NativeObject) -> @owned Builtin.NativeObject {
|
|
bb0(%0 : @owned $Builtin.NativeObject, %1 : @owned $Builtin.NativeObject):
|
|
%6 = function_ref @nativeobject_plus : $@convention(thin) (@owned Builtin.NativeObject, @owned Builtin.NativeObject) -> @owned Builtin.NativeObject
|
|
%7 = apply %6(%0, %1) : $@convention(thin) (@owned Builtin.NativeObject, @owned Builtin.NativeObject) -> @owned Builtin.NativeObject
|
|
return %7 : $Builtin.NativeObject
|
|
}
|
|
|
|
sil [ossa] [transparent] @test_partial_nativeobject_bar : $@convention(thin) (@owned @callee_owned (@owned Builtin.NativeObject) -> @owned Builtin.NativeObject, @owned Builtin.NativeObject) -> @owned Builtin.NativeObject {
|
|
bb0(%0 : @owned $@callee_owned (@owned Builtin.NativeObject) -> @owned Builtin.NativeObject, %1 : @owned $Builtin.NativeObject):
|
|
%7 = apply %0(%1) : $@callee_owned (@owned Builtin.NativeObject) -> @owned Builtin.NativeObject
|
|
return %7 : $Builtin.NativeObject
|
|
}
|
|
|
|
sil [ossa] [transparent] @test_partial_nativeobject_bar_guaranteed : $@convention(thin) (@guaranteed @callee_guaranteed (@owned Builtin.NativeObject) -> @owned Builtin.NativeObject, @owned Builtin.NativeObject) -> @owned Builtin.NativeObject {
|
|
bb0(%0 : @guaranteed $@callee_guaranteed (@owned Builtin.NativeObject) -> @owned Builtin.NativeObject, %1 : @owned $Builtin.NativeObject):
|
|
%7 = apply %0(%1) : $@callee_guaranteed (@owned Builtin.NativeObject) -> @owned Builtin.NativeObject
|
|
return %7 : $Builtin.NativeObject
|
|
}
|
|
|
|
// CHECK-LABEL: sil [transparent] [ossa] @test_partial_nativeobject_foo : $@convention(thin) (@owned Builtin.NativeObject) -> @owned Builtin.NativeObject {
|
|
// CHECK: bb0([[ARG:%.*]] : @owned $Builtin.NativeObject):
|
|
// CHECK: [[FN:%.*]] = function_ref @test_partial_nativeobject_baz :
|
|
// CHECK: [[ARG_COPY:%.*]] = copy_value [[ARG]]
|
|
// CHECK: [[ARG_COPY_2:%.*]] = copy_value [[ARG_COPY]]
|
|
// CHECK: [[PAI:%.*]] = partial_apply [[FN]]([[ARG_COPY]])
|
|
// CHECK: [[ARG_COPY_3:%.*]] = copy_value [[ARG]]
|
|
// CHECK: [[MOVE_ARG_COPY_3:%[^,]+]] = move_value [lexical] [[ARG_COPY_3]]
|
|
// CHECK: [[MOVE_ARG_COPY_2:%[^,]+]] = move_value [lexical] [[ARG_COPY_2]]
|
|
// CHECK: [[FN2:%.*]] = function_ref @nativeobject_plus :
|
|
// CHECK: [[RESULT:%.*]] = apply [[FN2]]([[MOVE_ARG_COPY_3]], [[MOVE_ARG_COPY_2]])
|
|
// CHECK: [[PAI_COPY:%.*]] = copy_value [[PAI]]
|
|
// CHECK: [[OPAQUE_FN:%.*]] = function_ref @partial_apply_user
|
|
// CHECK: apply [[OPAQUE_FN]]([[PAI_COPY]])
|
|
// CHECK: destroy_value [[PAI]]
|
|
// CHECK: destroy_value [[ARG]]
|
|
// CHECK: return [[RESULT]]
|
|
// CHECK: } // end sil function 'test_partial_nativeobject_foo'
|
|
sil [transparent] [ossa] @test_partial_nativeobject_foo : $@convention(thin) (@owned Builtin.NativeObject) -> @owned Builtin.NativeObject {
|
|
bb0(%0 : @owned $Builtin.NativeObject):
|
|
%2 = function_ref @test_partial_nativeobject_bar : $@convention(thin) (@owned @callee_owned (@owned Builtin.NativeObject) -> @owned Builtin.NativeObject, @owned Builtin.NativeObject) -> @owned Builtin.NativeObject
|
|
%3 = function_ref @test_partial_nativeobject_baz : $@convention(thin) (@owned Builtin.NativeObject, @owned Builtin.NativeObject) -> @owned Builtin.NativeObject
|
|
br bb1
|
|
|
|
bb1:
|
|
%0copy1 = copy_value %0 : $Builtin.NativeObject
|
|
%5 = partial_apply %3(%0copy1) : $@convention(thin) (@owned Builtin.NativeObject, @owned Builtin.NativeObject) -> @owned Builtin.NativeObject
|
|
br bb2
|
|
|
|
bb2:
|
|
%0copy2 = copy_value %0 : $Builtin.NativeObject
|
|
%5copy1 = copy_value %5 : $@callee_owned (@owned Builtin.NativeObject) -> @owned Builtin.NativeObject
|
|
%13 = apply %2(%5copy1, %0copy2) : $@convention(thin) (@owned @callee_owned (@owned Builtin.NativeObject) -> @owned Builtin.NativeObject, @owned Builtin.NativeObject) -> @owned Builtin.NativeObject
|
|
br bb3
|
|
|
|
bb3:
|
|
%5copy2 = copy_value %5 : $@callee_owned (@owned Builtin.NativeObject) -> @owned Builtin.NativeObject
|
|
%15 = function_ref @partial_apply_user : $@convention(thin) (@owned @callee_owned (@owned Builtin.NativeObject) -> @owned Builtin.NativeObject) -> ()
|
|
apply %15(%5copy2) : $@convention(thin) (@owned @callee_owned (@owned Builtin.NativeObject) -> @owned Builtin.NativeObject) -> ()
|
|
destroy_value %5 : $@callee_owned (@owned Builtin.NativeObject) -> @owned Builtin.NativeObject
|
|
destroy_value %0 : $Builtin.NativeObject
|
|
return %13 : $Builtin.NativeObject
|
|
}
|
|
|
|
// Make sure we do not eliminate the actual closure but do the inlining.
|
|
//
|
|
// CHECK-LABEL: sil [transparent] [ossa] @test_partial_nativeobject_foo_guaranteed_explicit_borrow : $@convention(thin) (@owned Builtin.NativeObject) -> @owned Builtin.NativeObject {
|
|
// CHECK: [[PAI:%.*]] = partial_apply [callee_guaranteed]
|
|
// CHECK: [[NATIVEOBJECT_PLUS_FUNC:%.*]] = function_ref @nativeobject_plus : $@convention(thin) (@owned Builtin.NativeObject, @owned Builtin.NativeObject) -> @owned Builtin.NativeObject
|
|
// CHECK-NEXT: apply [[NATIVEOBJECT_PLUS_FUNC]](
|
|
// CHECK: } // end sil function 'test_partial_nativeobject_foo_guaranteed_explicit_borrow'
|
|
sil [transparent] [ossa] @test_partial_nativeobject_foo_guaranteed_explicit_borrow : $@convention(thin) (@owned Builtin.NativeObject) -> @owned Builtin.NativeObject {
|
|
bb0(%0 : @owned $Builtin.NativeObject):
|
|
%2 = function_ref @test_partial_nativeobject_bar_guaranteed : $@convention(thin) (@guaranteed @callee_guaranteed (@owned Builtin.NativeObject) -> @owned Builtin.NativeObject, @owned Builtin.NativeObject) -> @owned Builtin.NativeObject
|
|
%3 = function_ref @test_partial_nativeobject_baz : $@convention(thin) (@owned Builtin.NativeObject, @owned Builtin.NativeObject) -> @owned Builtin.NativeObject
|
|
br bb1
|
|
|
|
bb1:
|
|
%0copy1 = copy_value %0 : $Builtin.NativeObject
|
|
%5 = partial_apply [callee_guaranteed] %3(%0copy1) : $@convention(thin) (@owned Builtin.NativeObject, @owned Builtin.NativeObject) -> @owned Builtin.NativeObject
|
|
%6 = begin_borrow %5 : $@callee_guaranteed (@owned Builtin.NativeObject) -> @owned Builtin.NativeObject
|
|
br bb2
|
|
|
|
bb2:
|
|
%0copy2 = copy_value %0 : $Builtin.NativeObject
|
|
%13 = apply %2(%6, %0copy2) : $@convention(thin) (@guaranteed @callee_guaranteed (@owned Builtin.NativeObject) -> @owned Builtin.NativeObject, @owned Builtin.NativeObject) -> @owned Builtin.NativeObject
|
|
end_borrow %6 : $@callee_guaranteed (@owned Builtin.NativeObject) -> @owned Builtin.NativeObject
|
|
br bb3
|
|
|
|
bb3:
|
|
%15 = function_ref @partial_apply_user_guaranteed : $@convention(thin) (@guaranteed @callee_guaranteed (@owned Builtin.NativeObject) -> @owned Builtin.NativeObject) -> ()
|
|
apply %15(%5) : $@convention(thin) (@guaranteed @callee_guaranteed (@owned Builtin.NativeObject) -> @owned Builtin.NativeObject) -> ()
|
|
destroy_value %5 : $@callee_guaranteed (@owned Builtin.NativeObject) -> @owned Builtin.NativeObject
|
|
destroy_value %0 : $Builtin.NativeObject
|
|
return %13 : $Builtin.NativeObject
|
|
}
|
|
|
|
// Make sure we do the inlining and delete the closure.
|
|
// CHECK-LABEL: sil [transparent] [ossa] @test_partial_nativeobject_foo_guaranteed_explicit_borrow_dead_pa : $@convention(thin) (@owned Builtin.NativeObject) -> @owned Builtin.NativeObject {
|
|
// CHECK-NOT: partial_apply
|
|
// CHECK: [[NATIVEOBJECT_PLUS_FUNC:%.*]] = function_ref @nativeobject_plus : $@convention(thin) (@owned Builtin.NativeObject, @owned Builtin.NativeObject) -> @owned Builtin.NativeObject
|
|
// CHECK-NEXT: apply [[NATIVEOBJECT_PLUS_FUNC]](
|
|
// CHECK-NOT: partial_apply
|
|
// CHECK: } // end sil function 'test_partial_nativeobject_foo_guaranteed_explicit_borrow_dead_pa'
|
|
sil [transparent] [ossa] @test_partial_nativeobject_foo_guaranteed_explicit_borrow_dead_pa : $@convention(thin) (@owned Builtin.NativeObject) -> @owned Builtin.NativeObject {
|
|
bb0(%0 : @owned $Builtin.NativeObject):
|
|
%2 = function_ref @test_partial_nativeobject_bar_guaranteed : $@convention(thin) (@guaranteed @callee_guaranteed (@owned Builtin.NativeObject) -> @owned Builtin.NativeObject, @owned Builtin.NativeObject) -> @owned Builtin.NativeObject
|
|
%3 = function_ref @test_partial_nativeobject_baz : $@convention(thin) (@owned Builtin.NativeObject, @owned Builtin.NativeObject) -> @owned Builtin.NativeObject
|
|
br bb1
|
|
|
|
bb1:
|
|
%0copy1 = copy_value %0 : $Builtin.NativeObject
|
|
%5 = partial_apply [callee_guaranteed] %3(%0copy1) : $@convention(thin) (@owned Builtin.NativeObject, @owned Builtin.NativeObject) -> @owned Builtin.NativeObject
|
|
%6 = begin_borrow %5 : $@callee_guaranteed (@owned Builtin.NativeObject) -> @owned Builtin.NativeObject
|
|
br bb2
|
|
|
|
bb2:
|
|
%0copy2 = copy_value %0 : $Builtin.NativeObject
|
|
%13 = apply %2(%6, %0copy2) : $@convention(thin) (@guaranteed @callee_guaranteed (@owned Builtin.NativeObject) -> @owned Builtin.NativeObject, @owned Builtin.NativeObject) -> @owned Builtin.NativeObject
|
|
end_borrow %6 : $@callee_guaranteed (@owned Builtin.NativeObject) -> @owned Builtin.NativeObject
|
|
br bb3
|
|
|
|
bb3:
|
|
destroy_value %5 : $@callee_guaranteed (@owned Builtin.NativeObject) -> @owned Builtin.NativeObject
|
|
destroy_value %0 : $Builtin.NativeObject
|
|
return %13 : $Builtin.NativeObject
|
|
}
|
|
|
|
// CHECK-LABEL: sil [transparent] [ossa] @test_partial_nativeobject_foo_guaranteed_implicit_borrow : $@convention(thin) (@owned Builtin.NativeObject) -> @owned Builtin.NativeObject {
|
|
// We shouldn't delete the PAI here.
|
|
// CHECK: [[PAI:%.*]] = partial_apply [callee_guaranteed]
|
|
// CHECK: [[NATIVEOBJECT_PLUS_FUNC:%.*]] = function_ref @nativeobject_plus : $@convention(thin) (@owned Builtin.NativeObject, @owned Builtin.NativeObject) -> @owned Builtin.NativeObject
|
|
// CHECK: apply [[NATIVEOBJECT_PLUS_FUNC]](
|
|
// CHECK: } // end sil function 'test_partial_nativeobject_foo_guaranteed_implicit_borrow'
|
|
sil [transparent] [ossa] @test_partial_nativeobject_foo_guaranteed_implicit_borrow : $@convention(thin) (@owned Builtin.NativeObject) -> @owned Builtin.NativeObject {
|
|
bb0(%0 : @owned $Builtin.NativeObject):
|
|
%2 = function_ref @test_partial_nativeobject_bar_guaranteed : $@convention(thin) (@guaranteed @callee_guaranteed (@owned Builtin.NativeObject) -> @owned Builtin.NativeObject, @owned Builtin.NativeObject) -> @owned Builtin.NativeObject
|
|
%3 = function_ref @test_partial_nativeobject_baz : $@convention(thin) (@owned Builtin.NativeObject, @owned Builtin.NativeObject) -> @owned Builtin.NativeObject
|
|
br bb1
|
|
|
|
bb1:
|
|
%0copy1 = copy_value %0 : $Builtin.NativeObject
|
|
%5 = partial_apply [callee_guaranteed] %3(%0copy1) : $@convention(thin) (@owned Builtin.NativeObject, @owned Builtin.NativeObject) -> @owned Builtin.NativeObject
|
|
br bb2
|
|
|
|
bb2:
|
|
%0copy2 = copy_value %0 : $Builtin.NativeObject
|
|
%13 = apply %2(%5, %0copy2) : $@convention(thin) (@guaranteed @callee_guaranteed (@owned Builtin.NativeObject) -> @owned Builtin.NativeObject, @owned Builtin.NativeObject) -> @owned Builtin.NativeObject
|
|
br bb3
|
|
|
|
bb3:
|
|
%15 = function_ref @partial_apply_user_guaranteed : $@convention(thin) (@guaranteed @callee_guaranteed (@owned Builtin.NativeObject) -> @owned Builtin.NativeObject) -> ()
|
|
apply %15(%5) : $@convention(thin) (@guaranteed @callee_guaranteed (@owned Builtin.NativeObject) -> @owned Builtin.NativeObject) -> ()
|
|
destroy_value %5 : $@callee_guaranteed (@owned Builtin.NativeObject) -> @owned Builtin.NativeObject
|
|
destroy_value %0 : $Builtin.NativeObject
|
|
return %13 : $Builtin.NativeObject
|
|
}
|
|
|
|
sil [transparent] [ossa] @term_ossa_checked_cast_addr_br_takealways_callee : $@convention(thin) (@owned Builtin.NativeObject) -> () {
|
|
bb0(%0 : @owned $Builtin.NativeObject):
|
|
%1 = alloc_stack $Builtin.NativeObject
|
|
%2 = alloc_stack $Klass
|
|
store %0 to [init] %1 : $*Builtin.NativeObject
|
|
checked_cast_addr_br take_always Builtin.NativeObject in %1 : $*Builtin.NativeObject to Klass in %2 : $*Klass, bb1, bb2
|
|
|
|
bb1:
|
|
destroy_addr %2 : $*Klass
|
|
br bb3
|
|
|
|
bb2:
|
|
br bb3
|
|
|
|
bb3:
|
|
dealloc_stack %2 : $*Klass
|
|
dealloc_stack %1 : $*Builtin.NativeObject
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
sil [transparent] [ossa] @term_ossa_checked_cast_addr_br_takealways_callee2 : $@convention(thin) (@in @thick Klass.Type) -> () {
|
|
bb0(%0 : $*@thick Klass.Type):
|
|
%2 = alloc_stack $AnotherKlass
|
|
checked_cast_addr_br take_always Klass in %0 : $*@thick Klass.Type to Klass in %2 : $*AnotherKlass, bb1, bb2
|
|
|
|
bb1:
|
|
destroy_addr %2 : $*AnotherKlass
|
|
br bb3
|
|
|
|
bb2:
|
|
br bb3
|
|
|
|
bb3:
|
|
dealloc_stack %2 : $*AnotherKlass
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @term_nonossa_checked_cast_addr_br_takealways_caller : $@convention(thin) (@owned Builtin.NativeObject) -> () {
|
|
// CHECK: bb0([[ARG:%.*]] :
|
|
// CHECK-NEXT: [[ARG_COPY:%.*]] = copy_value [[ARG]]
|
|
// CHECK-NEXT: [[ARG_MOVE:%[^,]+]] = move_value [lexical] [[ARG_COPY]] : $Builtin.NativeObject
|
|
// CHECK-NEXT: [[SRC_ADDR:%.*]] = alloc_stack $Builtin.NativeObject
|
|
// CHECK-NEXT: [[DEST_ADDR:%.*]] = alloc_stack $Klass
|
|
// CHECK-NEXT: store [[ARG_MOVE]] to [init] [[SRC_ADDR]]
|
|
// CHECK-NEXT: [[RELOADED_ARG:%.*]] = load [take] [[SRC_ADDR]]
|
|
// CHECK-NEXT: checked_cast_br Builtin.NativeObject in [[RELOADED_ARG]] : $Builtin.NativeObject to Klass, [[SUCCESS_BB:bb[0-9]+]], [[FAILURE_BB:bb[0-9]+]]
|
|
//
|
|
// ==> On success, we store the value into dest. The destroy is not from the
|
|
// ==> optimizer, but from the code.
|
|
// CHECK: [[SUCCESS_BB]]([[CAST_VALUE:%.*]] :
|
|
// CHECK-NEXT: store [[CAST_VALUE]] to [init] [[DEST_ADDR]]
|
|
// CHECK-NEXT: destroy_addr [[DEST_ADDR]]
|
|
// CHECK-NEXT: br [[CONT_BB:bb[0-9]+]]
|
|
//
|
|
// ==> take_always implies we destroy in failure
|
|
// CHECK: [[FAILURE_BB]]([[FAILURE_ARG:%.*]] :
|
|
// CHECK-NEXT: destroy_value [[FAILURE_ARG]]
|
|
// CHECK-NEXT: br [[CONT_BB]]
|
|
//
|
|
// CHECK: [[CONT_BB]]:
|
|
// CHECK: destroy_value [[ARG]]
|
|
// CHECK: } // end sil function 'term_nonossa_checked_cast_addr_br_takealways_caller'
|
|
sil [ossa] @term_nonossa_checked_cast_addr_br_takealways_caller : $@convention(thin) (@owned Builtin.NativeObject) -> () {
|
|
bb0(%0 : @owned $Builtin.NativeObject):
|
|
%3 = function_ref @term_ossa_checked_cast_addr_br_takealways_callee : $@convention(thin) (@owned Builtin.NativeObject) -> ()
|
|
%1 = copy_value %0 : $Builtin.NativeObject
|
|
apply %3(%1) : $@convention(thin) (@owned Builtin.NativeObject) -> ()
|
|
destroy_value %0 : $Builtin.NativeObject
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
sil [ossa] @get_klass_type : $@convention(thin) () -> @out @thick Klass.Type
|
|
|
|
// CHECK-LABEL: sil [ossa] @term_nonossa_checked_cast_addr_br_takealways_caller2 :
|
|
// CHECK: checked_cast_br Klass in {{.*}} : $@thick Klass.Type to Klass, [[SUCCESS_BB:bb[0-9]+]], [[FAILURE_BB:bb[0-9]+]], forwarding: @owned
|
|
// CHECK: [[SUCCESS_BB]]({{.*}}@owned $AnotherKlass):
|
|
// CHECK: [[FAILURE_BB]]([[FAILURE_ARG:%.*]] :
|
|
// CHECK: } // end sil function 'term_nonossa_checked_cast_addr_br_takealways_caller2'
|
|
sil [ossa] @term_nonossa_checked_cast_addr_br_takealways_caller2 : $@convention(thin) () -> () {
|
|
bb0:
|
|
%res = alloc_stack $@thick Klass.Type
|
|
%2 = function_ref @get_klass_type : $@convention(thin) () -> @out @thick Klass.Type
|
|
apply %2(%res) : $@convention(thin) () -> @out @thick Klass.Type
|
|
%3 = function_ref @term_ossa_checked_cast_addr_br_takealways_callee2 : $@convention(thin) (@in @thick Klass.Type) -> ()
|
|
apply %3(%res) : $@convention(thin) (@in @thick Klass.Type) -> ()
|
|
dealloc_stack %res : $*@thick Klass.Type
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
sil [transparent] [ossa] @term_ossa_checked_cast_addr_br_takeonsuccess_callee : $@convention(thin) (@owned Builtin.NativeObject) -> () {
|
|
bb0(%0 : @owned $Builtin.NativeObject):
|
|
%1 = alloc_stack $Builtin.NativeObject
|
|
%2 = alloc_stack $Klass
|
|
store %0 to [init] %1 : $*Builtin.NativeObject
|
|
checked_cast_addr_br take_on_success Builtin.NativeObject in %1 : $*Builtin.NativeObject to Klass in %2 : $*Klass, bb1, bb2
|
|
|
|
bb1:
|
|
destroy_addr %2 : $*Klass
|
|
br bb3
|
|
|
|
bb2:
|
|
destroy_addr %1 : $*Builtin.NativeObject
|
|
br bb3
|
|
|
|
bb3:
|
|
dealloc_stack %2 : $*Klass
|
|
dealloc_stack %1 : $*Builtin.NativeObject
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @checked_cast_addr_br_takeonsuccess_caller : $@convention(thin) (@owned Builtin.NativeObject) -> () {
|
|
// CHECK: bb0([[ARG:%.*]] :
|
|
// CHECK-NEXT: [[ARG_COPY:%.*]] = copy_value [[ARG]]
|
|
// CHECK-NEXT: [[ARG_MOVE:%[^,]+]] = move_value [lexical] [[ARG_COPY]] : $Builtin.NativeObject
|
|
// CHECK-NEXT: [[SRC_ADDR:%.*]] = alloc_stack $Builtin.NativeObject
|
|
// CHECK-NEXT: [[DEST_ADDR:%.*]] = alloc_stack $Klass
|
|
// CHECK-NEXT: store [[ARG_MOVE]] to [init] [[SRC_ADDR]]
|
|
// CHECK-NEXT: [[RELOADED_ARG:%.*]] = load [take] [[SRC_ADDR]]
|
|
// CHECK-NEXT: checked_cast_br Builtin.NativeObject in [[RELOADED_ARG]] : $Builtin.NativeObject to Klass, [[SUCCESS_BB:bb[0-9]+]], [[FAILURE_BB:bb[0-9]+]]
|
|
//
|
|
// CHECK: [[SUCCESS_BB]]([[CAST_VALUE:%.*]] :
|
|
// ==> On success, we store into dest and destroy dest.
|
|
// CHECK-NEXT: store [[CAST_VALUE]] to [init] [[DEST_ADDR]]
|
|
// CHECK-NEXT: destroy_addr [[DEST_ADDR]]
|
|
// CHECK-NEXT: br [[CONT_BB:bb[0-9]+]]
|
|
//
|
|
// ==> Since we are doing a take on success and we failed... store the original
|
|
// ==> value back into the memory slot.
|
|
// CHECK: [[FAILURE_BB]]([[FAIL_ARG:%.*]] :
|
|
// CHECK-NEXT: store [[FAIL_ARG]] to [init] [[SRC_ADDR]]
|
|
// CHECK-NEXT: destroy_addr [[SRC_ADDR]]
|
|
// CHECK-NEXT: br [[CONT_BB]]
|
|
//
|
|
// CHECK: } // end sil function 'checked_cast_addr_br_takeonsuccess_caller'
|
|
sil [ossa] @checked_cast_addr_br_takeonsuccess_caller : $@convention(thin) (@owned Builtin.NativeObject) -> () {
|
|
bb0(%0 : @owned $Builtin.NativeObject):
|
|
%2 = function_ref @term_ossa_checked_cast_addr_br_takeonsuccess_callee : $@convention(thin) (@owned Builtin.NativeObject) -> ()
|
|
%1 = copy_value %0 : $Builtin.NativeObject
|
|
apply %2(%1) : $@convention(thin) (@owned Builtin.NativeObject) -> ()
|
|
destroy_value %0 : $Builtin.NativeObject
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
sil [transparent] [ossa] @term_ossa_checked_cast_addr_br_copyonsuccess_callee : $@convention(thin) (@owned Builtin.NativeObject) -> () {
|
|
bb0(%0 : @owned $Builtin.NativeObject):
|
|
%1 = alloc_stack $Builtin.NativeObject
|
|
%2 = alloc_stack $Klass
|
|
store %0 to [init] %1 : $*Builtin.NativeObject
|
|
checked_cast_addr_br copy_on_success Builtin.NativeObject in %1 : $*Builtin.NativeObject to Klass in %2 : $*Klass, bb1, bb2
|
|
|
|
bb1:
|
|
destroy_addr %2 : $*Klass
|
|
destroy_addr %1 : $*Builtin.NativeObject
|
|
br bb3
|
|
|
|
bb2:
|
|
destroy_addr %1 : $*Builtin.NativeObject
|
|
br bb3
|
|
|
|
bb3:
|
|
dealloc_stack %2 : $*Klass
|
|
dealloc_stack %1 : $*Builtin.NativeObject
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @checked_cast_addr_br_copyonsuccess_caller : $@convention(thin) (@owned Builtin.NativeObject) -> () {
|
|
// CHECK: bb0([[ARG:%.*]] :
|
|
// CHECK-NEXT: [[ARG_COPY:%.*]] = copy_value [[ARG]]
|
|
// CHECK-NEXT: [[ARG_MOVE:%[^,]+]] = move_value [lexical] [[ARG_COPY]]
|
|
// CHECK-NEXT: [[SRC_ADDR:%.*]] = alloc_stack $Builtin.NativeObject
|
|
// CHECK-NEXT: [[DEST_ADDR:%.*]] = alloc_stack $Klass
|
|
// CHECK-NEXT: store [[ARG_MOVE]] to [init] [[SRC_ADDR]]
|
|
// CHECK-NEXT: [[RELOADED_ARG:%.*]] = load_borrow [[SRC_ADDR]]
|
|
// CHECK-NEXT: checked_cast_br Builtin.NativeObject in [[RELOADED_ARG]] : $Builtin.NativeObject to Klass, [[SUCCESS_BB:bb[0-9]+]], [[FAILURE_BB:bb[0-9]+]]
|
|
//
|
|
// CHECK: [[SUCCESS_BB]]([[CAST_VALUE:%.*]] : @guaranteed
|
|
// CHECK-NEXT: [[CAST_VALUE_COPY:%.*]] = copy_value [[CAST_VALUE]]
|
|
// CHECK-NEXT: end_borrow [[RELOADED_ARG]]
|
|
// CHECK-NEXT: store [[CAST_VALUE_COPY]] to [init] [[DEST_ADDR]]
|
|
// CHECK-NEXT: destroy_addr [[DEST_ADDR]]
|
|
// CHECK-NEXT: destroy_addr [[SRC_ADDR]]
|
|
// CHECK-NEXT: br [[CONT_BB:bb[0-9]+]]
|
|
//
|
|
// CHECK: [[FAILURE_BB]]([[FAILURE_BORROWED_ARG:%.*]] :
|
|
// CHECK-NEXT: end_borrow [[RELOADED_ARG]]
|
|
// CHECK-NEXT: destroy_addr [[SRC_ADDR]]
|
|
// CHECK-NEXT: br [[CONT_BB]]
|
|
//
|
|
// CHECK: } // end sil function 'checked_cast_addr_br_copyonsuccess_caller'
|
|
sil [ossa] @checked_cast_addr_br_copyonsuccess_caller : $@convention(thin) (@owned Builtin.NativeObject) -> () {
|
|
bb0(%0 : @owned $Builtin.NativeObject):
|
|
%1 = function_ref @term_ossa_checked_cast_addr_br_copyonsuccess_callee : $@convention(thin) (@owned Builtin.NativeObject) -> ()
|
|
%2 = copy_value %0 : $Builtin.NativeObject
|
|
apply %1(%2) : $@convention(thin) (@owned Builtin.NativeObject) -> ()
|
|
destroy_value %0 : $Builtin.NativeObject
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
///////////////////////
|
|
// Begin Apply Tests //
|
|
///////////////////////
|
|
|
|
// Make sure that we do not violate any ownership invariants after inlining this
|
|
// code.
|
|
|
|
sil @get_hidden_int_field_of_klass : $@convention(method) (@guaranteed Klass) -> Builtin.Int32
|
|
sil @int_klass_pair_user : $@convention(method) (Builtin.Int32, @guaranteed Klass) -> ()
|
|
|
|
sil [transparent] [ossa] @begin_apply_callee : $@yield_once @convention(method) (@guaranteed Klass) -> @yields @inout Builtin.Int32 {
|
|
bb0(%0 : @guaranteed $Klass):
|
|
%2 = alloc_stack $Builtin.Int32
|
|
%3 = function_ref @get_hidden_int_field_of_klass : $@convention(method) (@guaranteed Klass) -> Builtin.Int32
|
|
%4 = apply %3(%0) : $@convention(method) (@guaranteed Klass) -> Builtin.Int32
|
|
store %4 to [trivial] %2 : $*Builtin.Int32
|
|
yield %2 : $*Builtin.Int32, resume bb1, unwind bb2
|
|
|
|
bb1:
|
|
%7 = load [trivial] %2 : $*Builtin.Int32
|
|
%8 = function_ref @int_klass_pair_user : $@convention(method) (Builtin.Int32, @guaranteed Klass) -> ()
|
|
%9 = apply %8(%7, %0) : $@convention(method) (Builtin.Int32, @guaranteed Klass) -> ()
|
|
dealloc_stack %2 : $*Builtin.Int32
|
|
%11 = tuple ()
|
|
return %11 : $()
|
|
|
|
bb2:
|
|
%13 = load [trivial] %2 : $*Builtin.Int32
|
|
%14 = function_ref @int_klass_pair_user : $@convention(method) (Builtin.Int32, @guaranteed Klass) -> ()
|
|
%15 = apply %14(%13, %0) : $@convention(method) (Builtin.Int32, @guaranteed Klass) -> ()
|
|
dealloc_stack %2 : $*Builtin.Int32
|
|
unwind
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @begin_apply_caller : $@convention(method) (@guaranteed Klass) -> @error any Error {
|
|
// CHECK-NOT: begin_apply
|
|
// CHECK: } // end sil function 'begin_apply_caller'
|
|
sil [ossa] @begin_apply_caller : $@convention(method) (@guaranteed Klass) -> @error Error {
|
|
bb0(%0 : @guaranteed $Klass):
|
|
%6 = copy_value %0 : $Klass
|
|
%12 = function_ref @begin_apply_callee : $@yield_once @convention(method) (@guaranteed Klass) -> @yields @inout Builtin.Int32
|
|
(%13, %14) = begin_apply %12(%6) : $@yield_once @convention(method) (@guaranteed Klass) -> @yields @inout Builtin.Int32
|
|
end_apply %14 as $()
|
|
destroy_value %6 : $Klass
|
|
%19 = tuple ()
|
|
return %19 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @begin_apply_caller_2 : $@convention(method) (@guaranteed Klass) -> @error any Error {
|
|
// CHECK-NOT: begin_apply
|
|
// CHECK: } // end sil function 'begin_apply_caller_2'
|
|
sil [ossa] @begin_apply_caller_2 : $@convention(method) (@guaranteed Klass) -> @error Error {
|
|
bb0(%0 : @guaranteed $Klass):
|
|
%6 = copy_value %0 : $Klass
|
|
%12 = function_ref @begin_apply_callee : $@yield_once @convention(method) (@guaranteed Klass) -> @yields @inout Builtin.Int32
|
|
(%13, %14) = begin_apply %12(%6) : $@yield_once @convention(method) (@guaranteed Klass) -> @yields @inout Builtin.Int32
|
|
abort_apply %14
|
|
destroy_value %6 : $Klass
|
|
%19 = tuple ()
|
|
return %19 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @begin_apply_caller_3 : $@convention(method) (@guaranteed Klass) -> @error any Error {
|
|
// CHECK-NOT: begin_apply
|
|
// CHECK: } // end sil function 'begin_apply_caller_3'
|
|
sil [ossa] @begin_apply_caller_3 : $@convention(method) (@guaranteed Klass) -> @error Error {
|
|
bb0(%0 : @guaranteed $Klass):
|
|
%6 = copy_value %0 : $Klass
|
|
%12 = function_ref @begin_apply_callee : $@yield_once @convention(method) (@guaranteed Klass) -> @yields @inout Builtin.Int32
|
|
(%13, %14) = begin_apply %12(%6) : $@yield_once @convention(method) (@guaranteed Klass) -> @yields @inout Builtin.Int32
|
|
cond_br undef, bb1, bb2
|
|
|
|
bb1:
|
|
end_apply %14 as $()
|
|
br bb3
|
|
|
|
bb2:
|
|
abort_apply %14
|
|
br bb3
|
|
|
|
bb3:
|
|
destroy_value %6 : $Klass
|
|
%19 = tuple ()
|
|
return %19 : $()
|
|
}
|
|
|
|
sil [ossa] [transparent] @devirt_callee : $@yield_once @convention(method) (@guaranteed C) -> @yields @inout Builtin.Int64 {
|
|
bb0(%0 : @guaranteed $C):
|
|
%1 = alloc_stack $Builtin.Int64
|
|
%1a = integer_literal $Builtin.Int64, 0
|
|
store %1a to [trivial] %1 : $*Builtin.Int64
|
|
yield %1 : $*Builtin.Int64, resume bb1, unwind bb2
|
|
|
|
bb1:
|
|
dealloc_stack %1 : $*Builtin.Int64
|
|
%6 = tuple ()
|
|
return %6 : $()
|
|
|
|
bb2:
|
|
dealloc_stack %1 : $*Builtin.Int64
|
|
unwind
|
|
}
|
|
|
|
// Just make sure we actually inlined the begin_apply. We just want to make sure
|
|
// we are not breaking ownership invariants by not properly borrowing %0.
|
|
// CHECK-LABEL: sil [ossa] @begin_apply_devirt_caller : $@convention(method) (@owned C2) -> @error any Error {
|
|
// CHECK-NOT: begin_apply
|
|
// CHECK: } // end sil function 'begin_apply_devirt_caller'
|
|
sil [ossa] @begin_apply_devirt_caller : $@convention(method) (@owned C2) -> @error Error {
|
|
bb0(%0 : @owned $C2):
|
|
%1 = class_method %0 : $C2, #C2.i!modify : (C2) -> () -> (), $@yield_once @convention(method) (@guaranteed C2) -> @yields @inout Builtin.Int64
|
|
(%mem, %tok) = begin_apply %1(%0) : $@yield_once @convention(method) (@guaranteed C2) -> @yields @inout Builtin.Int64
|
|
br bb1
|
|
|
|
bb1:
|
|
end_apply %tok as $()
|
|
destroy_value %0 : $C2
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @begin_apply_devirt_caller_2 : $@convention(method) (@owned C2) -> @error any Error {
|
|
// CHECK-NOT: begin_apply
|
|
// CHECK: } // end sil function 'begin_apply_devirt_caller_2'
|
|
sil [ossa] @begin_apply_devirt_caller_2 : $@convention(method) (@owned C2) -> @error Error {
|
|
bb0(%0 : @owned $C2):
|
|
%1 = class_method %0 : $C2, #C2.i!modify : (C2) -> () -> (), $@yield_once @convention(method) (@guaranteed C2) -> @yields @inout Builtin.Int64
|
|
(%mem, %tok) = begin_apply %1(%0) : $@yield_once @convention(method) (@guaranteed C2) -> @yields @inout Builtin.Int64
|
|
br bb1
|
|
|
|
bb1:
|
|
abort_apply %tok
|
|
destroy_value %0 : $C2
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @begin_apply_devirt_caller_3 : $@convention(method) (@owned C2) -> @error any Error {
|
|
// CHECK-NOT: begin_apply
|
|
// CHECK: } // end sil function 'begin_apply_devirt_caller_3'
|
|
sil [ossa] @begin_apply_devirt_caller_3 : $@convention(method) (@owned C2) -> @error Error {
|
|
bb0(%0 : @owned $C2):
|
|
%1 = class_method %0 : $C2, #C2.i!modify : (C2) -> () -> (), $@yield_once @convention(method) (@guaranteed C2) -> @yields @inout Builtin.Int64
|
|
(%mem, %tok) = begin_apply %1(%0) : $@yield_once @convention(method) (@guaranteed C2) -> @yields @inout Builtin.Int64
|
|
cond_br undef, bb1, bb2
|
|
|
|
bb1:
|
|
end_apply %tok as $()
|
|
br bb3
|
|
|
|
bb2:
|
|
abort_apply %tok
|
|
br bb3
|
|
|
|
bb3:
|
|
destroy_value %0 : $C2
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
sil [transparent] [ossa] @deinit_barrier : $@convention(thin) (@in_guaranteed Int) -> () {
|
|
[global: deinit_barrier]
|
|
bb0(%0 : $*Int):
|
|
%1 = tuple ()
|
|
return %1
|
|
}
|
|
|
|
sil [transparent] [ossa] @no_deinit_barrier : $@convention(thin) (@in_guaranteed Int) -> () {
|
|
[global: ]
|
|
bb0(%0 : $*Int):
|
|
%1 = tuple ()
|
|
return %1
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @inline_deinit_barrier :
|
|
// CHECK: alloc_stack [lexical] $Int
|
|
// CHECK: alloc_stack $Int
|
|
// CHECK: } // end sil function 'inline_deinit_barrier'
|
|
sil [ossa] @inline_deinit_barrier : $@convention(thin) (Int) -> () {
|
|
bb0(%0 : $Int):
|
|
%1 = alloc_stack $Int
|
|
store %0 to [trivial] %1
|
|
%2 = function_ref @deinit_barrier : $@convention(thin) (@in_guaranteed Int) -> ()
|
|
apply %2(%1) : $@convention(thin) (@in_guaranteed Int) -> ()
|
|
dealloc_stack %1
|
|
|
|
%10 = alloc_stack $Int
|
|
store %0 to [trivial] %10
|
|
%12 = function_ref @no_deinit_barrier : $@convention(thin) (@in_guaranteed Int) -> ()
|
|
apply %12(%10) : $@convention(thin) (@in_guaranteed Int) -> ()
|
|
dealloc_stack %10
|
|
|
|
%r = tuple ()
|
|
return %r
|
|
}
|
|
|
|
sil_vtable C2 {
|
|
#C2.i!modify: (C2) -> () -> () : @devirt_callee
|
|
}
|