Skip to content

Commit b8b8f1a

Browse files
author
Anxhelo Xhebraj
committed
Swift Optimizer: add SmallProjectionWalkingPaths in WalkUtils
- This protocol with its default implementations simplifies writing walkers, requiring only `merge` for conformance
1 parent 9151db5 commit b8b8f1a

File tree

2 files changed

+44
-23
lines changed

2 files changed

+44
-23
lines changed

SwiftCompilerSources/Sources/Optimizer/Utilities/EscapeInfo.swift

Lines changed: 7 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,7 @@ struct EscapeInfo<V: EscapeInfoVisitor> {
6565
/// The EscapePath is updated and maintained during the up-walk and down-walk.
6666
///
6767
/// It's passed to the EscapeInfoVisitor's `visitUse` and `visitDef`.
68-
struct EscapePath: WalkingPath {
69-
68+
struct EscapePath: SmallProjectionWalkingPath {
7069
/// During the walk, a projection path indicates where the initial value is
7170
/// contained in an aggregate.
7271
/// Example for a walk-down:
@@ -115,12 +114,16 @@ struct EscapeInfo<V: EscapeInfoVisitor> {
115114
/// \endcode
116115
let knownType: Type?
117116

117+
func with(projectionPath: SmallProjectionPath) -> Self {
118+
return Self(projectionPath: projectionPath, followStores: self.followStores, knownType: self.knownType)
119+
}
120+
118121
func with(followStores: Bool) -> Self {
119-
return Self(projectionPath: projectionPath, followStores: followStores, knownType: self.knownType)
122+
return Self(projectionPath: self.projectionPath, followStores: followStores, knownType: self.knownType)
120123
}
121124

122125
func with(knownType: Type?) -> Self {
123-
return Self(projectionPath: projectionPath, followStores: self.followStores, knownType: knownType)
126+
return Self(projectionPath: self.projectionPath, followStores: self.followStores, knownType: knownType)
124127
}
125128

126129
func merge(with other: EscapePath) -> EscapePath {
@@ -138,25 +141,6 @@ struct EscapeInfo<V: EscapeInfoVisitor> {
138141
}
139142
return EscapePath(projectionPath: mergedPath, followStores: mergedFollowStores, knownType: mergedKnownType)
140143
}
141-
142-
// The following push and pop functions simply forward to the projectionPath.
143-
144-
func pop(kind: FieldKind) -> (index: Int, path: Self)? {
145-
if let (idx, p) = projectionPath.pop(kind: kind) {
146-
return (idx, EscapePath(projectionPath: p, followStores: followStores, knownType: knownType))
147-
}
148-
return nil
149-
}
150-
func popIfMatches(_ kind: FieldKind, index: Int?) -> Self? {
151-
if let p = projectionPath.popIfMatches(kind, index: index) {
152-
return EscapePath(projectionPath: p, followStores: followStores, knownType: knownType)
153-
}
154-
return nil
155-
}
156-
func push(_ kind: FieldKind, index: Int) -> Self {
157-
return EscapePath(projectionPath: projectionPath.push(kind, index:index), followStores: followStores, knownType: knownType)
158-
}
159-
160144
}
161145

162146
enum DefVisitResult {

SwiftCompilerSources/Sources/Optimizer/Utilities/WalkUtils.swift

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,43 @@ protocol WalkingPath : Equatable {
6969

7070
extension SmallProjectionPath : WalkingPath { }
7171

72+
/// A `WalkingPath` where `push` and `pop` instructions
73+
/// are forwarded to an underlying `projectionPath`.
74+
protocol SmallProjectionWalkingPath : WalkingPath {
75+
/// During the walk, a projection path indicates where the initial value is
76+
/// contained in an aggregate.
77+
/// Example for a walk-down:
78+
/// \code
79+
/// %1 = alloc_ref // 1. initial value, path = empty
80+
/// %2 = struct $S (%1) // 2. path = s0
81+
/// %3 = tuple (%other, %1) // 3. path = t1.s0
82+
/// %4 = tuple_extract %3, 1 // 4. path = s0
83+
/// %5 = struct_extract %4, #field // 5. path = empty
84+
/// \endcode
85+
///
86+
var projectionPath: SmallProjectionPath { get }
87+
func with(projectionPath: SmallProjectionPath) -> Self
88+
}
89+
90+
extension SmallProjectionWalkingPath {
91+
func pop(kind: FieldKind) -> (index: Int, path: Self)? {
92+
if let (idx, p) = projectionPath.pop(kind: kind) {
93+
return (idx, with(projectionPath: p))
94+
}
95+
return nil
96+
}
97+
98+
func popIfMatches(_ kind: FieldKind, index: Int?) -> Self? {
99+
if let p = projectionPath.popIfMatches(kind, index: index) {
100+
return with(projectionPath: p)
101+
}
102+
return nil
103+
}
104+
func push(_ kind: FieldKind, index: Int) -> Self {
105+
return with(projectionPath: projectionPath.push(kind, index: index))
106+
}
107+
}
108+
72109
/// Caches the state of a walk.
73110
///
74111
/// A client must provide this cache in a `walkUpCache` or `walkDownCache` property.

0 commit comments

Comments
 (0)