1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
|
// RUN: %target-sil-opt -opt-mode=none -silgen-cleanup -enable-ossa-complete-lifetimes -parse-incomplete-ossa -sil-verify-all %s | %FileCheck %s --check-prefix=CHECK
import Builtin
sil_stage raw
typealias AnyObject = Builtin.AnyObject
class Klass {
var property: Builtin.Int64
}
class SubKlass : Klass {}
class C {}
enum FakeOptional<T> {
case none
case some(T)
}
struct Int {
var _value : Builtin.Int32
}
struct UInt8 {
var _value : Builtin.Int8
}
protocol P : AnyObject {}
// =============================================================================
// Test complete OSSA lifetimes
// =============================================================================
sil @unreachableHandler : $@convention(thin) () -> ()
// CHECK-LABEL: sil [ossa] @testCompleteOSSALifetimes : {{.*}} {
// CHECK: [[BOX:%.*]] = alloc_box ${ var FakeOptional<Klass> }, var, name "c"
// CHECK: [[BORROW:%.,*]] = begin_borrow [lexical] [[BOX]] : ${ var FakeOptional<Klass> }
// CHECK: bb2:
// CHECK: apply
// CHECK: end_borrow [[BORROW]] : ${ var FakeOptional<Klass> }
// CHECK: dealloc_box [dead_end] [[BOX]] : ${ var FakeOptional<Klass> }
// CHECK: unreachable
// CHECK-LABEL: } // end sil function 'testCompleteOSSALifetimes'
sil [ossa] @testCompleteOSSALifetimes : $@convention(thin) (@owned FakeOptional<Klass>) -> () {
bb0(%0 : @owned $FakeOptional<Klass>):
%box = alloc_box ${ var FakeOptional<Klass> }, var, name "c"
%borrow = begin_borrow [lexical] %box : ${ var FakeOptional<Klass> }
%project = project_box %borrow : ${ var FakeOptional<Klass> }, 0
store %0 to [init] %project : $*FakeOptional<Klass>
cond_br undef, bb1, bb4
bb1:
%access = begin_access [read] [unknown] %project : $*FakeOptional<Klass>
%val = load [copy] %access : $*FakeOptional<Klass>
end_access %access : $*FakeOptional<Klass>
switch_enum %val : $FakeOptional<Klass>, case #FakeOptional.some!enumelt: bb3, case #FakeOptional.none!enumelt: bb2
bb2:
%21 = function_ref @unreachableHandler : $@convention(thin) () -> ()
%22 = apply %21() : $@convention(thin) () -> ()
unreachable
bb3(%24 : @owned $Klass):
destroy_value %24 : $Klass
br bb5
bb4:
br bb5
bb5:
end_borrow %borrow : ${ var FakeOptional<Klass> }
destroy_value %box : ${ var FakeOptional<Klass> }
%36 = tuple ()
return %36 : $()
}
// CHECK-LABEL: sil [ossa] @testExistentialLifetime : {{.*}} {
// CHECK-NOT: destroy
// CHECK-LABEL: } // end sil function 'testExistentialLifetime'
sil [ossa] @testExistentialLifetime : $@convention(thin) (@owned any P) -> @owned AnyObject {
bb0(%0 : @owned $any P):
%1 = open_existential_ref %0 : $any P to $@opened("34B79428-2E49-11ED-901A-8AC134504E1C", any P) Self
%2 = init_existential_ref %1 : $@opened("34B79428-2E49-11ED-901A-8AC134504E1C", any P) Self : $@opened("34B79428-2E49-11ED-901A-8AC134504E1C", any P) Self, $AnyObject
return %2 : $AnyObject
}
// CHECK-LABEL: sil [ossa] @store_borrow : {{.*}} {
// CHECK: bb0([[INSTANCE:%[^,]+]] :
// CHECK: [[ADDR:%[^,]+]] = alloc_stack $C
// CHECK: [[TOKEN:%[^,]+]] = store_borrow [[INSTANCE]] to [[ADDR]]
// CHECK: [[LOAD:%[^,]+]] = load_borrow [[TOKEN]]
// CHECK: cond_br undef, {{bb[0-9]+}}, [[DIE:bb[0-9]+]]
// CHECK: [[DIE]]:
// CHECK: end_borrow [[LOAD]]
// CHECK: end_borrow [[TOKEN]]
// CHECK: destroy_value [dead_end] [[INSTANCE]]
// CHECK: unreachable
// CHECK-LABEL: } // end sil function 'store_borrow'
sil [ossa] @store_borrow : $@convention(thin) (@owned C) -> () {
entry(%instance : @owned $C):
%addr = alloc_stack $C
%token = store_borrow %instance to %addr : $*C
%load = load_borrow %token : $*C
cond_br undef, exit, die
exit:
end_borrow %load : $C
end_borrow %token : $*C
dealloc_stack %addr : $*C
apply undef(%instance) : $@convention(thin) (@guaranteed C) -> ()
destroy_value %instance : $C
%retval = tuple ()
return %retval : $()
die:
unreachable
}
// CHECK-LABEL: sil [ossa] @begin_access : {{.*}} {
// CHECK: [[ADDR:%[^,]+]] = alloc_stack $C
// CHECK: [[ACCESS:%[^,]+]] = begin_access [modify] [static] [[ADDR]]
// CHECK: cond_br undef, {{bb[0-9]+}}, [[DIE:bb[0-9]+]]
// CHECK: [[DIE]]:
// CHECK: end_access [[ACCESS]]
// CHECK: unreachable
// CHECK-LABEL: } // end sil function 'begin_access'
sil [ossa] @begin_access : $@convention(thin) () -> () {
entry:
%addr2 = alloc_stack $C
%access = begin_access [static] [modify] %addr2 : $*C
apply undef(%access) : $@convention(thin) () -> (@out C)
destroy_addr %access : $*C
cond_br undef, exit, die
exit:
end_access %access : $*C
dealloc_stack %addr2 : $*C
%retval = tuple ()
return %retval : $()
die:
unreachable
}
|