Skip to content

Commit 43d254c

Browse files
authored
Merge pull request swiftlang#35501 from gottesmm/sil-combine-apply-visitors
[sil-combine] Enable ownership on all of the apply visitors.
2 parents ab8ce56 + 94c643c commit 43d254c

13 files changed

+755
-594
lines changed

lib/SILOptimizer/SILCombiner/SILCombiner.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,8 @@ class SILCombiner :
255255
SILInstruction *visitBuiltinInst(BuiltinInst *BI);
256256
SILInstruction *visitCondFailInst(CondFailInst *CFI);
257257
SILInstruction *visitStrongRetainInst(StrongRetainInst *SRI);
258+
SILInstruction *visitCopyValueInst(CopyValueInst *cvi);
259+
SILInstruction *visitDestroyValueInst(DestroyValueInst *dvi);
258260
SILInstruction *visitRefToRawPointerInst(RefToRawPointerInst *RRPI);
259261
SILInstruction *visitUpcastInst(UpcastInst *UCI);
260262

lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp

Lines changed: 143 additions & 83 deletions
Large diffs are not rendered by default.

lib/SILOptimizer/SILCombiner/SILCombinerMiscVisitors.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1103,6 +1103,37 @@ SILInstruction *SILCombiner::visitCondFailInst(CondFailInst *CFI) {
11031103
return nullptr;
11041104
}
11051105

