Skip to content

Commit 2f665ba

Browse files
authored
Merge pull request #69722 from eeckstein/escape-utils
EscapeUtils: handle `load_borrow`
2 parents 0042201 + 899034b commit 2f665ba

File tree

2 files changed

+38
-2
lines changed

2 files changed

+38
-2
lines changed

SwiftCompilerSources/Sources/Optimizer/Utilities/EscapeUtils.swift

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ extension ProjectedValue {
104104
_ context: some Context) -> V.Result? {
105105
var walker = EscapeWalker(visitor: visitor, complexityBudget: complexityBudget, context)
106106
if walker.walkUp(addressOrValue: value, path: path.escapePath) == .abortWalk {
107+
walker.visitor.cleanupOnAbort()
107108
return nil
108109
}
109110
return walker.visitor.result
@@ -119,6 +120,7 @@ extension ProjectedValue {
119120
_ context: some Context) -> V.Result? {
120121
var walker = EscapeWalker(visitor: visitor, context)
121122
if walker.walkDown(addressOrValue: value, path: path.escapePath) == .abortWalk {
123+
walker.visitor.cleanupOnAbort()
122124
return nil
123125
}
124126
return walker.visitor.result
@@ -182,6 +184,12 @@ extension EscapeVisitor {
182184
protocol EscapeVisitorWithResult : EscapeVisitor {
183185
associatedtype Result
184186
var result: Result { get }
187+
188+
mutating func cleanupOnAbort()
189+
}
190+
191+
extension EscapeVisitorWithResult {
192+
mutating func cleanupOnAbort() {}
185193
}
186194

187195
// FIXME: This ought to be marked private, but that triggers a compiler bug
@@ -482,7 +490,7 @@ fileprivate struct EscapeWalker<V: EscapeVisitor> : ValueDefUseWalker,
482490
// 1. the closure (with the captured values) itself can escape
483491
// 2. something can escape in a destructor when the context is destroyed
484492
return walkDownUses(ofValue: pai, path: path.with(knownType: nil))
485-
case is LoadInst, is LoadWeakInst, is LoadUnownedInst:
493+
case is LoadInst, is LoadWeakInst, is LoadUnownedInst, is LoadBorrowInst:
486494
if !followLoads(at: path.projectionPath) {
487495
return .continueWalk
488496
}
@@ -693,7 +701,7 @@ fileprivate struct EscapeWalker<V: EscapeVisitor> : ValueDefUseWalker,
693701
}
694702
case let ap as ApplyInst:
695703
return walkUpApplyResult(apply: ap, path: path.with(knownType: nil))
696-
case is LoadInst, is LoadWeakInst, is LoadUnownedInst:
704+
case is LoadInst, is LoadWeakInst, is LoadUnownedInst, is LoadBorrowInst:
697705
if !followLoads(at: path.projectionPath) {
698706
// When walking up we shouldn't end up at a load where followLoads is false,
699707
// because going from a (non-followLoads) address to a load always involves a class indirection.

test/SILOptimizer/escape_info.sil

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ enum E {
7777
case B(Z)
7878
}
7979

80+
sil @escaping_argument : $@convention(thin) (@guaranteed Y) -> ()
81+
8082
sil @not_escaping_argument : $@convention(thin) (@guaranteed Z) -> () {
8183
[%0: noescape **]
8284
}
@@ -801,6 +803,32 @@ bb0:
801803
return %9 : $()
802804
}
803805

806+
// CHECK-LABEL: Escape information for test_load_borrow:
807+
// CHECK: global: %0 = alloc_ref $Y
808+
// CHECK: - : %1 = alloc_ref $Y
809+
// CHECK: End function test_load_borrow
810+
sil [ossa] @test_load_borrow : $@convention(thin) () -> () {
811+
bb0:
812+
%0 = alloc_ref $Y
813+
%1 = alloc_ref $Y
814+
%2 = alloc_stack $Y
815+
%3 = alloc_stack $Y
816+
store %0 to [init] %2 : $*Y
817+
store %1 to [init] %3 : $*Y
818+
%6 = load_borrow %2 : $*Y
819+
%7 = load_borrow %3 : $*Y
820+
%8 = function_ref @escaping_argument : $@convention(thin) (@guaranteed Y) -> ()
821+
%9 = apply %8(%6) : $@convention(thin) (@guaranteed Y) -> ()
822+
end_borrow %7 : $Y
823+
end_borrow %6 : $Y
824+
destroy_addr %3 : $*Y
825+
destroy_addr %2 : $*Y
826+
dealloc_stack %3 : $*Y
827+
dealloc_stack %2 : $*Y
828+
%r = tuple ()
829+
return %r : $()
830+
}
831+
804832
// CHECK-LABEL: Escape information for call_unknown:
805833
// CHECK: global: %0 = alloc_ref $X
806834
// CHECK: - : %1 = alloc_ref $Y

0 commit comments

Comments
 (0)