mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Compute, update and handle borrowed-from instruction in various utilities and passes. Also, used borrowed-from to simplify `gatherBorrowIntroducers` and `gatherEnclosingValues`. Replace those utilities by `Value.getBorrowIntroducers` and `Value.getEnclosingValues`, which return a lazily computed Sequence of borrowed/enclosing values.
251 lines
8.0 KiB
Plaintext
251 lines
8.0 KiB
Plaintext
// RUN: %target-sil-opt -loop-rotate -update-borrowed-from -looprotate-single-block-loop=true %s | %FileCheck %s
|
|
sil_stage canonical
|
|
|
|
import Builtin
|
|
import Swift
|
|
|
|
class Klass {
|
|
|
|
}
|
|
|
|
struct BoxStruct {
|
|
var guts: Klass
|
|
}
|
|
|
|
sil [ossa] @useKlass : $@convention(thin) (@guaranteed Klass) -> ()
|
|
|
|
sil [ossa] @klassIdentity : $@convention(thin) (@owned Klass) -> @owned Klass
|
|
|
|
sil [ossa] @increment : $@convention(thin) (Builtin.Int32) -> Builtin.Int32
|
|
|
|
// CHECK-LABEL: sil [ossa] @testLoopSimple :
|
|
// CHECK: bb0(%0 : $Int32, %1 : @owned $Klass):
|
|
// CHECK: cond_br {{.*}}, bb2, bb1
|
|
// CHECK: bb1:
|
|
// CHECK-LABEL: } // end sil function 'testLoopSimple'
|
|
sil [ossa] @testLoopSimple : $@convention(thin) (Int32, @owned Klass) -> (){
|
|
bb0(%0 : $Int32, %1: @owned $Klass):
|
|
%2 = struct_extract %0 : $Int32, #Int32._value
|
|
%one = integer_literal $Builtin.Int32, 1
|
|
br bb1(%2 : $Builtin.Int32, %1 : $Klass)
|
|
|
|
bb1(%3 : $Builtin.Int32, %4: @owned $Klass):
|
|
%f1 = function_ref @klassIdentity : $@convention(thin) (@owned Klass) -> @owned Klass
|
|
%c1 = apply %f1(%4) : $@convention(thin) (@owned Klass) -> @owned Klass
|
|
%f2 = function_ref @increment : $@convention(thin) (Builtin.Int32) -> Builtin.Int32
|
|
%c2 = apply %f2(%3) : $@convention(thin) (Builtin.Int32) -> Builtin.Int32
|
|
%5 = struct $Int32 (%c2 : $Builtin.Int32)
|
|
%6 = builtin "cmp_eq_Word"(%5 : $Int32, %one : $Builtin.Int32) : $Builtin.Int1
|
|
cond_br %6, bb3, bb2
|
|
|
|
bb2:
|
|
br bb1(%c2 : $Builtin.Int32, %c1: $Klass)
|
|
|
|
bb3:
|
|
destroy_value %c1 : $Klass
|
|
%res = tuple ()
|
|
return %res : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @testLoopCopy :
|
|
// CHECK: bb0(%0 : $Int32, %1 : @owned $Klass):
|
|
// CHECK: cond_br {{.*}}, bb2, bb1
|
|
// CHECK: bb1:
|
|
// CHECK-LABEL: } // end sil function 'testLoopCopy'
|
|
sil [ossa] @testLoopCopy : $@convention(thin) (Int32, @owned Klass) -> (){
|
|
bb0(%0 : $Int32, %1: @owned $Klass):
|
|
%2 = struct_extract %0 : $Int32, #Int32._value
|
|
%one = integer_literal $Builtin.Int32, 1
|
|
br bb1(%2 : $Builtin.Int32, %1 : $Klass)
|
|
|
|
bb1(%3 : $Builtin.Int32, %4: @owned $Klass):
|
|
%f1 = function_ref @klassIdentity : $@convention(thin) (@owned Klass) -> @owned Klass
|
|
%copy = copy_value %4 : $Klass
|
|
destroy_value %4 : $Klass
|
|
%c1 = apply %f1(%copy) : $@convention(thin) (@owned Klass) -> @owned Klass
|
|
%f2 = function_ref @increment : $@convention(thin) (Builtin.Int32) -> Builtin.Int32
|
|
%c2 = apply %f2(%3) : $@convention(thin) (Builtin.Int32) -> Builtin.Int32
|
|
%5 = struct $Int32 (%c2 : $Builtin.Int32)
|
|
%6 = builtin "cmp_eq_Word"(%5 : $Int32, %one : $Builtin.Int32) : $Builtin.Int1
|
|
cond_br %6, bb3, bb2
|
|
|
|
bb2:
|
|
br bb1(%c2 : $Builtin.Int32, %c1: $Klass)
|
|
|
|
bb3:
|
|
destroy_value %c1 : $Klass
|
|
%res = tuple ()
|
|
return %res : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @testLoopBorrow1 :
|
|
// CHECK: bb0(%0 : $Int32, %1 : @owned $Klass):
|
|
// CHECK: cond_br {{.*}}, bb2, bb1
|
|
// CHECK: bb1:
|
|
// CHECK-LABEL: } // end sil function 'testLoopBorrow1'
|
|
sil [ossa] @testLoopBorrow1 : $@convention(thin) (Int32, @owned Klass) -> (){
|
|
bb0(%0 : $Int32, %1: @owned $Klass):
|
|
%2 = struct_extract %0 : $Int32, #Int32._value
|
|
%one = integer_literal $Builtin.Int32, 1
|
|
br bb1(%2 : $Builtin.Int32, %1 : $Klass)
|
|
|
|
bb1(%3 : $Builtin.Int32, %4: @owned $Klass):
|
|
%f1 = function_ref @useKlass : $@convention(thin) (@guaranteed Klass) -> ()
|
|
%borrow = begin_borrow %4 : $Klass
|
|
%c1 = apply %f1(%borrow) : $@convention(thin) (@guaranteed Klass) -> ()
|
|
end_borrow %borrow : $Klass
|
|
%f2 = function_ref @increment : $@convention(thin) (Builtin.Int32) -> Builtin.Int32
|
|
%c2 = apply %f2(%3) : $@convention(thin) (Builtin.Int32) -> Builtin.Int32
|
|
%5 = struct $Int32 (%c2 : $Builtin.Int32)
|
|
%6 = builtin "cmp_eq_Word"(%5 : $Int32, %one : $Builtin.Int32) : $Builtin.Int1
|
|
cond_br %6, bb3, bb2
|
|
|
|
bb2:
|
|
br bb1(%c2 : $Builtin.Int32, %4 : $Klass)
|
|
|
|
bb3:
|
|
destroy_value %4 : $Klass
|
|
%res = tuple ()
|
|
return %res : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @testLoopBorrow2 :
|
|
// CHECK: bb0(%0 : $Int32, %1 : @owned $Klass):
|
|
// CHECK: cond_br {{.*}}, bb2, bb1
|
|
// CHECK: bb1:
|
|
// CHECK-LABEL: } // end sil function 'testLoopBorrow2'
|
|
sil [ossa] @testLoopBorrow2 : $@convention(thin) (Int32, @owned Klass) -> () {
|
|
bb0(%0 : $Int32, %1: @owned $Klass):
|
|
%2 = struct_extract %0 : $Int32, #Int32._value
|
|
%one = integer_literal $Builtin.Int32, 1
|
|
%borrow = begin_borrow %1 : $Klass
|
|
br bb1(%2 : $Builtin.Int32, %borrow : $Klass)
|
|
|
|
bb1(%3 : $Builtin.Int32, %reborrow : @guaranteed $Klass):
|
|
%f1 = function_ref @useKlass : $@convention(thin) (@guaranteed Klass) -> ()
|
|
%c1 = apply %f1(%reborrow) : $@convention(thin) (@guaranteed Klass) -> ()
|
|
%f2 = function_ref @increment : $@convention(thin) (Builtin.Int32) -> Builtin.Int32
|
|
%c2 = apply %f2(%3) : $@convention(thin) (Builtin.Int32) -> Builtin.Int32
|
|
%5 = struct $Int32 (%c2 : $Builtin.Int32)
|
|
%6 = builtin "cmp_eq_Word"(%5 : $Int32, %one : $Builtin.Int32) : $Builtin.Int1
|
|
cond_br %6, bb3, bb2
|
|
|
|
bb2:
|
|
br bb1(%c2 : $Builtin.Int32, %reborrow : $Klass)
|
|
|
|
bb3:
|
|
end_borrow %reborrow : $Klass
|
|
destroy_value %1 : $Klass
|
|
%res = tuple ()
|
|
return %res : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @testLoopBorrow3 :
|
|
// CHECK: bb0(%0 : $Int32, %1 : @owned $Klass):
|
|
// CHECK: cond_br {{.*}}, bb2, bb1
|
|
// CHECK: bb1:
|
|
// CHECK-LABEL: } // end sil function 'testLoopBorrow3'
|
|
sil [ossa] @testLoopBorrow3 : $@convention(thin) (Int32, @owned Klass) -> () {
|
|
bb0(%0 : $Int32, %1: @owned $Klass):
|
|
%2 = struct_extract %0 : $Int32, #Int32._value
|
|
%one = integer_literal $Builtin.Int32, 1
|
|
%borrow = begin_borrow %1 : $Klass
|
|
br bb1(%2 : $Builtin.Int32, %borrow : $Klass)
|
|
|
|
bb1(%3 : $Builtin.Int32, %reborrow1 : @guaranteed $Klass):
|
|
%f1 = function_ref @useKlass : $@convention(thin) (@guaranteed Klass) -> ()
|
|
%c1 = apply %f1(%reborrow1) : $@convention(thin) (@guaranteed Klass) -> ()
|
|
%f2 = function_ref @increment : $@convention(thin) (Builtin.Int32) -> Builtin.Int32
|
|
%c2 = apply %f2(%3) : $@convention(thin) (Builtin.Int32) -> Builtin.Int32
|
|
%5 = struct $Int32 (%c2 : $Builtin.Int32)
|
|
%6 = builtin "cmp_eq_Word"(%5 : $Int32, %one : $Builtin.Int32) : $Builtin.Int1
|
|
end_borrow %reborrow1 : $Klass
|
|
%reborrow2 = begin_borrow %1 : $Klass
|
|
cond_br %6, bb3, bb2
|
|
|
|
bb2:
|
|
br bb1(%c2 : $Builtin.Int32, %reborrow2 : $Klass)
|
|
|
|
bb3:
|
|
end_borrow %reborrow2 : $Klass
|
|
destroy_value %1 : $Klass
|
|
%res = tuple ()
|
|
return %res : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @guaranteed_phi_argument : $@convention(thin) (@owned Klass) -> () {
|
|
// CHECK: {{bb[0-9]+}}({{%[^,]+}} : @reborrow @guaranteed $Klass):
|
|
// CHECK-LABEL: } // end sil function 'guaranteed_phi_argument'
|
|
sil [ossa] @guaranteed_phi_argument : $@convention(thin) (@owned Klass) -> () {
|
|
entry(%instance : @owned $Klass):
|
|
%lifetime_1 = begin_borrow [lexical] %instance : $Klass
|
|
br loop_header(%lifetime_1 : $Klass)
|
|
|
|
loop_header(%lifetime_2 : @guaranteed $Klass):
|
|
cond_br undef, loop_back_1, loop_back_2_or_exit
|
|
|
|
loop_back_1:
|
|
br loop_header(%lifetime_2 : $Klass)
|
|
|
|
loop_back_2_or_exit:
|
|
cond_br undef, loop_back_2, exit
|
|
|
|
loop_back_2:
|
|
br loop_header(%lifetime_2 : $Klass)
|
|
|
|
exit:
|
|
end_borrow %lifetime_2 : $Klass
|
|
destroy_value %instance : $Klass
|
|
%retval = tuple ()
|
|
return %retval : $()
|
|
}
|
|
|
|
// A guaranteed value whose ownership has been forwarded must not be reborrowed.
|
|
//
|
|
// CHECK-LABEL: sil [ossa] @forwarded_borrow_cant_be_reborrowed : $@convention(thin) (@owned BoxStruct) -> () {
|
|
// CHECK: {{bb[0-9]+}}({{%[^,]+}} : @reborrow @guaranteed $BoxStruct, {{%[^,]+}} : @guaranteed $Klass):
|
|
// CHECK-LABEL: } // end sil function 'forwarded_borrow_cant_be_reborrowed'
|
|
sil [ossa] @forwarded_borrow_cant_be_reborrowed : $@convention(thin) (@owned BoxStruct) -> () {
|
|
bb0(%0 : @owned $BoxStruct):
|
|
br bb1
|
|
|
|
bb1:
|
|
%2 = integer_literal $Builtin.Int1, 0
|
|
cond_br %2, bb2, bb3
|
|
|
|
bb2:
|
|
br bb10
|
|
|
|
bb3:
|
|
%5 = begin_borrow %0 : $BoxStruct
|
|
%6 = struct_extract %5 : $BoxStruct, #BoxStruct.guts
|
|
%7 = integer_literal $Builtin.Int1, 0
|
|
cond_br %7, bb4, bb5
|
|
|
|
bb4:
|
|
unreachable
|
|
|
|
bb5:
|
|
%10 = begin_borrow %6 : $Klass
|
|
end_borrow %10 : $Klass
|
|
end_borrow %5 : $BoxStruct
|
|
br bb6
|
|
|
|
bb6:
|
|
br bb7
|
|
|
|
|
|
bb7:
|
|
%16 = integer_literal $Builtin.Int1, -1
|
|
cond_br %16, bb8, bb9
|
|
|
|
bb8:
|
|
br bb10
|
|
|
|
bb9:
|
|
br bb1
|
|
|
|
bb10:
|
|
unreachable
|
|
}
|