@@ -21,19 +21,23 @@ sil @owned_user : $@convention(thin) (@owned Builtin.NativeObject) -> ()
21
21
sil @get_owned_obj : $@convention(thin) () -> @owned Builtin.NativeObject
22
22
sil @unreachable_guaranteed_user : $@convention(thin) (@guaranteed Builtin.NativeObject) -> MyNever
23
23
sil @inout_user : $@convention(thin) (@inout FakeOptional<NativeObjectPair>) -> ()
24
+ sil @get_native_object : $@convention(thin) () -> @owned Builtin.NativeObject
24
25
25
26
struct NativeObjectPair {
26
27
var obj1 : Builtin.NativeObject
27
28
var obj2 : Builtin.NativeObject
28
29
}
29
30
31
+ sil @get_object_pair : $@convention(thin) () -> @owned NativeObjectPair
32
+
30
33
struct FakeOptionalNativeObjectPairPair {
31
34
var pair1 : FakeOptional<NativeObjectPair>
32
35
var pair2 : FakeOptional<NativeObjectPair>
33
36
}
34
37
sil @inout_user2 : $@convention(thin) (@inout FakeOptionalNativeObjectPairPair) -> ()
35
38
36
39
sil @get_nativeobject_pair : $@convention(thin) () -> @owned NativeObjectPair
40
+ sil @consume_nativeobject_pair : $@convention(thin) (@owned NativeObjectPair) -> ()
37
41
38
42
protocol MyFakeAnyObject : Klass {
39
43
func myFakeMethod()
@@ -2868,3 +2872,208 @@ bb3(%result : @owned $FakeOptional<Builtin.NativeObject>):
2868
2872
dealloc_stack %allocStack : $*Builtin.NativeObject
2869
2873
return %result : $FakeOptional<Builtin.NativeObject>
2870
2874
}
2875
+
2876
+ // CHECK-LABEL: sil [ossa] @simple_recursive_copy_case : $@convention(thin) () -> () {
2877
+ // CHECK-NOT: copy_value
2878
+ // CHECK: } // end sil function 'simple_recursive_copy_case'
2879
+ sil [ossa] @simple_recursive_copy_case : $@convention(thin) () -> () {
2880
+ bb0:
2881
+ %f = function_ref @get_object_pair : $@convention(thin) () -> @owned NativeObjectPair
2882
+ %pair = apply %f() : $@convention(thin) () -> @owned NativeObjectPair
2883
+ %1 = copy_value %pair : $NativeObjectPair
2884
+ %2 = begin_borrow %1 : $NativeObjectPair
2885
+ %3 = struct_extract %2 : $NativeObjectPair, #NativeObjectPair.obj1
2886
+ %gUserFun = function_ref @guaranteed_user : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
2887
+ apply %gUserFun(%3) : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
2888
+ end_borrow %2 : $NativeObjectPair
2889
+ destroy_value %1 : $NativeObjectPair
2890
+ destroy_value %pair : $NativeObjectPair
2891
+ %9999 = tuple()
2892
+ return %9999 : $()
2893
+ }
2894
+
2895
+ // CHECK-LABEL: sil [ossa] @simple_recursive_copy_case_2 : $@convention(thin) () -> () {
2896
+ // CHECK-NOT: copy_value
2897
+ // CHECK: } // end sil function 'simple_recursive_copy_case_2'
2898
+ sil [ossa] @simple_recursive_copy_case_2 : $@convention(thin) () -> () {
2899
+ bb0:
2900
+ %f = function_ref @get_object_pair : $@convention(thin) () -> @owned NativeObjectPair
2901
+ %pair = apply %f() : $@convention(thin) () -> @owned NativeObjectPair
2902
+ %1 = copy_value %pair : $NativeObjectPair
2903
+ %2 = begin_borrow %1 : $NativeObjectPair
2904
+ destroy_value %pair : $NativeObjectPair
2905
+ %3 = struct_extract %2 : $NativeObjectPair, #NativeObjectPair.obj1
2906
+ %gUserFun = function_ref @guaranteed_user : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
2907
+ apply %gUserFun(%3) : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
2908
+ end_borrow %2 : $NativeObjectPair
2909
+ destroy_value %1 : $NativeObjectPair
2910
+ %9999 = tuple()
2911
+ return %9999 : $()
2912
+ }
2913
+
2914
+ // We fail in this case since the lifetime of %pair ends too early and our
2915
+ // joined lifetime analysis is too simplistic to handle this case.
2916
+ //
2917
+ // CHECK-LABEL: sil [ossa] @simple_recursive_copy_case_3 : $@convention(thin) () -> () {
2918
+ // CHECK: copy_value
2919
+ // CHECK: } // end sil function 'simple_recursive_copy_case_3'
2920
+ sil [ossa] @simple_recursive_copy_case_3 : $@convention(thin) () -> () {
2921
+ bb0:
2922
+ %f = function_ref @get_object_pair : $@convention(thin) () -> @owned NativeObjectPair
2923
+ %pair = apply %f() : $@convention(thin) () -> @owned NativeObjectPair
2924
+ %1 = copy_value %pair : $NativeObjectPair
2925
+ %2 = begin_borrow %1 : $NativeObjectPair
2926
+ %3 = struct_extract %2 : $NativeObjectPair, #NativeObjectPair.obj1
2927
+ %gUserFun = function_ref @guaranteed_user : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
2928
+ apply %gUserFun(%3) : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
2929
+ end_borrow %2 : $NativeObjectPair
2930
+ %consumeFunc = function_ref @consume_nativeobject_pair : $@convention(thin) (@owned NativeObjectPair) -> ()
2931
+ apply %consumeFunc(%pair) : $@convention(thin) (@owned NativeObjectPair) -> ()
2932
+ cond_br undef, bb1, bb2
2933
+
2934
+ bb1:
2935
+ (%1a, %1b) = destructure_struct %1 : $NativeObjectPair
2936
+ %ownedUser = function_ref @owned_user : $@convention(thin) (@owned Builtin.NativeObject) -> ()
2937
+ apply %ownedUser(%1a) : $@convention(thin) (@owned Builtin.NativeObject) -> ()
2938
+ apply %ownedUser(%1b) : $@convention(thin) (@owned Builtin.NativeObject) -> ()
2939
+ br bb3
2940
+
2941
+ bb2:
2942
+ destroy_value %1 : $NativeObjectPair
2943
+ br bb3
2944
+
2945
+ bb3:
2946
+ %9999 = tuple()
2947
+ return %9999 : $()
2948
+ }
2949
+
2950
+ // This case fails due to the destructure of our parent object even though the
2951
+ // lifetimes line up. We don't support destructures here yet.
2952
+ //
2953
+ // TODO: Handle this!
2954
+ //
2955
+ // CHECK-LABEL: sil [ossa] @simple_recursive_copy_case_4 : $@convention(thin) () -> () {
2956
+ // CHECK: copy_value
2957
+ // CHECK: } // end sil function 'simple_recursive_copy_case_4'
2958
+ sil [ossa] @simple_recursive_copy_case_4 : $@convention(thin) () -> () {
2959
+ bb0:
2960
+ %f = function_ref @get_object_pair : $@convention(thin) () -> @owned NativeObjectPair
2961
+ %pair = apply %f() : $@convention(thin) () -> @owned NativeObjectPair
2962
+ %1 = copy_value %pair : $NativeObjectPair
2963
+ %2 = begin_borrow %1 : $NativeObjectPair
2964
+ %3 = struct_extract %2 : $NativeObjectPair, #NativeObjectPair.obj1
2965
+ %gUserFun = function_ref @guaranteed_user : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
2966
+ apply %gUserFun(%3) : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
2967
+ end_borrow %2 : $NativeObjectPair
2968
+ %consumeFunc = function_ref @consume_nativeobject_pair : $@convention(thin) (@owned NativeObjectPair) -> ()
2969
+ destroy_value %1 : $NativeObjectPair
2970
+ (%pair1, %pair2) = destructure_struct %pair : $NativeObjectPair
2971
+ %ownedUser = function_ref @owned_user : $@convention(thin) (@owned Builtin.NativeObject) -> ()
2972
+ apply %ownedUser(%pair1) : $@convention(thin) (@owned Builtin.NativeObject) -> ()
2973
+ apply %ownedUser(%pair2) : $@convention(thin) (@owned Builtin.NativeObject) -> ()
2974
+ %9999 = tuple()
2975
+ return %9999 : $()
2976
+ }
2977
+
2978
+ // This case fails due to the destructure of our parent object even though the
2979
+ // lifetimes line up. We don't support destructures here yet.
2980
+ //
2981
+ // TODO: Handle this!
2982
+ //
2983
+ // CHECK-LABEL: sil [ossa] @simple_recursive_copy_case_5 : $@convention(thin) () -> () {
2984
+ // CHECK: copy_value
2985
+ // CHECK: } // end sil function 'simple_recursive_copy_case_5'
2986
+ sil [ossa] @simple_recursive_copy_case_5 : $@convention(thin) () -> () {
2987
+ bb0:
2988
+ %f = function_ref @get_object_pair : $@convention(thin) () -> @owned NativeObjectPair
2989
+ %pair = apply %f() : $@convention(thin) () -> @owned NativeObjectPair
2990
+ %1 = copy_value %pair : $NativeObjectPair
2991
+ %2 = begin_borrow %1 : $NativeObjectPair
2992
+ %3 = struct_extract %2 : $NativeObjectPair, #NativeObjectPair.obj1
2993
+ %gUserFun = function_ref @guaranteed_user : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
2994
+ apply %gUserFun(%3) : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
2995
+ end_borrow %2 : $NativeObjectPair
2996
+ %consumeFunc = function_ref @consume_nativeobject_pair : $@convention(thin) (@owned NativeObjectPair) -> ()
2997
+ (%pair1, %pair2) = destructure_struct %pair : $NativeObjectPair
2998
+ %ownedUser = function_ref @owned_user : $@convention(thin) (@owned Builtin.NativeObject) -> ()
2999
+ destroy_value %1 : $NativeObjectPair
3000
+ apply %ownedUser(%pair1) : $@convention(thin) (@owned Builtin.NativeObject) -> ()
3001
+ apply %ownedUser(%pair2) : $@convention(thin) (@owned Builtin.NativeObject) -> ()
3002
+ %9999 = tuple()
3003
+ return %9999 : $()
3004
+ }
3005
+
3006
+ // Make sure we do not eliminate copies where only the destroy_value is outside
3007
+ // of the lifetime of the parent value, but a begin_borrow extends the lifetime
3008
+ // of the value.
3009
+ //
3010
+ // CHECK-LABEL: sil [ossa] @simple_recursive_copy_case_destroying_use_out_of_lifetime : $@convention(thin) () -> () {
3011
+ // CHECK: copy_value
3012
+ // CHECK: } // end sil function 'simple_recursive_copy_case_destroying_use_out_of_lifetime'
3013
+ sil [ossa] @simple_recursive_copy_case_destroying_use_out_of_lifetime : $@convention(thin) () -> () {
3014
+ bb0:
3015
+ %f = function_ref @get_object_pair : $@convention(thin) () -> @owned NativeObjectPair
3016
+ %pair = apply %f() : $@convention(thin) () -> @owned NativeObjectPair
3017
+ %pairBorrow = begin_borrow %pair : $NativeObjectPair
3018
+ %3 = struct_extract %pairBorrow : $NativeObjectPair, #NativeObjectPair.obj1
3019
+ %gUserFun = function_ref @guaranteed_user : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
3020
+ apply %gUserFun(%3) : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
3021
+ end_borrow %pairBorrow : $NativeObjectPair
3022
+ cond_br undef, bb1, bb2
3023
+
3024
+ bb1:
3025
+ %1 = copy_value %pair : $NativeObjectPair
3026
+ %2 = begin_borrow %1 : $NativeObjectPair
3027
+ destroy_value %pair : $NativeObjectPair
3028
+ %3a = struct_extract %2 : $NativeObjectPair, #NativeObjectPair.obj1
3029
+ apply %gUserFun(%3a) : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
3030
+ end_borrow %2 : $NativeObjectPair
3031
+ destroy_value %1 : $NativeObjectPair
3032
+ br bb3
3033
+
3034
+ bb2:
3035
+ destroy_value %pair : $NativeObjectPair
3036
+ br bb3
3037
+
3038
+ bb3:
3039
+ %9999 = tuple()
3040
+ return %9999 : $()
3041
+ }
3042
+
3043
+ // Second version of the test that consumes the pair in case we make the
3044
+ // lifetime joining smart enough to handle the original case.
3045
+ //
3046
+ // CHECK-LABEL: sil [ossa] @simple_recursive_copy_case_destroying_use_out_of_lifetime_2 : $@convention(thin) () -> () {
3047
+ // CHECK: copy_value
3048
+ // CHECK: } // end sil function 'simple_recursive_copy_case_destroying_use_out_of_lifetime_2'
3049
+ sil [ossa] @simple_recursive_copy_case_destroying_use_out_of_lifetime_2 : $@convention(thin) () -> () {
3050
+ bb0:
3051
+ %f = function_ref @get_object_pair : $@convention(thin) () -> @owned NativeObjectPair
3052
+ %pair = apply %f() : $@convention(thin) () -> @owned NativeObjectPair
3053
+ %pairBorrow = begin_borrow %pair : $NativeObjectPair
3054
+ %3 = struct_extract %pairBorrow : $NativeObjectPair, #NativeObjectPair.obj1
3055
+ %gUserFun = function_ref @guaranteed_user : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
3056
+ apply %gUserFun(%3) : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
3057
+ end_borrow %pairBorrow : $NativeObjectPair
3058
+ cond_br undef, bb1, bb2
3059
+
3060
+ bb1:
3061
+ %1 = copy_value %pair : $NativeObjectPair
3062
+ %2 = begin_borrow %1 : $NativeObjectPair
3063
+ destroy_value %pair : $NativeObjectPair
3064
+ %3a = struct_extract %2 : $NativeObjectPair, #NativeObjectPair.obj1
3065
+ apply %gUserFun(%3a) : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
3066
+ end_borrow %2 : $NativeObjectPair
3067
+ destroy_value %1 : $NativeObjectPair
3068
+ br bb3
3069
+
3070
+ bb2:
3071
+ %consumePair = function_ref @consume_nativeobject_pair : $@convention(thin) (@owned NativeObjectPair) -> ()
3072
+ apply %consumePair(%pair) : $@convention(thin) (@owned NativeObjectPair) -> ()
3073
+ br bb3
3074
+
3075
+ bb3:
3076
+ %9999 = tuple()
3077
+ return %9999 : $()
3078
+ }
3079
+
0 commit comments