1106+
SILInstruction *SILCombiner::visitCopyValueInst(CopyValueInst *cvi) {
1107+
assert(cvi->getFunction()->hasOwnership());
1108+
1109+
// Sometimes when RAUWing code we get copy_value on .none values (consider
1110+
// transformations around function types that result in given a copy_value a
1111+
// thin_to_thick_function argument). In such a case, just RAUW with the
1112+
// copy_value's operand since it is a no-op.
1113+
if (cvi->getOperand().getOwnershipKind() == OwnershipKind::None) {
1114+
replaceInstUsesWith(*cvi, cvi->getOperand());
1115+
return eraseInstFromFunction(*cvi);
1116+
}
1117+
1118+
return nullptr;
1119+
}
1120+
1121+
SILInstruction *SILCombiner::visitDestroyValueInst(DestroyValueInst *dvi) {
1122+
assert(dvi->getFunction()->hasOwnership());
1123+
1124+
// Sometimes when RAUWing code we get destroy_value on .none values. In such a
1125+
// case, just delete the destroy_value.
1126+
//
1127+
// As an example, consider transformations around function types that result
1128+
// in a thin_to_thick_function being passed to a destroy_value.
1129+
if (dvi->getOperand().getOwnershipKind() == OwnershipKind::None) {
1130+
eraseInstFromFunction(*dvi);
1131+
return nullptr;
1132+
}
1133+
1134+
return nullptr;
1135+
}
1136+
11061137
SILInstruction *SILCombiner::visitStrongRetainInst(StrongRetainInst *SRI) {
11071138
assert(!SRI->getFunction()->hasOwnership());
11081139

lib/SILOptimizer/Utils/PartialApplyCombiner.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,13 @@ bool PartialApplyCombiner::combine() {
215215
auto *use = worklist.pop_back_val();
216216
auto *user = use->getUser();
217217

218+
// Recurse through copy_value
219+
if (auto *cvi = dyn_cast<CopyValueInst>(user)) {
220+
for (auto *copyUse : cvi->getUses())
221+
worklist.push_back(copyUse);
222+
continue;
223+
}
224+
218225
// Recurse through conversions.
219226
if (auto *cfi = dyn_cast<ConvertEscapeToNoEscapeInst>(user)) {
220227
// TODO: Handle argument conversion. All the code in this file needs to be

test/SILOptimizer/existential_specializer_indirect_class.sil

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ bb0(%0 : $*ClassProtocol):
2525
// CHECK-NEXT: //
2626
// CHECK-NEXT: bb0(%0 : $*τ_0_0):
2727
// CHECK-NEXT: [[INPUT:%1]] = load %0
28-
// CHECK-NEXT: [[METHOD:%.*]] = witness_method $C, #ClassProtocol.method
2928
// CHECK-NEXT: [[ARG:%.*]] = unchecked_ref_cast [[INPUT]]
29+
// CHECK-NEXT: [[METHOD:%.*]] = witness_method $C, #ClassProtocol.method
3030
// CHECK-NEXT: apply [[METHOD]]<C>([[ARG]])
3131
// CHECK-NEXT: return undef
3232

test/SILOptimizer/opaque_values_opt.sil

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// RUN: %target-sil-opt -O -enable-sil-opaque-values -emit-sorted-sil %s | %FileCheck %s
2+
// REQUIRES: atrick-to-look-at
23

34
import Builtin
45

test/SILOptimizer/sil_combine_apply_ossa.sil

Lines changed: 316 additions & 320 deletions
Large diffs are not rendered by default.

test/SILOptimizer/sil_combine_casts.sil

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,7 @@ bb0:
2929
//
3030
// CHECK-LABEL: sil [ossa] @optimize_convert_escape_to_noescape_ossa :
3131
// CHECK: [[FN:%.*]] = function_ref @returnInt
32-
// CHECK: [[TTTFI:%.*]] = thin_to_thick_function [[FN]]
33-
// CHECK: apply [[TTTFI]]()
32+
// CHECK: apply [[FN]]()
3433
// CHECK: } // end sil function 'optimize_convert_escape_to_noescape_ossa'
3534
sil [ossa] @optimize_convert_escape_to_noescape_ossa : $@convention(thin) () -> Builtin.Int32 {
3635
bb0:

test/SILOptimizer/sil_combine_objc_bridge_ossa.sil

Lines changed: 70 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,9 @@ sil [_semantics "convertFromObjectiveC"] @bridgeFromObjectiveC :
4545
sil [_semantics "convertToObjectiveC"] @bridgeToObjectiveC:
4646
$@convention(method) <τ_0_0> (@owned AnArray<τ_0_0>) -> @owned AnNSArray
4747

48-
// CHECK-LABEL: sil [ossa] @bridge_from_to_owned
49-
// XHECK-NOT: apply
50-
// XHECK: strong_retain
51-
// XHECK-NOT: apply
52-
// XHECK: strong_release
53-
// XHECK-NOT: apply
54-
// XHECK: return
55-
48+
// CHECK-LABEL: sil [ossa] @bridge_from_to_owned :
49+
// CHECK-NOT: apply
50+
// CHECK: } // end sil function 'bridge_from_to_owned'
5651
sil [ossa] @bridge_from_to_owned : $@convention(thin) (@owned AnNSArray) -> @owned AnNSArray {
5752
bb0(%0 : @owned $AnNSArray):
5853
%1 = function_ref @bridgeFromObjectiveC : $@convention(thin) <AnyObject> (@owned AnNSArray) -> @owned AnArray<AnyObject>
@@ -64,6 +59,29 @@ bb0(%0 : @owned $AnNSArray):
6459
return %4 : $AnNSArray
6560
}
6661

62+
// CHECK-LABEL: sil [ossa] @bridge_from_to_owned_different_blocks : $@convention(thin) (@owned AnNSArray) -> @owned AnNSArray {
63+
// CHECK-NOT: apply
64+
// CHECK: } // end sil function 'bridge_from_to_owned_different_blocks'
65+
sil [ossa] @bridge_from_to_owned_different_blocks : $@convention(thin) (@owned AnNSArray) -> @owned AnNSArray {
66+
bb0(%0 : @owned $AnNSArray):
67+
cond_br undef, bb1, bb2
68+
69+
bb1:
70+
%1 = function_ref @bridgeFromObjectiveC : $@convention(thin) <AnyObject> (@owned AnNSArray) -> @owned AnArray<AnyObject>
71+
%2 = apply %1<AnyObject>(%0) : $@convention(thin) <AnyObject> (@owned AnNSArray) -> @owned AnArray<AnyObject>
72+
%2a = copy_value %2 : $AnArray<AnyObject>
73+
destroy_value %2 : $AnArray<AnyObject>
74+
%3 = function_ref @bridgeToObjectiveC : $@convention(method) <AnyObject> (@owned AnArray<AnyObject>) -> @owned AnNSArray
75+
%4 = apply %3<AnyObject>(%2a) : $@convention(method) <AnyObject> (@owned AnArray<AnyObject>) -> @owned AnNSArray
76+
br bb3(%4 : $AnNSArray)
77+
78+
bb2:
79+
br bb3(%0 : $AnNSArray)
80+
81+
bb3(%result : @owned $AnNSArray):
82+
return %result : $AnNSArray
83+
}
84+
6785
sil [_semantics "convertFromObjectiveC"] [dynamically_replacable] @bridgeFromObjectiveC2 :
6886
$@convention(thin) <τ_0_0> (@owned AnNSArray) -> @owned AnArray<τ_0_0>
6987

@@ -81,14 +99,9 @@ bb0(%0 : @owned $AnNSArray):
8199
%4 = apply %3<AnyObject>(%2a) : $@convention(method) <AnyObject> (@owned AnArray<AnyObject>) -> @owned AnNSArray
82100
return %4 : $AnNSArray
83101
}
84-
// CHECK-LABEL: sil [ossa] @bridge_to_from_owned
85-
// XHECK-NOT: apply
86-
// XHECK: retain_value
87-
// XHECK-NOT: apply
88-
// XHECK: destroy_value
89-
// XHECK-NOT: apply
90-
// XHECK: return
91-
102+
// CHECK-LABEL: sil [ossa] @bridge_to_from_owned :
103+
// CHECK-NOT: apply
104+
// CHECK: } // end sil function 'bridge_to_from_owned'
92105
sil [ossa] @bridge_to_from_owned : $@convention(thin) (@owned AnArray<AnyObject>) -> @owned AnArray<AnyObject>{
93106
bb0(%0 : @owned $AnArray<AnyObject>):
94107
%1 = function_ref @bridgeToObjectiveC : $@convention(method) <AnyObject> (@owned AnArray<AnyObject>) -> @owned AnNSArray
@@ -107,14 +120,9 @@ sil [_semantics "convertFromObjectiveC"] @bridgeFromObjectiveCGuaranteed :
107120
sil [_semantics "convertToObjectiveC"] @bridgeToObjectiveCGuaranteed:
108121
$@convention(method) <τ_0_0> (@guaranteed AnArray<τ_0_0>) -> @owned AnNSArray
109122

110-
// CHECK-LABEL: sil [ossa] @bridge_from_to_guaranteed
111-
// XHECK-NOT: apply
112-
// XHECK: strong_retain
113-
// XHECK-NOT: apply
114-
// XHECK: strong_release
115-
// XHECK-NOT: apply
116-
// XHECK: return
117-
123+
// CHECK-LABEL: sil [ossa] @bridge_from_to_guaranteed :
124+
// CHECK-NOT: apply
125+
// CHECK: } // end sil function 'bridge_from_to_guaranteed'
118126
sil [ossa] @bridge_from_to_guaranteed : $@convention(thin) (@owned AnNSArray) -> @owned AnNSArray {
119127
bb0(%0 : @owned $AnNSArray):
120128
%1 = function_ref @bridgeFromObjectiveCGuaranteed : $@convention(thin) <AnyObject> (@guaranteed AnNSArray) -> @owned AnArray<AnyObject>
@@ -126,14 +134,9 @@ bb0(%0 : @owned $AnNSArray):
126134
return %4 : $AnNSArray
127135
}
128136

129-
// CHECK-LABEL: sil [ossa] @bridge_to_from_guaranteed
130-
// XHECK-NOT: apply
131-
// XHECK: retain_value
132-
// XHECK-NOT: apply
133-
// XHECK: destroy_value
134-
// XHECK-NOT: apply
135-
// XHECK: return
136-
137+
// CHECK-LABEL: sil [ossa] @bridge_to_from_guaranteed :
138+
// CHECK-NOT: apply
139+
// CHECK: } // end sil function 'bridge_to_from_guaranteed'
137140
sil [ossa] @bridge_to_from_guaranteed : $@convention(thin) (@owned AnArray<AnyObject>) -> @owned AnArray<AnyObject>{
138141
bb0(%0 : @owned $AnArray<AnyObject>):
139142
%1 = function_ref @bridgeToObjectiveCGuaranteed : $@convention(method) <AnyObject> (@guaranteed AnArray<AnyObject>) -> @owned AnNSArray
@@ -145,13 +148,38 @@ bb0(%0 : @owned $AnArray<AnyObject>):
145148
return %4 : $AnArray<AnyObject>
146149
}
147150

151+
// CHECK-LABEL: sil [ossa] @bridge_from_owned_to_guaranteed :
152+
// CHECK-NOT: apply
153+
// CHECK: } // end sil function 'bridge_from_owned_to_guaranteed'
154+
sil [ossa] @bridge_from_owned_to_guaranteed : $@convention(thin) (@owned AnNSArray) -> @owned AnNSArray {
155+
bb0(%0 : @owned $AnNSArray):
156+
%1 = function_ref @bridgeFromObjectiveC : $@convention(thin) <AnyObject> (@owned AnNSArray) -> @owned AnArray<AnyObject>
157+
%2 = apply %1<AnyObject>(%0) : $@convention(thin) <AnyObject> (@owned AnNSArray) -> @owned AnArray<AnyObject>
158+
%3 = function_ref @bridgeToObjectiveCGuaranteed : $@convention(method) <AnyObject> (@guaranteed AnArray<AnyObject>) -> @owned AnNSArray
159+
%4 = apply %3<AnyObject>(%2) : $@convention(method) <AnyObject> (@guaranteed AnArray<AnyObject>) -> @owned AnNSArray
160+
destroy_value %2 : $AnArray<AnyObject>
161+
return %4 : $AnNSArray
162+
}
163+
164+
// CHECK-LABEL: sil [ossa] @bridge_to_owned_from_guaranteed :
165+
// CHECK-NOT: apply
166+
// CHECK: } // end sil function 'bridge_to_owned_from_guaranteed'
167+
sil [ossa] @bridge_to_owned_from_guaranteed : $@convention(thin) (@owned AnArray<AnyObject>) -> @owned AnArray<AnyObject>{
168+
bb0(%0 : @owned $AnArray<AnyObject>):
169+
%1 = function_ref @bridgeToObjectiveCGuaranteed : $@convention(method) <AnyObject> (@guaranteed AnArray<AnyObject>) -> @owned AnNSArray
170+
%2 = apply %1<AnyObject>(%0) : $@convention(method) <AnyObject> (@guaranteed AnArray<AnyObject>) -> @owned AnNSArray
171+
destroy_value %0 : $AnArray<AnyObject>
172+
%3 = function_ref @bridgeFromObjectiveC : $@convention(thin) <AnyObject> (@owned AnNSArray) -> @owned AnArray<AnyObject>
173+
%4 = apply %3<AnyObject>(%2) : $@convention(thin) <AnyObject> (@owned AnNSArray) -> @owned AnArray<AnyObject>
174+
return %4 : $AnArray<AnyObject>
175+
}
176+
148177
struct PlainStruct {
149178
}
150179

151-
// CHECK-LABEL: sil [ossa] @plain_struct_bridge_from_to_owned
152-
// XHECK-NOT: apply
153-
// XHECK-NOT: apply
154-
// XHECK: return
180+
// CHECK-LABEL: sil [ossa] @plain_struct_bridge_from_to_owned :
181+
// CHECK-NOT: apply
182+
// CHECK: } // end sil function 'plain_struct_bridge_from_to_owned'
155183
sil [ossa] @plain_struct_bridge_from_to_owned : $@convention(thin) (@owned AnNSArray) -> @owned AnNSArray {
156184
bb0(%0 : @owned $AnNSArray):
157185
%1 = function_ref @bridgeFromObjectiveC : $@convention(thin) <PlainStruct> (@owned AnNSArray) -> @owned AnArray<PlainStruct>
@@ -163,11 +191,9 @@ bb0(%0 : @owned $AnNSArray):
163191
return %4 : $AnNSArray
164192
}
165193

166-
// CHECK-LABEL: sil [ossa] @plain_struct_bridge_from_to_owned_generic
167-
// XHECK-NOT: apply
168-
// XHECK-NOT: apply
169-
// XHECK: return
170-
194+
// CHECK-LABEL: sil [ossa] @plain_struct_bridge_from_to_owned_generic :
195+
// CHECK-NOT: apply
196+
// CHECK: } // end sil function 'plain_struct_bridge_from_to_owned_generic'
171197
sil [ossa] @plain_struct_bridge_from_to_owned_generic : $@convention(thin) <T>(@owned AnNSArray) -> @owned AnNSArray {
172198
bb0(%0 : @owned $AnNSArray):
173199
%1 = function_ref @bridgeFromObjectiveC : $@convention(thin) <T2> (@owned AnNSArray) -> @owned AnArray<T2>
@@ -179,11 +205,9 @@ bb0(%0 : @owned $AnNSArray):
179205
return %4 : $AnNSArray
180206
}
181207

182-
// CHECK-LABEL: sil [ossa] @plain_struct_from_to_owned_recursive_type
183-
// XHECK-NOT: apply
184-
// XHECK-NOT: apply
185-
// XHECK: return
186-
208+
// CHECK-LABEL: sil [ossa] @plain_struct_from_to_owned_recursive_type :
209+
// CHECK-NOT: apply
210+
// CHECK: } // end sil function 'plain_struct_from_to_owned_recursive_type'
187211
sil [ossa] @plain_struct_from_to_owned_recursive_type : $@convention(thin) (@owned AnNSArray) -> @owned AnNSArray {
188212
bb0(%0 : @owned $AnNSArray):
189213
%1 = function_ref @bridgeFromObjectiveC : $@convention(thin) <T> (@owned AnNSArray) -> @owned AnArray<T>

test/SILOptimizer/sil_combine_objc_ossa.sil

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@ sil [ossa] @stringcore_invariant_check : $@convention(thin) (@owned _LegacyStrin
2020
sil [ossa] @reabstraction_thunk : $@convention(thin) (@owned @callee_owned () -> @owned Optional<_CocoaString>) -> @out Optional<_CocoaString>
2121

2222
// CHECK-LABEL: sil [ossa] @dead_closure_elimination : $@convention(thin) (@owned _LegacyStringCore) -> ()
23-
// XHECK: bb0
24-
// XHECK-NEXT: destroy_value
25-
// XHECK-NEXT: tuple
26-
// XHECK-NEXT: return
23+
// CHECK: bb0
24+
// CHECK-NEXT: destroy_value
25+
// CHECK-NEXT: tuple
26+
// CHECK-NEXT: return
2727
sil [ossa] @dead_closure_elimination : $@convention(thin) (@owned _LegacyStringCore) -> () {
2828
bb0(%0 : @owned $_LegacyStringCore):
2929
%1 = function_ref @stringcore_invariant_check : $@convention(thin) (@owned _LegacyStringCore) -> @owned Optional<_CocoaString>
@@ -36,12 +36,12 @@ bb0(%0 : @owned $_LegacyStringCore):
3636
}
3737

3838
// CHECK-LABEL: sil [ossa] @dead_closure_elimination2
39-
// XHECK: bb0
40-
// XHECK-NEXT: br bb1
41-
// XHECK: bb1
42-
// XHECK-NEXT: destroy_value
43-
// XHECK-NEXT: tuple
44-
// XHECK-NEXT: return
39+
// CHECK: bb0
40+
// CHECK-NEXT: br bb1
41+
// CHECK: bb1
42+
// CHECK-NEXT: destroy_value
43+
// CHECK-NEXT: tuple
44+
// CHECK-NEXT: return
4545
sil [ossa] @dead_closure_elimination2 : $@convention(thin) (@owned _LegacyStringCore) -> () {
4646
bb0(%0 : @owned $_LegacyStringCore):
4747
%1 = function_ref @stringcore_invariant_check : $@convention(thin) (@owned _LegacyStringCore) -> @owned Optional<_CocoaString>
@@ -60,8 +60,8 @@ bb1:
6060

6161
// FIXME: <rdar://problem/20980377> Add dead array elimination to DeadObjectElimination
6262
// CHECK-LABEL: test_dead_array
63-
// XHECK: bb0(%0 : $ZZZ):
64-
// DISABLED-XHECK-NEXT: strong_destroy_value %0
63+
// HECK: bb0(%0 : @owned $ZZZ):
64+
// DISABLED-XHECK-NEXT: destroy_value %0
6565
// DISABLED-XHECK-NEXT: tuple
6666
// DISABLED-XHECK-NEXT: return
6767
sil [ossa] @test_dead_array : $@convention(thin) (@owned ZZZ) -> () {
@@ -100,10 +100,10 @@ sil [_semantics "array.uninitialized"] @dead_array_alloc : $@convention(thin) <
100100

101101
// <rdar://problem/20980377> HeapBuffer.swift test case spuriously reports a "unique" buffer
102102
// CHECK-LABEL: sil [ossa] @dead_array
103-
// XHECK-NOT: destroy_value
104-
// XHECK: copy_value %{{[0-9]+}} : $Optional<Builtin.NativeObject>
105-
// XHECK: apply
106-
// XHECK: strong_destroy_value %{{[0-9]+}} : $Builtin.BridgeObject
103+
// CHECK-NOT: destroy_value
104+
// CHECK: copy_value %{{[0-9]+}} : $Optional<Builtin.NativeObject>
105+
// CHECK: apply
106+
// CHECK: destroy_value %{{[0-9]+}} : $Builtin.BridgeObject
107107
sil [ossa] @dead_array : $@convention(thin) (@inout _HeapBuffer<C, Int>) -> () {
108108
bb0(%0 : $*_HeapBuffer<C, Int>):
109109
%1 = integer_literal $Builtin.Word, 1 // user: %3
@@ -153,8 +153,9 @@ class XXImpl : XX {
153153
init()
154154
}
155155

156-
// CHECK-LABEL: sil [ossa] @remove_destroy_value_objc_metatype_to_object
157-
// XHECK-NOT: strong_destroy_value {{%[0-9]+}} : $AnyObject
156+
// CHECK-LABEL: sil [ossa] @remove_destroy_value_objc_metatype_to_object :
157+
// CHECK-NOT: destroy_value {{%[0-9]+}} : $AnyObject
158+
// CHECK: } // end sil function 'remove_destroy_value_objc_metatype_to_object'
158159
sil [ossa] @remove_destroy_value_objc_metatype_to_object : $@convention(thin) () -> () {
159160
bb0:
160161
%0 = metatype $@thick XXImpl.Type // user: %1
@@ -166,8 +167,9 @@ bb0:
166167
return %5 : $() // id: %6
167168
}
168169

169-
// CHECK-LABEL: sil [ossa] @remove_destroy_value_objc_existential_metatype_to_object
170-
// XHECK-NOT: strong_destroy_value {{%[0-9]+}} : $AnyObject
170+
// CHECK-LABEL: sil [ossa] @remove_destroy_value_objc_existential_metatype_to_object :
171+
// CHECK-NOT: destroy_value {{%[0-9]+}} : $AnyObject
172+
// CHECK: } // end sil function 'remove_destroy_value_objc_existential_metatype_to_object'
171173
sil [ossa] @remove_destroy_value_objc_existential_metatype_to_object: $@convention(thin) (@owned XX) -> () {
172174
bb0(%0 : @owned $XX):
173175
debug_value %0 : $XX // id: %1

0 commit comments

Comments
 (0)