Skip to content

Commit 0bec28f

Browse files
committed
Update borrowed from for guaranteed results of borrow accessors
1 parent 5c33459 commit 0bec28f

File tree

2 files changed

+60
-0
lines changed

2 files changed

+60
-0
lines changed

SwiftCompilerSources/Sources/SIL/Utilities/BorrowUtils.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,9 @@ public final class EnclosingValueIterator : IteratorProtocol {
535535
// Recurse through guaranteed forwarding non-phi instructions.
536536
let ops = forwardingInst.forwardedOperands
537537
worklist.pushIfNotVisited(contentsOf: ops.lazy.map { $0.value })
538+
} else if value.isGuaranteedApplyResult {
539+
let selfArgument = (value as! ApplyInst).arguments.last!
540+
worklist.pushIfNotVisited(selfArgument)
538541
} else {
539542
fatalError("cannot get borrow introducers for unknown guaranteed value")
540543
}
@@ -617,6 +620,19 @@ extension Value {
617620
}
618621
return self
619622
}
623+
624+
public var isGuaranteedApplyResult: Bool {
625+
guard let definingInstruction = self.definingInstruction else {
626+
return false
627+
}
628+
guard let apply = definingInstruction as? ApplyInst else {
629+
return false
630+
}
631+
guard apply.singleDirectResult != nil else {
632+
return false
633+
}
634+
return apply.functionConvention.results[0].convention == .guaranteed
635+
}
620636
}
621637

622638
extension Phi {

test/SILOptimizer/borrowed_from_updater.sil

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,3 +300,47 @@ bb2(%5 : @guaranteed $C):
300300
return %0 : $C
301301
}
302302

303+
class Klass {}
304+
305+
public struct Wrapper {
306+
@_hasStorage var _k: Klass { get set }
307+
var k: Klass
308+
}
309+
310+
public struct GenWrapper<T> {
311+
@_hasStorage var _prop: T { get set }
312+
public var prop: T
313+
}
314+
315+
// CHECK-LABEL: sil [ossa] @borrow_loadable_prop : $@convention(method) (@guaranteed Wrapper) -> @guaranteed Klass {
316+
sil [ossa] @borrow_loadable_prop : $@convention(method) (@guaranteed Wrapper) -> @guaranteed Klass {
317+
bb0(%0 : @guaranteed $Wrapper):
318+
%2 = struct_extract %0, #Wrapper._k
319+
return %2
320+
}
321+
322+
// CHECK-LABEL: sil [ossa] @test_borrow_accessor :
323+
// CHECK: bb3([[PHI:%.*]] : @guaranteed $Klass):
324+
// CHECK: [[B:%.*]] = borrowed [[PHI]] : $Klass from (%1 : $Wrapper)
325+
// CHECK-LABEL: } // end sil function 'test_borrow_accessor'
326+
sil [ossa] @test_borrow_accessor : $@convention(thin) (@owned Wrapper) -> () {
327+
bb0(%0 : @owned $Wrapper):
328+
%1 = begin_borrow %0
329+
%2 = function_ref @borrow_loadable_prop : $@convention(method) (@guaranteed Wrapper) -> @guaranteed Klass
330+
cond_br undef, bb1, bb2
331+
332+
bb1:
333+
%3 = apply %2(%1) : $@convention(method) (@guaranteed Wrapper) -> @guaranteed Klass
334+
br bb3(%3)
335+
336+
bb2:
337+
%5 = apply %2(%1) : $@convention(method) (@guaranteed Wrapper) -> @guaranteed Klass
338+
br bb3(%5)
339+
340+
bb3(%7 : @guaranteed $Klass):
341+
end_borrow %1
342+
destroy_value %0
343+
%t = tuple ()
344+
return %t
345+
}
346+

0 commit comments

Comments
 (0)