@@ -95,7 +95,7 @@ typealias InnerScopeHandler = (Value) -> WalkResult
9595/// - All inner scopes are complete. (Use `innerScopeHandler` to complete them or bail-out).
9696func computeInteriorLiveness( for definingValue: Value , _ context: FunctionPassContext ,
9797 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)
9999 switch result. pointerStatus {
100100 case . nonescaping:
101101 break
@@ -113,8 +113,9 @@ func computeInteriorLiveness(for definingValue: Value, _ context: FunctionPassCo
113113/// Compute known liveness and return a range, which the caller must deinitialize.
114114///
115115/// 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
118119}
119120
120121/// If any interior pointer may escape, then record the first instance here. If 'ignoseEscape' is true, this
@@ -161,7 +162,7 @@ struct InteriorLivenessResult: CustomDebugStringConvertible {
161162 let range : InstructionRange
162163 let pointerStatus : InteriorPointerStatus
163164
164- static func compute( for definingValue: Value , ignoreEscape: Bool = false ,
165+ static func compute( for definingValue: Value , ignoreEscape: Bool = false , visitInnerUses : Bool ,
165166 _ context: FunctionPassContext ,
166167 innerScopeHandler: InnerScopeHandler ? = nil ) -> InteriorLivenessResult {
167168
@@ -170,7 +171,8 @@ struct InteriorLivenessResult: CustomDebugStringConvertible {
170171
171172 var range = InstructionRange ( for: definingValue, context)
172173
173- var visitor = InteriorUseWalker ( definingValue: definingValue, ignoreEscape: ignoreEscape, context) {
174+ var visitor = InteriorUseWalker ( definingValue: definingValue, ignoreEscape: ignoreEscape,
175+ visitInnerUses: visitInnerUses, context) {
174176 range. insert ( $0. instruction)
175177 return . continueWalk
176178 }
@@ -526,6 +528,11 @@ struct InteriorUseWalker {
526528
527529 let definingValue : Value
528530 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+
529536 let useVisitor : ( Operand ) -> WalkResult
530537
531538 var innerScopeHandler : InnerScopeHandler ? = nil
@@ -549,12 +556,13 @@ struct InteriorUseWalker {
549556 visited. deinitialize ( )
550557 }
551558
552- init ( definingValue: Value , ignoreEscape: Bool , _ context: FunctionPassContext ,
559+ init ( definingValue: Value , ignoreEscape: Bool , visitInnerUses : Bool , _ context: FunctionPassContext ,
553560 visitor: @escaping ( Operand ) -> WalkResult ) {
554561 assert ( !definingValue. type. isAddress, " address values have no ownership " )
555562 self . functionContext = context
556563 self . definingValue = definingValue
557564 self . ignoreEscape = ignoreEscape
565+ self . visitInnerUses = visitInnerUses
558566 self . useVisitor = visitor
559567 self . visited = ValueSet ( context)
560568 }
@@ -665,6 +673,9 @@ extension InteriorUseWalker: OwnershipUseVisitor {
665673 if handleInner ( borrowed: beginBorrow. value) == . abortWalk {
666674 return . abortWalk
667675 }
676+ if visitInnerUses {
677+ return visitUsesOfOuter ( value: beginBorrow. value)
678+ }
668679 }
669680 return visitInnerBorrowUses ( of: borrowInst)
670681 }
@@ -950,7 +961,7 @@ let interiorLivenessTest = FunctionTest("interior_liveness_swift") {
950961 var range = InstructionRange ( for: value, context)
951962 defer { range. deinitialize ( ) }
952963
953- var visitor = InteriorUseWalker ( definingValue: value, ignoreEscape: true , context) {
964+ var visitor = InteriorUseWalker ( definingValue: value, ignoreEscape: true , visitInnerUses : false , context) {
954965 range. insert ( $0. instruction)
955966 return . continueWalk
956967 }
0 commit comments