@@ -95,7 +95,7 @@ typealias InnerScopeHandler = (Value) -> WalkResult
95
95
/// - All inner scopes are complete. (Use `innerScopeHandler` to complete them or bail-out).
96
96
func computeInteriorLiveness( for definingValue: Value , _ context: FunctionPassContext ,
97
97
innerScopeHandler: InnerScopeHandler ? = nil ) -> InstructionRange {
98
- let result = InteriorLivenessResult . compute ( for: definingValue, ignoreEscape: false , context)
98
+ let result = InteriorLivenessResult . compute ( for: definingValue, ignoreEscape: false , visitInnerUses : false , context)
99
99
switch result. pointerStatus {
100
100
case . nonescaping:
101
101
break
@@ -113,8 +113,9 @@ func computeInteriorLiveness(for definingValue: Value, _ context: FunctionPassCo
113
113
/// Compute known liveness and return a range, which the caller must deinitialize.
114
114
///
115
115
/// This computes a minimal liveness, ignoring pointer escaping uses.
116
- func computeKnownLiveness( for definingValue: Value , _ context: FunctionPassContext ) -> InstructionRange {
117
- return InteriorLivenessResult . compute ( for: definingValue, ignoreEscape: true , context) . range
116
+ func computeKnownLiveness( for definingValue: Value , visitInnerUses: Bool = false , _ context: FunctionPassContext ) -> InstructionRange {
117
+ return InteriorLivenessResult . compute ( for: definingValue, ignoreEscape: true ,
118
+ visitInnerUses: visitInnerUses, context) . range
118
119
}
119
120
120
121
/// If any interior pointer may escape, then record the first instance here. If 'ignoseEscape' is true, this
@@ -161,7 +162,7 @@ struct InteriorLivenessResult: CustomDebugStringConvertible {
161
162
let range : InstructionRange
162
163
let pointerStatus : InteriorPointerStatus
163
164
164
- static func compute( for definingValue: Value , ignoreEscape: Bool = false ,
165
+ static func compute( for definingValue: Value , ignoreEscape: Bool = false , visitInnerUses : Bool ,
165
166
_ context: FunctionPassContext ,
166
167
innerScopeHandler: InnerScopeHandler ? = nil ) -> InteriorLivenessResult {
167
168
@@ -170,7 +171,8 @@ struct InteriorLivenessResult: CustomDebugStringConvertible {
170
171
171
172
var range = InstructionRange ( for: definingValue, context)
172
173
173
- var visitor = InteriorUseWalker ( definingValue: definingValue, ignoreEscape: ignoreEscape, context) {
174
+ var visitor = InteriorUseWalker ( definingValue: definingValue, ignoreEscape: ignoreEscape,
175
+ visitInnerUses: visitInnerUses, context) {
174
176
range. insert ( $0. instruction)
175
177
return . continueWalk
176
178
}
@@ -526,6 +528,11 @@ struct InteriorUseWalker {
526
528
527
529
let definingValue : Value
528
530
let ignoreEscape : Bool
531
+
532
+ // If true, it's not assumed that inner scopes are linear. It forces to visit
533
+ // all interior uses if inner scopes.
534
+ let visitInnerUses : Bool
535
+
529
536
let useVisitor : ( Operand ) -> WalkResult
530
537
531
538
var innerScopeHandler : InnerScopeHandler ? = nil
@@ -549,12 +556,13 @@ struct InteriorUseWalker {
549
556
visited. deinitialize ( )
550
557
}
551
558
552
- init ( definingValue: Value , ignoreEscape: Bool , _ context: FunctionPassContext ,
559
+ init ( definingValue: Value , ignoreEscape: Bool , visitInnerUses : Bool , _ context: FunctionPassContext ,
553
560
visitor: @escaping ( Operand ) -> WalkResult ) {
554
561
assert ( !definingValue. type. isAddress, " address values have no ownership " )
555
562
self . functionContext = context
556
563
self . definingValue = definingValue
557
564
self . ignoreEscape = ignoreEscape
565
+ self . visitInnerUses = visitInnerUses
558
566
self . useVisitor = visitor
559
567
self . visited = ValueSet ( context)
560
568
}
@@ -665,6 +673,9 @@ extension InteriorUseWalker: OwnershipUseVisitor {
665
673
if handleInner ( borrowed: beginBorrow. value) == . abortWalk {
666
674
return . abortWalk
667
675
}
676
+ if visitInnerUses {
677
+ return visitUsesOfOuter ( value: beginBorrow. value)
678
+ }
668
679
}
669
680
return visitInnerBorrowUses ( of: borrowInst)
670
681
}
@@ -950,7 +961,7 @@ let interiorLivenessTest = FunctionTest("interior_liveness_swift") {
950
961
var range = InstructionRange ( for: value, context)
951
962
defer { range. deinitialize ( ) }
952
963
953
- var visitor = InteriorUseWalker ( definingValue: value, ignoreEscape: true , context) {
964
+ var visitor = InteriorUseWalker ( definingValue: value, ignoreEscape: true , visitInnerUses : false , context) {
954
965
range. insert ( $0. instruction)
955
966
return . continueWalk
956
967
}
0 commit comments