Skip to content

Commit 86d337b

Browse files
committed
EscapeUtils: make hasRelevantType configurable in the EscapeVisitor
1 parent e1c65bd commit 86d337b

File tree

1 file changed

+19
-16
lines changed

1 file changed

+19
-16
lines changed

SwiftCompilerSources/Sources/Optimizer/Utilities/EscapeUtils.swift

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -177,15 +177,29 @@ protocol EscapeVisitor {
177177

178178
/// Called during the UseDef walk for each definition
179179
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
180183
}
181184

182185
extension EscapeVisitor {
183186
mutating func visitUse(operand: Operand, path: EscapePath) -> UseResult {
184187
return .continueWalk
185188
}
189+
186190
mutating func visitDef(def: Value, path: EscapePath) -> DefResult {
187191
return .continueWalkUp
188192
}
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+
}
189203
}
190204

191205
/// A visitor which returns a `result`.
@@ -360,7 +374,7 @@ fileprivate struct EscapeWalker<V: EscapeVisitor> : ValueDefUseWalker,
360374
}
361375

362376
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) {
364378
switch visitor.visitUse(operand: value, path: path) {
365379
case .continueWalk:
366380
return walkDownDefault(value: value, path: path)
@@ -456,7 +470,7 @@ fileprivate struct EscapeWalker<V: EscapeVisitor> : ValueDefUseWalker,
456470
}
457471

458472
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) {
460474
switch visitor.visitUse(operand: address, path: path) {
461475
case .continueWalk:
462476
return walkDownDefault(address: address, path: path)
@@ -691,7 +705,7 @@ fileprivate struct EscapeWalker<V: EscapeVisitor> : ValueDefUseWalker,
691705
}
692706

693707
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) {
695709
switch visitor.visitDef(def: value, path: path) {
696710
case .continueWalkUp:
697711
return walkUpDefault(value: value, path: path)
@@ -736,7 +750,7 @@ fileprivate struct EscapeWalker<V: EscapeVisitor> : ValueDefUseWalker,
736750
}
737751

738752
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) {
740754
switch visitor.visitDef(def: address, path: path) {
741755
case .continueWalkUp:
742756
return walkUpDefault(address: address, path: path)
@@ -833,17 +847,6 @@ fileprivate struct EscapeWalker<V: EscapeVisitor> : ValueDefUseWalker,
833847
// private utility functions
834848
//===--------------------------------------------------------------------===//
835849

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-
847850
/// Returns true if the selected address/value at `path` can be ignored for loading from
848851
/// that address or for passing that address/value to a called function.
849852
///
@@ -867,7 +870,7 @@ fileprivate struct EscapeWalker<V: EscapeVisitor> : ValueDefUseWalker,
867870
/// Tries to pop the given projection from path, if the projected `value` has a relevant type.
868871
private func pop(_ kind: Path.FieldKind, index: Int? = nil, from path: Path, yielding value: Value) -> Path? {
869872
if let newPath = path.popIfMatches(kind, index: index),
870-
hasRelevantType(value, at: newPath.projectionPath) {
873+
visitor.hasRelevantType(value, at: newPath.projectionPath, analyzeAddresses: analyzeAddresses) {
871874
return newPath
872875
}
873876
return nil

0 commit comments

Comments
 (0)