Skip to content

Commit 28af56e

Browse files
committed
ForwardingUtils.swift cleanup. Make the API easier to extend.
1 parent e7eac7f commit 28af56e

File tree

1 file changed

+52
-32
lines changed

1 file changed

+52
-32
lines changed

SwiftCompilerSources/Sources/Optimizer/Utilities/ForwardingUtils.swift

Lines changed: 52 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@
99
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
1010
//
1111
//===----------------------------------------------------------------------===//
12+
///
13+
/// TODO: Once the hasPointerEscape flags are implemented for
14+
/// BeginBorrowInst, MoveValueInst, and Allocation,
15+
/// ForwardingUseDefWalker should be used to check whether any value
16+
/// is part of a forward-extended lifetime that has a pointer escape.
17+
//===----------------------------------------------------------------------===//
1218

1319
import SIL
1420

@@ -84,9 +90,9 @@ protocol ForwardingUseDefWalker {
8490

8591
extension ForwardingUseDefWalker {
8692
mutating func walkUp(value: Value) -> WalkResult {
87-
walkUpDefault(value: value)
93+
walkUpDefault(forwarded: value)
8894
}
89-
mutating func walkUpDefault(value: Value) -> WalkResult {
95+
mutating func walkUpDefault(forwarded value: Value) -> WalkResult {
9096
if let inst = value.forwardingInstruction {
9197
return walkUp(instruction: inst)
9298
}
@@ -120,18 +126,30 @@ extension ForwardingUseDefWalker {
120126
// This conveniently gathers all forward introducers and deinitializes
121127
// visitedValues before the caller has a chance to recurse.
122128
func gatherLifetimeIntroducers(for value: Value, _ context: Context) -> [Value] {
123-
var gather = GatherLifetimeIntroducers(context)
124-
defer { gather.visitedValues.deinitialize() }
125-
let result = gather.walkUp(value: value)
126-
assert(result == .continueWalk)
127-
return gather.introducers
129+
var introducers: [Value] = []
130+
var walker = VisitLifetimeIntroducers(context) {
131+
introducers.append($0)
132+
return .continueWalk
133+
}
134+
defer { walker.visitedValues.deinitialize() }
135+
_ = walker.walkUp(value: value)
136+
return introducers
128137
}
129138

130-
private struct GatherLifetimeIntroducers : ForwardingUseDefWalker {
139+
// TODO: visitor can be nonescaping when we have borrowed properties.
140+
func visitLifetimeIntroducers(for value: Value, _ context: Context,
141+
visitor: @escaping (Value) -> WalkResult) -> WalkResult {
142+
var walker = VisitLifetimeIntroducers(context, visitor: visitor)
143+
defer { walker.visitedValues.deinitialize() }
144+
return walker.walkUp(value: value)
145+
}
146+
147+
private struct VisitLifetimeIntroducers : ForwardingUseDefWalker {
148+
var visitor: (Value) -> WalkResult
131149
var visitedValues: ValueSet
132-
var introducers: [Value] = []
133150

134-
init(_ context: Context) {
151+
init(_ context: Context, visitor: @escaping (Value) -> WalkResult) {
152+
self.visitor = visitor
135153
self.visitedValues = ValueSet(context)
136154
}
137155

@@ -140,8 +158,7 @@ private struct GatherLifetimeIntroducers : ForwardingUseDefWalker {
140158
}
141159

142160
mutating func introducer(_ value: Value) -> WalkResult {
143-
introducers.append(value)
144-
return .continueWalk
161+
visitor(value)
145162
}
146163
}
147164

@@ -163,7 +180,16 @@ enum ForwardingUseResult: CustomStringConvertible {
163180
}
164181
}
165182

166-
/// Visit all the uses in a forward-extended lifetime (LifetimeIntroducer -> Operand).
183+
/// Visit all the uses in a forward-extended lifetime
184+
/// (LifetimeIntroducer -> Operand).
185+
///
186+
/// Minimal requirements:
187+
/// needWalk(for value: Value) -> Bool
188+
/// leafUse(_ operand: Operand) -> WalkResult
189+
/// deadValue(_ value: Value, using operand: Operand?) -> WalkResult
190+
///
191+
/// Start walking:
192+
/// walkDown(root: Value)
167193
protocol ForwardingDefUseWalker {
168194
// Minimally, check a ValueSet. This walker may traverse chains of
169195
// aggregation and destructuring by default. Implementations may
@@ -180,24 +206,24 @@ protocol ForwardingDefUseWalker {
180206
// \p operand is nil if \p value is the root.
181207
mutating func deadValue(_ value: Value, using operand: Operand?) -> WalkResult
182208

183-
mutating func walkDown(root: Value) -> WalkResult
184-
185209
mutating func walkDownUses(of: Value, using: Operand?) -> WalkResult
186210

187211
mutating func walkDown(operand: Operand) -> WalkResult
188212
}
189213

190214
extension ForwardingDefUseWalker {
215+
/// Start walking
191216
mutating func walkDown(root: Value) -> WalkResult {
192217
walkDownUses(of: root, using: nil)
193218
}
194219

195220
mutating func walkDownUses(of value: Value, using operand: Operand?)
196221
-> WalkResult {
197-
return walkDownUsesDefault(of: value, using: operand)
222+
return walkDownUsesDefault(forwarding: value, using: operand)
198223
}
199224

200-
mutating func walkDownUsesDefault(of value: Value, using operand: Operand?)
225+
mutating func walkDownUsesDefault(forwarding value: Value,
226+
using operand: Operand?)
201227
-> WalkResult {
202228
if !needWalk(for: value) { return .continueWalk }
203229

@@ -215,33 +241,27 @@ extension ForwardingDefUseWalker {
215241
}
216242

217243
mutating func walkDown(operand: Operand) -> WalkResult {
218-
walkDownDefault(operand: operand)
244+
walkDownDefault(forwarding: operand)
219245
}
220246

221-
mutating func walkDownDefault(operand: Operand) -> WalkResult {
247+
mutating func walkDownDefault(forwarding operand: Operand) -> WalkResult {
222248
if let inst = operand.instruction as? ForwardingInstruction {
223-
return walkDownAllResults(of: inst, using: operand)
249+
return inst.forwardedResults.walk { walkDownUses(of: $0, using: operand) }
224250
}
225251
if let phi = Phi(using: operand) {
226252
return walkDownUses(of: phi.value, using: operand)
227253
}
228254
return leafUse(operand)
229255
}
230-
231-
private mutating func walkDownAllResults(of inst: ForwardingInstruction,
232-
using operand: Operand?) -> WalkResult {
233-
for result in inst.forwardedResults {
234-
if walkDownUses(of: result, using: operand) == .abortWalk {
235-
return .abortWalk
236-
}
237-
}
238-
return .continueWalk
239-
}
240256
}
241257

242-
/// This conveniently allows a closure to be called for each leaf use of a forward-extended lifetime. It should be called on a forward introducer provided by ForwardingDefUseWalker.introducer() or gatherLifetimeIntroducers().
258+
/// This conveniently allows a closure to be called for each leaf use
259+
/// of a forward-extended lifetime. It should be called on a forward
260+
/// introducer provided by ForwardingDefUseWalker.introducer() or
261+
/// gatherLifetimeIntroducers().
243262
///
244-
/// TODO: make the visitor non-escaping once Swift supports stored non-escaping closues.
263+
/// TODO: make the visitor non-escaping once Swift supports stored
264+
/// non-escaping closues.
245265
func visitForwardedUses(introducer: Value, _ context: Context,
246266
visitor: @escaping (ForwardingUseResult) -> WalkResult)
247267
-> WalkResult {

0 commit comments

Comments
 (0)