Skip to content

Commit ff4d053

Browse files
committed
[NFC] LifetimeDependenceDefUseWalker.inoutDependence entry point
Handle cases where there's no relevant operand.
1 parent a0f0c10 commit ff4d053

File tree

4 files changed

+23
-25
lines changed

4 files changed

+23
-25
lines changed

SwiftCompilerSources/Sources/Optimizer/FunctionPasses/LifetimeDependenceDiagnostics.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -557,9 +557,9 @@ extension DiagnoseDependenceWalker : LifetimeDependenceDefUseWalker {
557557
return .abortWalk
558558
}
559559

560-
mutating func inoutDependence(argument: FunctionArgument, on operand: Operand) -> WalkResult {
560+
mutating func inoutDependence(argument: FunctionArgument, functionExit: Instruction) -> WalkResult {
561561
if diagnostics.checkInoutResult(argument: argument) == .abortWalk {
562-
diagnostics.reportEscaping(operand: operand)
562+
diagnostics.reportEscaping(value: argument, user: functionExit)
563563
return .abortWalk
564564
}
565565
return .continueWalk

SwiftCompilerSources/Sources/Optimizer/FunctionPasses/LifetimeDependenceScopeFixup.swift

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -685,7 +685,7 @@ extension ScopeExtension {
685685
do {
686686
// The innermost scope that must be extended must dominate all uses.
687687
var walker = LifetimeDependentUseWalker(function, localReachabilityCache, context) {
688-
inRangeUses.append($0.instruction)
688+
inRangeUses.append($0)
689689
return .continueWalk
690690
}
691691
defer {walker.deinitialize()}
@@ -1064,15 +1064,15 @@ private extension BeginApplyInst {
10641064
private struct LifetimeDependentUseWalker : LifetimeDependenceDefUseWalker {
10651065
let function: Function
10661066
let context: Context
1067-
let visitor: (Operand) -> WalkResult
1067+
let visitor: (Instruction) -> WalkResult
10681068
let localReachabilityCache: LocalVariableReachabilityCache
10691069
var visitedValues: ValueSet
10701070

10711071
/// Set to true if the dependence is returned from the current function.
10721072
var dependsOnCaller = false
10731073

10741074
init(_ function: Function, _ localReachabilityCache: LocalVariableReachabilityCache, _ context: Context,
1075-
visitor: @escaping (Operand) -> WalkResult) {
1075+
visitor: @escaping (Instruction) -> WalkResult) {
10761076
self.function = function
10771077
self.context = context
10781078
self.visitor = visitor
@@ -1091,42 +1091,42 @@ private struct LifetimeDependentUseWalker : LifetimeDependenceDefUseWalker {
10911091
mutating func deadValue(_ value: Value, using operand: Operand?)
10921092
-> WalkResult {
10931093
if let operand {
1094-
return visitor(operand)
1094+
return visitor(operand.instruction)
10951095
}
10961096
return .continueWalk
10971097
}
10981098

10991099
mutating func leafUse(of operand: Operand) -> WalkResult {
1100-
return visitor(operand)
1100+
return visitor(operand.instruction)
11011101
}
11021102

11031103
mutating func escapingDependence(on operand: Operand) -> WalkResult {
11041104
log(">>> Escaping dependence: \(operand)")
1105-
_ = visitor(operand)
1105+
_ = visitor(operand.instruction)
11061106
// Make a best-effort attempt to extend the access scope regardless of escapes. It is possible that some mandatory
11071107
// pass between scope fixup and diagnostics will make it possible for the LifetimeDependenceDefUseWalker to analyze
11081108
// this use.
11091109
return .continueWalk
11101110
}
11111111

1112-
mutating func inoutDependence(argument: FunctionArgument, on operand: Operand) -> WalkResult {
1112+
mutating func inoutDependence(argument: FunctionArgument, functionExit: Instruction) -> WalkResult {
11131113
dependsOnCaller = true
1114-
return visitor(operand)
1114+
return visitor(functionExit)
11151115
}
11161116

11171117
mutating func returnedDependence(result operand: Operand) -> WalkResult {
11181118
dependsOnCaller = true
1119-
return visitor(operand)
1119+
return visitor(operand.instruction)
11201120
}
11211121

11221122
mutating func returnedDependence(address: FunctionArgument,
11231123
on operand: Operand) -> WalkResult {
11241124
dependsOnCaller = true
1125-
return visitor(operand)
1125+
return visitor(operand.instruction)
11261126
}
11271127

11281128
mutating func yieldedDependence(result: Operand) -> WalkResult {
1129-
return visitor(result)
1129+
return visitor(result.instruction)
11301130
}
11311131

11321132
mutating func storeToYieldDependence(address: Value, of operand: Operand) -> WalkResult {

SwiftCompilerSources/Sources/Optimizer/Utilities/LifetimeDependenceUtils.swift

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -614,7 +614,7 @@ extension LifetimeDependence.Scope {
614614
/// leafUse(of: Operand) -> WalkResult
615615
/// deadValue(_ value: Value, using operand: Operand?) -> WalkResult
616616
/// escapingDependence(on operand: Operand) -> WalkResult
617-
/// inoutDependence(argument: FunctionArgument, on: Operand) -> WalkResult
617+
/// inoutDependence(argument: FunctionArgument, functionExit: Instruction) -> WalkResult
618618
/// returnedDependence(result: Operand) -> WalkResult
619619
/// returnedDependence(address: FunctionArgument, on: Operand) -> WalkResult
620620
/// yieldedDependence(result: Operand) -> WalkResult
@@ -634,9 +634,9 @@ protocol LifetimeDependenceDefUseWalker : ForwardingDefUseWalker,
634634

635635
mutating func escapingDependence(on operand: Operand) -> WalkResult
636636

637-
// Assignment to an inout argument. This does not include the indirect out result, which is considered a return
637+
// Assignment to an inout argument. This does not include the @out result, which is considered a return
638638
// value.
639-
mutating func inoutDependence(argument: FunctionArgument, on: Operand) -> WalkResult
639+
mutating func inoutDependence(argument: FunctionArgument, functionExit: Instruction) -> WalkResult
640640

641641
mutating func returnedDependence(result: Operand) -> WalkResult
642642

@@ -1025,15 +1025,12 @@ extension LifetimeDependenceDefUseWalker {
10251025
if !localReachability.gatherAllReachableUses(of: storeAccess, in: &accessStack) {
10261026
return escapingDependence(on: storedOperand)
10271027
}
1028-
for localAccess in accessStack {
1029-
if visitLocalAccess(allocation: allocation, localAccess: localAccess, initialValue: storedOperand) == .abortWalk {
1030-
return .abortWalk
1031-
}
1028+
return accessStack.walk { localAccess in
1029+
visitLocalAccess(allocation: allocation, localAccess: localAccess)
10321030
}
1033-
return .continueWalk
10341031
}
10351032

1036-
private mutating func visitLocalAccess(allocation: Value, localAccess: LocalVariableAccess, initialValue: Operand)
1033+
private mutating func visitLocalAccess(allocation: Value, localAccess: LocalVariableAccess)
10371034
-> WalkResult {
10381035
switch localAccess.kind {
10391036
case .beginAccess:
@@ -1080,7 +1077,7 @@ extension LifetimeDependenceDefUseWalker {
10801077
case .outgoingArgument:
10811078
let arg = allocation as! FunctionArgument
10821079
assert(arg.type.isAddress, "returned local must be allocated with an indirect argument")
1083-
return inoutDependence(argument: arg, on: initialValue)
1080+
return inoutDependence(argument: arg, functionExit: localAccess.instruction!)
10841081
case .inoutYield:
10851082
return yieldedDependence(result: localAccess.operand!)
10861083
case .incomingArgument:
@@ -1180,8 +1177,8 @@ private struct LifetimeDependenceUsePrinter : LifetimeDependenceDefUseWalker {
11801177
return .continueWalk
11811178
}
11821179

1183-
mutating func inoutDependence(argument: FunctionArgument, on operand: Operand) -> WalkResult {
1184-
print("Out use: \(operand) in: \(argument)")
1180+
mutating func inoutDependence(argument: FunctionArgument, functionExit: Instruction) -> WalkResult {
1181+
print("Returned inout: \(argument) exit: \(functionExit)")
11851182
return .continueWalk
11861183
}
11871184

SwiftCompilerSources/Sources/Optimizer/Utilities/LocalVariableUtils.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -857,6 +857,7 @@ extension LocalVariableReachableAccess {
857857
break
858858
}
859859
if block.terminator.isFunctionExiting {
860+
// Record any reachable function exit as .outgoingArgument.
860861
accessStack.push(LocalVariableAccess(.outgoingArgument, block.terminator))
861862
} else if block.successors.isEmpty {
862863
accessStack.push(LocalVariableAccess(.deadEnd, block.terminator))

0 commit comments

Comments
 (0)