@@ -177,15 +177,29 @@ protocol EscapeVisitor {
177
177
178
178
/// Called during the UseDef walk for each definition
179
179
mutating func visitDef( def: Value , path: EscapePath ) -> DefResult
180
+
181
+ /// Returns true if the type of `value` at `path` is relevant and should be tracked.
182
+ func hasRelevantType( _ value: Value , at path: SmallProjectionPath , analyzeAddresses: Bool ) -> Bool
180
183
}
181
184
182
185
extension EscapeVisitor {
183
186
mutating func visitUse( operand: Operand , path: EscapePath ) -> UseResult {
184
187
return . continueWalk
185
188
}
189
+
186
190
mutating func visitDef( def: Value , path: EscapePath ) -> DefResult {
187
191
return . continueWalkUp
188
192
}
193
+
194
+ func hasRelevantType( _ value: Value , at path: SmallProjectionPath , analyzeAddresses: Bool ) -> Bool {
195
+ let type = value. type
196
+ if type. isNonTrivialOrContainsRawPointer ( in: value. function) { return true }
197
+
198
+ // For selected addresses we also need to consider trivial types (`value`
199
+ // is a selected address if the path does not contain any class projections).
200
+ if analyzeAddresses && type. isAddress && !path. hasClassProjection { return true }
201
+ return false
202
+ }
189
203
}
190
204
191
205
/// A visitor which returns a `result`.
@@ -360,7 +374,7 @@ fileprivate struct EscapeWalker<V: EscapeVisitor> : ValueDefUseWalker,
360
374
}
361
375
362
376
mutating func walkDown( value: Operand , path: Path ) -> WalkResult {
363
- if hasRelevantType ( value. value, at: path. projectionPath) {
377
+ if visitor . hasRelevantType ( value. value, at: path. projectionPath, analyzeAddresses : analyzeAddresses ) {
364
378
switch visitor. visitUse ( operand: value, path: path) {
365
379
case . continueWalk:
366
380
return walkDownDefault ( value: value, path: path)
@@ -456,7 +470,7 @@ fileprivate struct EscapeWalker<V: EscapeVisitor> : ValueDefUseWalker,
456
470
}
457
471
458
472
mutating func walkDown( address: Operand , path: Path ) -> WalkResult {
459
- if hasRelevantType ( address. value, at: path. projectionPath) {
473
+ if visitor . hasRelevantType ( address. value, at: path. projectionPath, analyzeAddresses : analyzeAddresses ) {
460
474
switch visitor. visitUse ( operand: address, path: path) {
461
475
case . continueWalk:
462
476
return walkDownDefault ( address: address, path: path)
@@ -691,7 +705,7 @@ fileprivate struct EscapeWalker<V: EscapeVisitor> : ValueDefUseWalker,
691
705
}
692
706
693
707
mutating func walkUp( value: Value , path: Path ) -> WalkResult {
694
- if hasRelevantType ( value, at: path. projectionPath) {
708
+ if visitor . hasRelevantType ( value, at: path. projectionPath, analyzeAddresses : analyzeAddresses ) {
695
709
switch visitor. visitDef ( def: value, path: path) {
696
710
case . continueWalkUp:
697
711
return walkUpDefault ( value: value, path: path)
@@ -736,7 +750,7 @@ fileprivate struct EscapeWalker<V: EscapeVisitor> : ValueDefUseWalker,
736
750
}
737
751
738
752
mutating func walkUp( address: Value , path: Path ) -> WalkResult {
739
- if hasRelevantType ( address, at: path. projectionPath) {
753
+ if visitor . hasRelevantType ( address, at: path. projectionPath, analyzeAddresses : analyzeAddresses ) {
740
754
switch visitor. visitDef ( def: address, path: path) {
741
755
case . continueWalkUp:
742
756
return walkUpDefault ( address: address, path: path)
@@ -833,17 +847,6 @@ fileprivate struct EscapeWalker<V: EscapeVisitor> : ValueDefUseWalker,
833
847
// private utility functions
834
848
//===--------------------------------------------------------------------===//
835
849
836
- /// Returns true if the type of `value` at `path` is relevant and should be tracked.
837
- private func hasRelevantType( _ value: Value , at path: SmallProjectionPath ) -> Bool {
838
- let type = value. type
839
- if type. isNonTrivialOrContainsRawPointer ( in: value. function) { return true }
840
-
841
- // For selected addresses we also need to consider trivial types (`value`
842
- // is a selected address if the path does not contain any class projections).
843
- if analyzeAddresses && type. isAddress && !path. hasClassProjection { return true }
844
- return false
845
- }
846
-
847
850
/// Returns true if the selected address/value at `path` can be ignored for loading from
848
851
/// that address or for passing that address/value to a called function.
849
852
///
@@ -867,7 +870,7 @@ fileprivate struct EscapeWalker<V: EscapeVisitor> : ValueDefUseWalker,
867
870
/// Tries to pop the given projection from path, if the projected `value` has a relevant type.
868
871
private func pop( _ kind: Path . FieldKind , index: Int ? = nil , from path: Path , yielding value: Value ) -> Path ? {
869
872
if let newPath = path. popIfMatches ( kind, index: index) ,
870
- hasRelevantType ( value, at: newPath. projectionPath) {
873
+ visitor . hasRelevantType ( value, at: newPath. projectionPath, analyzeAddresses : analyzeAddresses ) {
871
874
return newPath
872
875
}
873
876
return nil
0 commit comments