File tree Expand file tree Collapse file tree 3 files changed +61
-1
lines changed
lib/SILOptimizer/SILCombiner Expand file tree Collapse file tree 3 files changed +61
-1
lines changed Original file line number Diff line number Diff line change @@ -301,6 +301,7 @@ class SILCombiner :
301
301
302
302
SILInstruction *visitMarkDependenceInst (MarkDependenceInst *MDI);
303
303
SILInstruction *visitClassifyBridgeObjectInst (ClassifyBridgeObjectInst *CBOI);
304
+ SILInstruction *visitGlobalValueInst (GlobalValueInst *globalValue);
304
305
SILInstruction *visitConvertFunctionInst (ConvertFunctionInst *CFI);
305
306
SILInstruction *
306
307
visitConvertEscapeToNoEscapeInst (ConvertEscapeToNoEscapeInst *Cvt);
Original file line number Diff line number Diff line change @@ -2283,3 +2283,40 @@ SILCombiner::visitClassifyBridgeObjectInst(ClassifyBridgeObjectInst *cboi) {
2283
2283
2284
2284
return nullptr ;
2285
2285
}
2286
+
2287
+ // / Returns true if reference counting and debug_value users of a global_value
2288
+ // / can be deleted.
2289
+ static bool checkGlobalValueUsers (SILValue val,
2290
+ SmallVectorImpl<SILInstruction *> &toDelete) {
2291
+ for (Operand *use : val->getUses ()) {
2292
+ SILInstruction *user = use->getUser ();
2293
+ if (isa<RefCountingInst>(user) || isa<DebugValueInst>(user)) {
2294
+ toDelete.push_back (user);
2295
+ continue ;
2296
+ }
2297
+ if (auto *upCast = dyn_cast<UpcastInst>(user)) {
2298
+ if (!checkGlobalValueUsers (upCast, toDelete))
2299
+ return false ;
2300
+ continue ;
2301
+ }
2302
+ // Projection instructions don't access the object header, so they don't
2303
+ // prevent deleting reference counting instructions.
2304
+ if (isa<RefElementAddrInst>(user) || isa<RefTailAddrInst>(user))
2305
+ continue ;
2306
+ return false ;
2307
+ }
2308
+ return true ;
2309
+ }
2310
+
2311
+ SILInstruction *
2312
+ SILCombiner::visitGlobalValueInst (GlobalValueInst *globalValue) {
2313
+ // Delete all reference count instructions on a global_value if the only other
2314
+ // users are projections (ref_element_addr and ref_tail_addr).
2315
+ SmallVector<SILInstruction *, 8 > toDelete;
2316
+ if (!checkGlobalValueUsers (globalValue, toDelete))
2317
+ return nullptr ;
2318
+ for (SILInstruction *inst : toDelete) {
2319
+ eraseInstFromFunction (*inst);
2320
+ }
2321
+ return nullptr ;
2322
+ }
Original file line number Diff line number Diff line change @@ -4203,4 +4203,26 @@ bb1(%result : $Builtin.NativeObject):
4203
4203
4204
4204
bb2(%error : $Error):
4205
4205
unreachable
4206
- }
4206
+ }
4207
+
4208
+ sil_global private @outlined_global : $_ContiguousArrayStorage<Int>
4209
+
4210
+ // CHECK-LABEL: sil @test_global_value
4211
+ // CHECK-NOT: retain
4212
+ // CHECK-NOT: release
4213
+ // CHECK-NOT: debug_value
4214
+ // CHECK: } // end sil function 'test_global_value'
4215
+ sil @test_global_value : $@convention(thin) () -> Int {
4216
+ bb0:
4217
+ %0 = global_value @outlined_global : $_ContiguousArrayStorage<Int>
4218
+ strong_retain %0 : $_ContiguousArrayStorage<Int>
4219
+ debug_value %0 : $_ContiguousArrayStorage<Int>, let, name "x"
4220
+ %2 = upcast %0 : $_ContiguousArrayStorage<Int> to $__ContiguousArrayStorageBase
4221
+ strong_retain %2 : $__ContiguousArrayStorageBase
4222
+ %13 = ref_tail_addr [immutable] %2 : $__ContiguousArrayStorageBase, $Int
4223
+ %16 = load %13 : $*Int
4224
+ strong_release %2 : $__ContiguousArrayStorageBase
4225
+ strong_release %0 : $_ContiguousArrayStorage<Int>
4226
+ return %16 : $Int
4227
+ } // end sil function 'test_global_value'
4228
+
You can’t perform that action at this time.
0 commit comments