Skip to content

Commit d602836

Browse files
committed
EscapeUtils: consider that a begin_apply can yield it's indirect arguments
This is the only apply instruction where address arguments actually can "escape"
1 parent 113e23d commit d602836

File tree

2 files changed

+36
-1
lines changed

2 files changed

+36
-1
lines changed

SwiftCompilerSources/Sources/Optimizer/Utilities/EscapeUtils.swift

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -547,7 +547,9 @@ fileprivate struct EscapeWalker<V: EscapeVisitor> : ValueDefUseWalker,
547547
}
548548

549549
// Indirect arguments cannot escape the function, but loaded values from such can.
550-
if !followLoads(at: path.projectionPath) {
550+
if !followLoads(at: path.projectionPath) &&
551+
// Except for begin_apply: it can yield an address value.
552+
!apply.isBeginApplyWithIndirectResults {
551553
return .continueWalk
552554
}
553555

@@ -824,3 +826,13 @@ private extension SmallProjectionPath {
824826
EscapeUtilityTypes.EscapePath(projectionPath: self, followStores: false, knownType: nil)
825827
}
826828
}
829+
830+
private extension ApplySite {
831+
var isBeginApplyWithIndirectResults: Bool {
832+
guard let ba = self as? BeginApplyInst else {
833+
return false
834+
}
835+
// Note that the token result is always a non-address type.
836+
return ba.results.contains { $0.type.isAddress }
837+
}
838+
}

test/SILOptimizer/addr_escape_info.sil

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ sil @initX : $@convention(method) (@owned X) -> @owned X {
5151
[%0: escape => %r, escape c*.v** => %r.c*.v**]
5252
}
5353
sil @modifyStr : $@convention(method) (@inout Str) -> ()
54+
sil @guaranteed_yield_coroutine : $@yield_once @convention(thin) (@inout X) -> @yields @inout X
5455

5556
// CHECK-LABEL: Address escape information for test_simple:
5657
// CHECK: value: %1 = struct_element_addr %0 : $*Str, #Str.a
@@ -268,6 +269,28 @@ bb0:
268269
return %12 : $()
269270
}
270271

272+
// CHECK-LABEL: Address escape information for indirect_argument_escape_to_yield:
273+
// CHECK: value: %1 = alloc_stack $X
274+
// CHECK-NEXT: ==> (%5, %6) = begin_apply %4(%1) : $@yield_once @convention(thin) (@inout X) -> @yields @inout X
275+
// CHECK-NEXT: ==> %8 = apply %7(%5) : $@convention(thin) (@inout X) -> ()
276+
// CHECK: End function indirect_argument_escape_to_yield
277+
sil @indirect_argument_escape_to_yield : $@convention(thin) (@guaranteed X) -> () {
278+
bb0(%0 : $X):
279+
%1 = alloc_stack $X
280+
store %0 to %1 : $*X
281+
fix_lifetime %1 : $*X
282+
%3 = function_ref @guaranteed_yield_coroutine : $@yield_once @convention(thin) (@inout X) -> @yields @inout X
283+
(%4, %5) = begin_apply %3(%1) : $@yield_once @convention(thin) (@inout X) -> @yields @inout X
284+
285+
%6 = function_ref @inout_class_argument : $@convention(thin) (@inout X) -> ()
286+
%7 = apply %6(%4) : $@convention(thin) (@inout X) -> ()
287+
288+
end_apply %5
289+
dealloc_stack %1 : $*X
290+
%r = tuple ()
291+
return %r : $()
292+
}
293+
271294
// CHECK-LABEL: Address escape information for ignore_copy_addr_and_release:
272295
// CHECK: value: %1 = ref_element_addr %0 : $X, #X.s
273296
// CHECK-NEXT: - %6 = apply %5(%3) : $@convention(thin) (@in Str) -> ()

0 commit comments

Comments
 (0)