Skip to content

Commit e934bb1

Browse files
committed
BorrowUtils: support guaranteed forwarding phis without forwarding instructions when computing enclosing values
For example: ``` %1 = begin_borrow %0 %2 = br bb1(%1, %1) bb1(%3 : @reborrow @guaranteed, %4: @guaranteed): // %4 is a guaranteed forwarding phi without any forwarding instructions between the begin_borrow and the incoming value. ``` Also improve the comments
1 parent f7d49a9 commit e934bb1

File tree

1 file changed

+23
-5
lines changed

1 file changed

+23
-5
lines changed

SwiftCompilerSources/Sources/Optimizer/Utilities/BorrowUtils.swift

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -592,7 +592,7 @@ func gatherEnclosingValuesFromPredecessors(
592592
let incomingOperand = phi.incomingOperand(inPredecessor: predecessor)
593593

594594
for predEV in incomingOperand.value.getEnclosingValues(context) {
595-
let ev = predecessor.mapToPhiInSuccessor(incomingEnclosingValue: predEV)
595+
let ev = predecessor.getEnclosingValueInSuccessor(ofIncoming: predEV)
596596
if alreadyAdded.insert(ev) {
597597
enclosingValues.push(ev)
598598
}
@@ -601,13 +601,31 @@ func gatherEnclosingValuesFromPredecessors(
601601
}
602602

603603
extension BasicBlock {
604-
func mapToPhiInSuccessor(incomingEnclosingValue: Value) -> Value {
604+
// Returns either the `incomingEnclosingValue` or an adjacent phi in the successor block.
605+
func getEnclosingValueInSuccessor(ofIncoming incomingEnclosingValue: Value) -> Value {
605606
let branch = terminator as! BranchInst
606-
if let incomingEV = branch.operands.first(where: { $0.value.lookThroughBorrowedFrom == incomingEnclosingValue }) {
607+
if let incomingEV = branch.operands.first(where: { branchOp in
608+
// Only if the lifetime of `branchOp` ends at the branch (either because it's a reborrow or an owned value),
609+
// the corresponding phi argument can be the adjacent phi for the incoming value.
610+
// bb1:
611+
// %incomingEnclosingValue = some_owned_value
612+
// %2 = begin_borrow %incomingEnclosingValue // %incomingEnclosingValue = the enclosing value of %2 in bb1
613+
// br bb2(%incomingEnclosingValue, %2) // lifetime of incomingEnclosingValue ends here
614+
// bb2(%4 : @owned, %5 : @guaranteed): // -> %4 = the enclosing value of %5 in bb2
615+
//
616+
branchOp.endsLifetime &&
617+
branchOp.value.lookThroughBorrowedFrom == incomingEnclosingValue
618+
}) {
607619
return branch.getArgument(for: incomingEV)
608620
}
609-
// No candidates phi are outer-adjacent phis. The incoming
610-
// `predDef` must dominate the current guaranteed phi.
621+
// No candidates phi are outer-adjacent phis. The incomingEnclosingValue must dominate the successor block.
622+
// bb1: // dominates bb3
623+
// %incomingEnclosingValue = some_owned_value
624+
// bb2:
625+
// %2 = begin_borrow %incomingEnclosingValue
626+
// br bb3(%2)
627+
// bb3(%5 : @guaranteed): // -> %incomingEnclosingValue = the enclosing value of %5 in bb3
628+
//
611629
return incomingEnclosingValue
612630
}
613631
}

0 commit comments

Comments
 (0)