Skip to content

Commit d3e41e5

Browse files
committed
Update SwiftCompilerSources' OwnershipLiveness utility for borrow accessors
It uses a check on conformance to ForwardInstruction for walking down guaranteed forwarding uses. Since apply of borrow accessors cannot be represented as ForwardingInstruction, handle them separately. Representing apply of borrow accessors for consistent handling in the optimizer is TBD.
1 parent 11097c4 commit d3e41e5

File tree

3 files changed

+105
-1
lines changed

3 files changed

+105
-1
lines changed

SwiftCompilerSources/Sources/Optimizer/Utilities/OwnershipLiveness.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -806,6 +806,10 @@ extension InteriorUseWalker {
806806
if let inst = operand.instruction as? ForwardingInstruction {
807807
return inst.forwardedResults.walk { walkDownUses(of: $0) }
808808
}
809+
// TODO: Represent apply of borrow accessors as ForwardingOperation and use that over ForwardingInstruction
810+
if let apply = operand.instruction as? FullApplySite, apply.hasGuaranteedResult {
811+
return walkDownUses(of: apply.singleDirectResult!)
812+
}
809813
// TODO: verify that ForwardInstruction handles all .forward operand ownership and assert that only phis can be
810814
// reached: assert(Phi(using: operand) != nil)
811815
return .continueWalk

SwiftCompilerSources/Sources/SIL/ApplySite.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,14 @@ extension ApplySite {
299299
public func calleeArgumentIndex(of operand: Operand) -> Int? {
300300
operandConventions.calleeArgumentIndex(of: operand)
301301
}
302+
303+
public var hasGuaranteedResult: Bool {
304+
functionConvention.hasGuaranteedResult
305+
}
306+
307+
public var hasGuaranteedAddressResult: Bool {
308+
functionConvention.hasGuaranteedAddressResult
309+
}
302310
}
303311

304312
extension ApplySite {

test/SILOptimizer/ownership_liveness_unit.sil

Lines changed: 93 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ struct NE: ~Escapable {
4545

4646
sil [ossa] @useCAddress : $@convention(thin) (@inout_aliasable C) -> ()
4747

48-
4948
// =============================================================================
5049
// LinearLiveness
5150
// =============================================================================
@@ -2139,3 +2138,96 @@ exit:
21392138
%retval = tuple ()
21402139
return %retval : $()
21412140
}
2141+
2142+
class Klass {
2143+
}
2144+
2145+
public struct Wrapper {
2146+
var _k: Klass
2147+
var i: Int
2148+
}
2149+
2150+
sil @get_wrapper : $@convention(thin) () -> @owned Wrapper
2151+
sil @use_klass : $@convention(thin) (@guaranteed Klass) -> ()
2152+
2153+
sil [ossa] @borrow_loadable_prop : $@convention(method) (@guaranteed Wrapper) -> @guaranteed Klass {
2154+
bb0(%0 : @guaranteed $Wrapper):
2155+
%2 = struct_extract %0, #Wrapper._k
2156+
return %2
2157+
}
2158+
2159+
// CHECK: begin running test 1 of 2 on test_borrow_accessor1: interior_liveness with: %1
2160+
// CHECK: sil [ossa] @test_borrow_accessor1 : $@convention(thin) (@owned Wrapper) -> () {
2161+
// CHECK: bb0(%0 : @owned $Wrapper):
2162+
// CHECK: %1 = copy_value %0 : $Wrapper
2163+
// CHECK: %2 = begin_borrow %1 : $Wrapper
2164+
// CHECK: %3 = function_ref @borrow_loadable_prop : $@convention(method) (@guaranteed Wrapper) -> @guaranteed Klass
2165+
// CHECK: %4 = apply %3(%2) : $@convention(method) (@guaranteed Wrapper) -> @guaranteed Klass
2166+
// CHECK: %5 = function_ref @use_klass : $@convention(thin) (@guaranteed Klass) -> ()
2167+
// CHECK: %6 = apply %5(%4) : $@convention(thin) (@guaranteed Klass) -> ()
2168+
// CHECK: unreachable
2169+
// CHECK: }
2170+
// CHECK: Interior liveness: %2 = begin_borrow %1 : $Wrapper
2171+
// CHECK: bb0: LiveWithin
2172+
// CHECK: regular user: %4 = apply %3(%2) : $@convention(method) (@guaranteed Wrapper) -> @guaranteed Klass
2173+
// CHECK: regular user: %6 = apply %5(%4) : $@convention(thin) (@guaranteed Klass) -> ()
2174+
// CHECK: Complete liveness
2175+
// CHECK: last user: %6 = apply %5(%4) : $@convention(thin) (@guaranteed Klass) -> ()
2176+
// CHECK: end running test 1 of 2 on test_borrow_accessor1: interior_liveness with: %1
2177+
sil [ossa] @test_borrow_accessor1 : $@convention(thin) (@owned Wrapper) -> () {
2178+
bb0(%0 : @owned $Wrapper):
2179+
specify_test "interior_liveness %1"
2180+
specify_test "interior_liveness_swift %1"
2181+
%copy = copy_value %0
2182+
%1 = begin_borrow %copy
2183+
%2 = function_ref @borrow_loadable_prop : $@convention(method) (@guaranteed Wrapper) -> @guaranteed Klass
2184+
%3 = apply %2(%1) : $@convention(method) (@guaranteed Wrapper) -> @guaranteed Klass
2185+
%4 = function_ref @use_klass : $@convention(thin) (@guaranteed Klass) -> ()
2186+
%5 = apply %4(%3) : $@convention(thin) (@guaranteed Klass) -> ()
2187+
unreachable
2188+
}
2189+
2190+
// CHECK: begin running test 1 of 2 on test_borrow_accessor2: interior_liveness with: %3
2191+
// CHECK: sil [ossa] @test_borrow_accessor2 : $@convention(thin) () -> () {
2192+
// CHECK: bb0:
2193+
// CHECK: %0 = function_ref @get_wrapper : $@convention(thin) () -> @owned Wrapper
2194+
// CHECK: %1 = apply %0() : $@convention(thin) () -> @owned Wrapper
2195+
// CHECK: %2 = begin_borrow %1 : $Wrapper
2196+
// CHECK: %3 = function_ref @borrow_loadable_prop : $@convention(method) (@guaranteed Wrapper) -> @guaranteed Klass
2197+
// CHECK: %4 = apply %3(%2) : $@convention(method) (@guaranteed Wrapper) -> @guaranteed Klass
2198+
// CHECK: %5 = copy_value %4 : $Klass
2199+
// CHECK: %6 = function_ref @use_klass : $@convention(thin) (@guaranteed Klass) -> ()
2200+
// CHECK: %7 = apply %6(%5) : $@convention(thin) (@guaranteed Klass) -> ()
2201+
// CHECK: unreachable
2202+
// CHECK: }
2203+
// CHECK: Interior liveness: %2 = begin_borrow %1 : $Wrapper
2204+
// CHECK: bb0: LiveWithin
2205+
// CHECK: regular user: %4 = apply %3(%2) : $@convention(method) (@guaranteed Wrapper) -> @guaranteed Klass
2206+
// CHECK: regular user: %5 = copy_value %4 : $Klass
2207+
// CHECK: Complete liveness
2208+
// CHECK: last user: %5 = copy_value %4 : $Klass
2209+
// CHECK: end running test 1 of 2 on test_borrow_accessor2: interior_liveness with: %3
2210+
// CHECK: begin running test 2 of 2 on test_borrow_accessor2: interior_liveness_swift with: %3
2211+
// CHECK: Interior liveness: %2 = begin_borrow %1 : $Wrapper
2212+
// CHECK: begin: %2 = begin_borrow %1 : $Wrapper
2213+
// CHECK: ends: %5 = copy_value %4 : $Klass
2214+
// CHECK: exits:
2215+
// CHECK: interiors: %4 = apply %3(%2) : $@convention(method) (@guaranteed Wrapper) -> @guaranteed Klass
2216+
// CHECK: last user: %5 = copy_value %4 : $Klass
2217+
// CHECK: end running test 2 of 2 on test_borrow_accessor2: interior_liveness_swift with: %3
2218+
2219+
sil [ossa] @test_borrow_accessor2 : $@convention(thin) () -> () {
2220+
bb0:
2221+
specify_test "interior_liveness %3"
2222+
specify_test "interior_liveness_swift %3"
2223+
%1 = function_ref @get_wrapper : $@convention(thin) () -> @owned Wrapper
2224+
%2 = apply %1() : $@convention(thin) () -> @owned Wrapper
2225+
%3 = begin_borrow %2
2226+
%4 = function_ref @borrow_loadable_prop : $@convention(method) (@guaranteed Wrapper) -> @guaranteed Klass
2227+
%5 = apply %4(%3) : $@convention(method) (@guaranteed Wrapper) -> @guaranteed Klass
2228+
%copy = copy_value %5
2229+
%6 = function_ref @use_klass : $@convention(thin) (@guaranteed Klass) -> ()
2230+
%7 = apply %6(%copy) : $@convention(thin) (@guaranteed Klass) -> ()
2231+
unreachable
2232+
}
2233+

0 commit comments

Comments
 (0)