Skip to content

Commit 1b916b2

Browse files
authored
Merge pull request #79810 from meg-gupta/fixctb
Fix copy-to-borrow optimization's end_borrow insertion
2 parents 35fed04 + 87dcb65 commit 1b916b2

File tree

2 files changed

+56
-5
lines changed

2 files changed

+56
-5
lines changed

SwiftCompilerSources/Sources/Optimizer/FunctionPasses/CopyToBorrowOptimization.swift

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -124,10 +124,6 @@ private struct Uses {
124124
// E.g. the none-case of a switch_enum of an Optional.
125125
private(set) var nonDestroyingLiverangeExits: Stack<Instruction>
126126

127-
var allLifetimeEndingInstructions: [Instruction] {
128-
Array(destroys.lazy.map { $0 }) + Array(nonDestroyingLiverangeExits)
129-
}
130-
131127
private(set) var usersInDeadEndBlocks: Stack<Instruction>
132128

133129
init(_ context: FunctionPassContext) {
@@ -323,7 +319,16 @@ private func createEndBorrows(for beginBorrow: Value, atEndOf liverange: Instruc
323319
// destroy_value %2
324320
// destroy_value %3 // The final destroy. Here we need to create the `end_borrow`(s)
325321
//
326-
for endInst in collectedUses.allLifetimeEndingInstructions {
322+
323+
var allLifetimeEndingInstructions = InstructionWorklist(context)
324+
allLifetimeEndingInstructions.pushIfNotVisited(contentsOf: collectedUses.destroys.lazy.map { $0 })
325+
allLifetimeEndingInstructions.pushIfNotVisited(contentsOf: collectedUses.nonDestroyingLiverangeExits)
326+
327+
defer {
328+
allLifetimeEndingInstructions.deinitialize()
329+
}
330+
331+
while let endInst = allLifetimeEndingInstructions.pop() {
327332
if !liverange.contains(endInst) {
328333
let builder = Builder(before: endInst, context)
329334
builder.createEndBorrow(of: beginBorrow)

test/SILOptimizer/copy-to-borrow-optimization.sil

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2156,3 +2156,49 @@ bb0(%0 : $*MultiPayload):
21562156
return %2
21572157
}
21582158

2159+
// CHECK-LABEL: sil [ossa] @duplicate_lifetime_end1 :
2160+
// CHECK: load_borrow %0
2161+
// CHECK: } // end sil function 'duplicate_lifetime_end1'
2162+
sil [ossa] @duplicate_lifetime_end1 : $@convention(thin) (@in_guaranteed (C, Optional<C>)) -> () {
2163+
bb0(%0 : $*(C, Optional<C>)):
2164+
%1 = load [copy] %0
2165+
(%2, %3) = destructure_tuple %1
2166+
switch_enum %3, case #Optional.some!enumelt: bb1, case #Optional.none!enumelt: bb2
2167+
2168+
bb1(%4 : @owned $C):
2169+
destroy_value %2
2170+
destroy_value %4
2171+
br bb3
2172+
2173+
bb2:
2174+
debug_value %2
2175+
destroy_value %2
2176+
br bb3
2177+
2178+
bb3:
2179+
%r = tuple ()
2180+
return %r
2181+
}
2182+
2183+
// CHECK-LABEL: sil [ossa] @duplicate_lifetime_end2 :
2184+
// CHECK: load_borrow %0
2185+
// CHECK: } // end sil function 'duplicate_lifetime_end2'
2186+
sil [ossa] @duplicate_lifetime_end2 : $@convention(thin) (@in_guaranteed (C, Optional<C>)) -> () {
2187+
bb0(%0 : $*(C, Optional<C>)):
2188+
%1 = load [copy] %0
2189+
(%2, %3) = destructure_tuple %1
2190+
switch_enum %3, case #Optional.some!enumelt: bb1, case #Optional.none!enumelt: bb2
2191+
2192+
bb1(%4 : @owned $C):
2193+
destroy_value %2
2194+
destroy_value %4
2195+
br bb3
2196+
2197+
bb2:
2198+
destroy_value %2
2199+
br bb3
2200+
2201+
bb3:
2202+
%r = tuple ()
2203+
return %r
2204+
}

0 commit comments

Comments
 (0)