Skip to content

Commit e225415

Browse files
committed
Remove unused computeInterorLiveness API.
This encourages the client to check whether InteriorLivenessResult is valid or escaping before using the instruction range.
1 parent fda5392 commit e225415

File tree

1 file changed

+35
-40
lines changed

1 file changed

+35
-40
lines changed

SwiftCompilerSources/Sources/Optimizer/Utilities/OwnershipLiveness.swift

Lines changed: 35 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -72,49 +72,16 @@ func computeLinearLiveness(for definingValue: Value, _ context: Context)
7272
return range
7373
}
7474

75-
typealias InnerScopeHandler = (Value) -> WalkResult
76-
77-
/// Compute liveness and return a range, which the caller must deinitialize.
78-
///
79-
/// An OSSA lifetime begins with a single "defining" value, which must be owned, or must begin a borrow scope. A
80-
/// complete OSSA lifetime has a linear lifetime, meaning that it has a lifetime-ending use on all paths. Interior
81-
/// liveness computes liveness without assuming the lifetime is complete. To do this, it must find all "use points" and
82-
/// prove that the defining value is never propagated beyond those points. This is used to initially complete OSSA
83-
/// lifetimes and fix them after transformations that's don't preserve OSSA.
84-
///
85-
/// The caller must check that `definingValue` has no pointer escape before calling this.
86-
///
87-
/// Invariants:
88-
///
89-
/// - The definition dominates all use points.
90-
///
91-
/// - Liveness does not extend beyond lifetime-ending operations
92-
/// (a.k.a. affine lifetimes).
93-
///
94-
/// - All inner scopes are complete. (Use `innerScopeHandler` to complete them or bail-out).
95-
func computeInteriorLiveness(for definingValue: Value, _ context: FunctionPassContext,
96-
innerScopeHandler: InnerScopeHandler? = nil) -> InstructionRange {
97-
let result = InteriorLivenessResult.compute(for: definingValue, ignoreEscape: false, visitInnerUses: false, context)
98-
switch result.pointerStatus {
99-
case .nonescaping:
100-
break
101-
case let .escaping(operands):
102-
fatalError("""
103-
check findPointerEscape() before computing interior liveness.
104-
Pointer escape: \(operands[0].instruction)
105-
""")
106-
case let .unknown(operand):
107-
fatalError("Unrecognized SIL address user \(operand.instruction)")
108-
}
109-
return result.range
110-
}
111-
11275
/// Compute known liveness and return a range, which the caller must deinitialize.
11376
///
11477
/// This computes a minimal liveness, ignoring pointer escaping uses.
115-
func computeKnownLiveness(for definingValue: Value, visitInnerUses: Bool = false, _ context: FunctionPassContext) -> InstructionRange {
78+
///
79+
/// The caller must call deinitialize() on the result.
80+
func computeKnownLiveness(for definingValue: Value, visitInnerUses: Bool = false, _ context: FunctionPassContext)
81+
-> InstructionRange {
82+
// Ignore pointer escapes and other failures.
11683
return InteriorLivenessResult.compute(for: definingValue, ignoreEscape: true,
117-
visitInnerUses: visitInnerUses, context).range
84+
visitInnerUses: visitInnerUses, context).acquireRange
11885
}
11986

12087
/// If any interior pointer may escape, then record the first instance here. If 'ignoseEscape' is true, this
@@ -156,11 +123,32 @@ enum InteriorPointerStatus: CustomDebugStringConvertible {
156123
}
157124
}
158125

126+
typealias InnerScopeHandler = (Value) -> WalkResult
127+
128+
/// An OSSA lifetime begins with a single "defining" value, which must be owned, or must begin a borrow scope. A
129+
/// complete OSSA lifetime has a linear lifetime, meaning that it has a lifetime-ending use on all paths. Interior
130+
/// liveness computes liveness without assuming the lifetime is complete. To do this, it must find all "use points" and
131+
/// prove that the defining value is never propagated beyond those points. This is used to initially complete OSSA
132+
/// lifetimes and fix them after transformations that's don't preserve OSSA.
133+
///
134+
/// Invariants:
135+
///
136+
/// - The definition dominates all use points (hence the result is a single InstructionRange).
137+
///
138+
/// - Liveness does not extend beyond lifetime-ending operations (a.k.a. affine lifetimes).
139+
///
140+
/// - All inner scopes are complete. (Use `innerScopeHandler` to either complete them or to recursively compute their
141+
/// liveness and either bail-out on or propagate inner pointer escapes outward).
159142
struct InteriorLivenessResult: CustomDebugStringConvertible {
143+
// 'success' may only be set to .abortWalk if pointerStatus != .nonescaping or visitInnerUses returned false.
144+
// The client can therefore ensure success if it has already checked for pointer escapes.
160145
let success: WalkResult
161-
let range: InstructionRange
146+
var range: InstructionRange
162147
let pointerStatus: InteriorPointerStatus
163148

149+
/// Compute liveness for a single OSSA value without assuming a complete lifetime.
150+
///
151+
/// The caller must call acquireRange or deinitialize() on the result.
164152
static func compute(for definingValue: Value, ignoreEscape: Bool = false, visitInnerUses: Bool,
165153
_ context: FunctionPassContext,
166154
innerScopeHandler: InnerScopeHandler? = nil) -> InteriorLivenessResult {
@@ -184,6 +172,13 @@ struct InteriorLivenessResult: CustomDebugStringConvertible {
184172
return result
185173
}
186174

175+
/// Client must call deinitialize() on the result.
176+
var acquireRange: InstructionRange { consuming get { range } }
177+
178+
mutating func deinitialize() {
179+
range.deinitialize()
180+
}
181+
187182
var debugDescription: String {
188183
"\(success)\n\(range)\n\(pointerStatus)"
189184
}

0 commit comments

Comments
 (0)