Skip to content

Commit 9889f16

Browse files
committed
EscapeUtils: another small refactoring of the isEscape functions
Instead of the `startWalkingDown` arguments, add separate `isEscapingWhenWalkingDown`/`visitByWalkingDown` functions
1 parent a8b5873 commit 9889f16

File tree

2 files changed

+42
-39
lines changed

2 files changed

+42
-39
lines changed

SwiftCompilerSources/Sources/Optimizer/FunctionPasses/ComputeEffects.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ let computeEffects = FunctionPass(name: "compute-effects", {
4646
if argsWithDefinedEffects.contains(arg.index) { continue }
4747

4848
// First check: is the argument (or a projected value of it) escaping at all?
49-
if !arg.at(.anything).isEscaping(using: IgnoreRecursiveCallVisitor(),
50-
startWalkingDown: true, context) {
49+
if !arg.at(.anything).isEscapingWhenWalkingDown(using: IgnoreRecursiveCallVisitor(),
50+
context) {
5151
newEffects.push(ArgumentEffect(.notEscaping, argumentIndex: arg.index, pathPattern: SmallProjectionPath(.anything)))
5252
continue
5353
}
@@ -131,8 +131,8 @@ func addArgEffects(_ arg: FunctionArgument, argPath ap: SmallProjectionPath,
131131
}
132132
}
133133

134-
guard let result = arg.at(argPath).visit(using: ArgEffectsVisitor(),
135-
startWalkingDown: true, context) else {
134+
guard let result = arg.at(argPath).visitByWalkingDown(using: ArgEffectsVisitor(),
135+
context) else {
136136
return false
137137
}
138138

@@ -253,6 +253,6 @@ func isExclusiveEscapeToArgument(fromArgument: Argument, fromPath: SmallProjecti
253253
let visitor = IsExclusiveArgumentEscapeVisitor(fromArgument: fromArgument, fromPath: fromPath,
254254
toArgumentIndex: toArgumentIndex, toPath: toPath)
255255
let toArg = fromArgument.function.arguments[toArgumentIndex]
256-
return !toArg.at(toPath).isEscaping(using: visitor, startWalkingDown: true, context)
256+
return !toArg.at(toPath).isEscapingWhenWalkingDown(using: visitor, context)
257257
}
258258

SwiftCompilerSources/Sources/Optimizer/Utilities/EscapeUtils.swift

Lines changed: 37 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -50,16 +50,9 @@ extension ProjectedValue {
5050
/// The provided `visitor` can be used to override the handling a certain defs and uses during
5151
/// the walk. See `EscapeVisitor` for details.
5252
///
53-
/// By default, the walk starts in upward direction. This makes sense most of the time. But for
54-
/// some use cases, e.g. to check if an argument escapes inside the function (without
55-
/// considering potential escapes in the caller), the walk must start downwards - by setting
56-
/// `startWalkingDown` to true.
57-
///
58-
func isEscaping<V: EscapeVisitor>(using visitor: V = DefaultVisitor(),
59-
startWalkingDown: Bool = false,
60-
_ context: PassContext) -> Bool {
53+
func isEscaping<V: EscapeVisitor>(using visitor: V = DefaultVisitor(), _ context: PassContext) -> Bool {
6154
var walker = EscapeWalker(visitor: visitor, analyzeAddresses: false, context)
62-
return walker.isEscaping(self, startWalkingDown: startWalkingDown)
55+
return walker.walkUp(addressOrValue: value, path: escapePath(path)) == .abortWalk
6356
}
6457

6558
/// Returns true if the projected address value escapes.
@@ -70,11 +63,21 @@ extension ProjectedValue {
7063
/// not the value stored at the address.
7164
/// * Addresses with trivial types are _not_ ignored.
7265
///
73-
func isAddressEscaping<V: EscapeVisitor>(using visitor: V = DefaultVisitor(),
74-
startWalkingDown: Bool = false,
75-
_ context: PassContext) -> Bool {
66+
func isAddressEscaping<V: EscapeVisitor>(using visitor: V = DefaultVisitor(), _ context: PassContext) -> Bool {
7667
var walker = EscapeWalker(visitor: visitor, analyzeAddresses: true, context)
77-
return walker.isEscaping(self, startWalkingDown: startWalkingDown)
68+
return walker.walkUp(addressOrValue: value, path: escapePath(path)) == .abortWalk
69+
}
70+
71+
/// Returns true if the function argument escapes, but ignoring any potential escapes in the caller.
72+
///
73+
/// This function is similar to `ProjectedValue.isEscaping()`, but it ignores any potential
74+
/// escapes which might have happened before the argument's function is called.
75+
/// Technically, this means that the walk starts downwards instead of upwards.
76+
///
77+
func isEscapingWhenWalkingDown<V: EscapeVisitor>(using visitor: V = DefaultVisitor(),
78+
_ context: PassContext) -> Bool {
79+
var walker = EscapeWalker(visitor: visitor, analyzeAddresses: false, context)
80+
return walker.walkDown(addressOrValue: value, path: escapePath(path)) == .abortWalk
7881
}
7982

8083
/// Returns the result of the visitor if the projected value does not escape.
@@ -83,11 +86,9 @@ extension ProjectedValue {
8386
/// it returns the `result` of the `visitor`, if the projected value does not escape.
8487
/// Returns nil, if the projected value escapes.
8588
///
86-
func visit<V: EscapeVisitorWithResult>(using visitor: V,
87-
startWalkingDown: Bool = false,
88-
_ context: PassContext) -> V.Result? {
89+
func visit<V: EscapeVisitorWithResult>(using visitor: V, _ context: PassContext) -> V.Result? {
8990
var walker = EscapeWalker(visitor: visitor, analyzeAddresses: false, context)
90-
if walker.isEscaping(self, startWalkingDown: startWalkingDown) {
91+
if walker.walkUp(addressOrValue: value, path: escapePath(path)) == .abortWalk {
9192
return nil
9293
}
9394
return walker.visitor.result
@@ -99,16 +100,29 @@ extension ProjectedValue {
99100
/// it returns the `result` of the `visitor`, if the projected address does not escape.
100101
/// Returns nil, if the projected address escapes.
101102
///
102-
func visitAddress<V: EscapeVisitorWithResult>(using visitor: V,
103-
startWalkingDown: Bool = false,
104-
_ context: PassContext) -> V.Result? {
103+
func visitAddress<V: EscapeVisitorWithResult>(using visitor: V, _ context: PassContext) -> V.Result? {
105104
var walker = EscapeWalker(visitor: visitor, analyzeAddresses: true, context)
106-
if walker.isEscaping(self, startWalkingDown: startWalkingDown) {
105+
if walker.walkUp(addressOrValue: value, path: escapePath(path)) == .abortWalk {
107106
return nil
108107
}
109108
return walker.visitor.result
110109
}
111110

111+
/// Returns the result of the visitor if the projected value does not escape - ignoring
112+
/// any potential escapes in the caller.
113+
///
114+
/// This function is similar to `isEscapingIgnoringCallerEscapes() -> Bool`, but instead
115+
/// of returning a Bool, it returns the `result` of the `visitor`.
116+
///
117+
func visitByWalkingDown<V: EscapeVisitorWithResult>(using visitor: V,
118+
_ context: PassContext) -> V.Result? {
119+
var walker = EscapeWalker(visitor: visitor, analyzeAddresses: false, context)
120+
if walker.walkDown(addressOrValue: value, path: escapePath(path)) == .abortWalk {
121+
return nil
122+
}
123+
return walker.visitor.result
124+
}
125+
112126
/// Returns true if the address can alias with `rhs`.
113127
///
114128
/// Example:
@@ -132,19 +146,16 @@ extension ProjectedValue {
132146
}
133147
return true
134148
}
135-
136149
}
137150

138151
extension Value {
139152
/// The un-projected version of `ProjectedValue.isEscaping()`.
140-
func isEscaping<V: EscapeVisitor>(using visitor: V = DefaultVisitor(),
141-
_ context: PassContext) -> Bool {
153+
func isEscaping<V: EscapeVisitor>(using visitor: V = DefaultVisitor(), _ context: PassContext) -> Bool {
142154
return self.at(SmallProjectionPath()).isEscaping(using: visitor, context)
143155
}
144156

145157
/// The un-projected version of `ProjectedValue.visit()`.
146-
func visit<V: EscapeVisitorWithResult>(using visitor: V,
147-
_ context: PassContext) -> V.Result? {
158+
func visit<V: EscapeVisitorWithResult>(using visitor: V, _ context: PassContext) -> V.Result? {
148159
return self.at(SmallProjectionPath()).visit(using: visitor, context)
149160
}
150161
}
@@ -328,14 +339,6 @@ fileprivate struct EscapeWalker<V: EscapeVisitor> : ValueDefUseWalker,
328339
self.analyzeAddresses = analyzeAddresses
329340
}
330341

331-
mutating func isEscaping(_ projValue: ProjectedValue, startWalkingDown: Bool) -> Bool {
332-
if startWalkingDown {
333-
return walkDown(addressOrValue: projValue.value, path: escapePath(projValue.path)) == .abortWalk
334-
} else {
335-
return walkUp(addressOrValue: projValue.value, path: escapePath(projValue.path)) == .abortWalk
336-
}
337-
}
338-
339342
//===--------------------------------------------------------------------===//
340343
// Walking down
341344
//===--------------------------------------------------------------------===//

0 commit comments

Comments
 (0)