@@ -17,6 +17,14 @@ class HasInt64 {
17
17
var i : Int64
18
18
}
19
19
20
+ class HasInt64Sub : HasObj {
21
+ var i : Int64
22
+ }
23
+
24
+ class HasHasInt64 : HasObj {
25
+ var hi : HasInt64
26
+ }
27
+
20
28
class HasHasObj {
21
29
var ho : HasObj
22
30
}
@@ -26,10 +34,10 @@ class HasHasObj {
26
34
//
27
35
// CHECK-LABEL: sil @testLocalNotReachesEscaped : $@convention(thin) (Int64, @owned HasObj) -> AnyObject {
28
36
// CHECK: bb0(%0 : $Int64, %1 : $HasObj):
29
- // CHECK: [[LO:%.*]] = alloc_ref $HasInt
37
+ // CHECK: [[LO:%.*]] = alloc_ref $HasInt64
30
38
// CHECK: [[IADR:%.*]] = ref_element_addr [[LO]] : $HasInt64, #HasInt64.i
31
39
// CHECK: store %0 to [[IADR]] : $*Int64
32
- // CHECK: strong_release [[LO]] : $HasInt
40
+ // CHECK: strong_release [[LO]] : $HasInt64
33
41
// CHECK: [[OADR:%.*]] = ref_element_addr %1 : $HasObj, #HasObj.o
34
42
// CHECK: [[O:%.*]] = load [[OADR]] : $*AnyObject
35
43
// CHECK: return [[O]] : $AnyObject
@@ -39,13 +47,39 @@ bb0(%0 : $Int64, %1 : $HasObj):
39
47
%lo = alloc_ref $HasInt64
40
48
%iadr = ref_element_addr %lo : $HasInt64, #HasInt64.i
41
49
store %0 to %iadr : $*Int64
42
-
43
50
%oadr = ref_element_addr %1 : $HasObj, #HasObj.o
44
51
%o = load %oadr : $*AnyObject
45
52
strong_release %lo : $HasInt64
46
53
return %o : $AnyObject
47
54
}
48
55
56
+ // The release of %lo cannot be hoisted over the load because it the
57
+ // release of %lo causes all objects pointed to by its fields to
58
+ // escape. Since it has at least one reference-type field, it may
59
+ // point to escaping memory.
60
+ //
61
+ // CHECK-LABEL: sil @testLocalMayReachEscaped : $@convention(thin) (Int64, @owned HasObj) -> AnyObject {
62
+ // CHECK: bb0(%0 : $Int64, %1 : $HasObj):
63
+ // CHECK: [[LO:%.*]] = alloc_ref $HasInt64Sub
64
+ // CHECK: [[IADR:%.*]] = ref_element_addr [[LO]] : $HasInt64Sub, #HasInt64Sub.i
65
+ // CHECK: store %0 to [[IADR]] : $*Int64
66
+ // CHECK: [[OADR:%.*]] = ref_element_addr %1 : $HasObj, #HasObj.o
67
+ // CHECK: [[O:%.*]] = load [[OADR]] : $*AnyObject
68
+ // CHECK: strong_release [[LO]] : $HasInt64Sub
69
+ // CHECK: return [[O]] : $AnyObject
70
+ // CHECK-LABEL: } // end sil function 'testLocalMayReachEscaped'
71
+ sil @testLocalMayReachEscaped : $@convention(thin) (Int64, @owned HasObj) -> AnyObject {
72
+ bb0(%0 : $Int64, %1 : $HasObj):
73
+ %lo = alloc_ref $HasInt64Sub
74
+ %iadr = ref_element_addr %lo : $HasInt64Sub, #HasInt64Sub.i
75
+ store %0 to %iadr : $*Int64
76
+
77
+ %oadr = ref_element_addr %1 : $HasObj, #HasObj.o
78
+ %o = load %oadr : $*AnyObject
79
+ strong_release %lo : $HasInt64Sub
80
+ return %o : $AnyObject
81
+ }
82
+
49
83
// The release of %lo cannot be hoisted over the load.
50
84
//
51
85
// CHECK-LABEL: sil @testLocalReachesEscaped : $@convention(thin) (@owned AnyObject) -> AnyObject {
@@ -70,10 +104,12 @@ bb0(%0 : $AnyObject):
70
104
return %o : $AnyObject
71
105
}
72
106
73
- // The release of %lo can be hoisted above the load from %oadr. There
74
- // is a points-to relation between %lo and %oadr. However, the
75
- // points-to path from %lo to %oadr reaches another reference counted
76
- // object before reaching $oadr.
107
+ // The release of %lo cannot be hoisted above the load from %oadr
108
+ // because there is a points-to relation between %lo and %oadr.
109
+ //
110
+ // TODO: To hoist this release, AliasAnalysis also need to prove that
111
+ // it isn't being hoisted above the last use. This information is not
112
+ // properly communicated between AliasAnalysis and EscapeAnalysis.
77
113
//
78
114
// CHECK-LABEL: sil @testLocalReachesRCEscaped : $@convention(thin) (@owned HasObj) -> AnyObject {
79
115
// CHECK: bb0(%0 : $HasObj):
@@ -82,9 +118,9 @@ bb0(%0 : $AnyObject):
82
118
// CHECK: strong_retain %0 : $HasObj
83
119
// CHECK: store %0 to [[HOADR]] : $*HasObj
84
120
// CHECK: [[HO:%.*]] = load [[HOADR]] : $*HasObj
85
- // CHECK: strong_release [[LO]] : $HasHasObj
86
121
// CHECK: [[OADR:%.*]] = ref_element_addr [[HO]] : $HasObj, #HasObj.o
87
122
// CHECK: [[O:%.*]] = load [[OADR]] : $*AnyObject
123
+ // CHECK: strong_release [[LO]] : $HasHasObj
88
124
// CHECK: return [[O]] : $AnyObject
89
125
// CHECK-LABEL: } // end sil function 'testLocalReachesRCEscaped'
90
126
sil @testLocalReachesRCEscaped : $@convention(thin) (@owned HasObj) -> AnyObject {
@@ -144,9 +180,13 @@ bb0(%0 : $AnyObject):
144
180
return %o : $AnyObject
145
181
}
146
182
147
- // Two local references, one reachable from the other. We assume that
183
+ // Two local references, one reachable from the other. We cannot assume that
148
184
// the reachable one has its own reference count and hoist
149
- // strong_release %hho above load %oadr.
185
+ // strong_release %hho above load %oadr without more information.
186
+ //
187
+ // TODO: To hoist this release, AliasAnalysis also need to prove that
188
+ // it isn't being hoisted above the last use. This information is not
189
+ // properly communicated between AliasAnalysis and EscapeAnalysis.
150
190
//
151
191
// CHECK-LABEL: sil @testLocalReachesRCLocal : $@convention(thin) (AnyObject) -> AnyObject {
152
192
// CHECK: bb0(%0 : $AnyObject):
@@ -158,9 +198,9 @@ bb0(%0 : $AnyObject):
158
198
// CHECK: [[HOADR:%.*]] = ref_element_addr [[HHO]] : $HasHasObj, #HasHasObj.ho
159
199
// CHECK: store [[LO]] to [[HOADR]] : $*HasObj
160
200
// CHECK: [[HO:%.*]] = load [[HOADR]] : $*HasObj
161
- // CHECK: strong_release [[HHO]] : $HasHasObj
162
201
// CHECK: [[OADR2:%.*]] = ref_element_addr [[HO]] : $HasObj, #HasObj.o
163
202
// CHECK: [[O:%.*]] = load [[OADR2]] : $*AnyObject
203
+ // CHECK: strong_release [[HHO]] : $HasHasObj
164
204
// CHECK: strong_retain [[O]] : $AnyObject
165
205
// CHECK: return [[O]] : $AnyObject
166
206
// CHECK-LABEL: } // end sil function 'testLocalReachesRCLocal'
@@ -232,3 +272,33 @@ bb0(%0 : $AnyObject, %1 : $HasHasObj):
232
272
strong_release %1 : $HasHasObj
233
273
return %o : $AnyObject
234
274
}
275
+
276
+ // 'strong_release %lo : $HasHasInt64' cannot be hoisted because it
277
+ // contains a reference that appears to escape. With the current
278
+ // information, we can't be sure if that escaping reference points to
279
+ // the load of '%oadr'.
280
+ //
281
+ // TODO: To hoist this release, AliasAnalysis also need to prove that
282
+ // it isn't being hoisted above the last use. This information is not
283
+ // properly communicated between AliasAnalysis and EscapeAnalysis.
284
+ //
285
+ // CHECK-LABEL: sil @testLocalWithReferenceProperty : $@convention(thin) (Int64, @owned HasObj) -> AnyObject {
286
+ // CHECK: bb0(%0 : $Int64, %1 : $HasObj):
287
+ // CHECK: [[O:%.*]] = load {{.*}} : $*AnyObject
288
+ // CHECK: strong_release %{{.*}} : $HasHasInt64
289
+ // CHECK: return [[O]] : $AnyObject
290
+ // CHECK-LABEL: } // end sil function 'testLocalWithReferenceProperty'
291
+ sil @testLocalWithReferenceProperty : $@convention(thin) (Int64, @owned HasObj) -> AnyObject {
292
+ bb0(%0 : $Int64, %1 : $HasObj):
293
+ %hi = alloc_ref $HasInt64
294
+ %iadr = ref_element_addr %hi : $HasInt64, #HasInt64.i
295
+ store %0 to %iadr : $*Int64
296
+ %lo = alloc_ref $HasHasInt64
297
+ %hiadr = ref_element_addr %lo : $HasHasInt64, #HasHasInt64.hi
298
+ store %hi to %hiadr : $*HasInt64
299
+
300
+ %oadr = ref_element_addr %1 : $HasObj, #HasObj.o
301
+ %o = load %oadr : $*AnyObject
302
+ strong_release %lo : $HasHasInt64
303
+ return %o : $AnyObject
304
+ }
0 commit comments