@@ -44,9 +44,9 @@ STATISTIC(NumLoadCopyConvertedToLoadBorrow,
44
44
// /
45
45
// / Semantically this implies that a value is never passed off as +1 to memory
46
46
// / or another function implying it can be used everywhere at +0.
47
- static bool isDeadLiveRange (
48
- SILValue v, SmallVectorImpl<DestroyValueInst *> &destroys,
49
- NullablePtr< SmallVectorImpl<SILInstruction *>> forwardingInsts = nullptr ) {
47
+ static bool
48
+ isDeadLiveRange ( SILValue v, SmallVectorImpl<DestroyValueInst *> &destroys,
49
+ SmallVectorImpl<SILInstruction *> & forwardingInsts) {
50
50
assert (v.getOwnershipKind () == ValueOwnershipKind::Owned);
51
51
SmallVector<Operand *, 32 > worklist (v->use_begin (), v->use_end ());
52
52
while (!worklist.empty ()) {
@@ -84,8 +84,7 @@ static bool isDeadLiveRange(
84
84
//
85
85
// NOTE: Today we do not support TermInsts for simplicity... we /could/
86
86
// support it though if we need to.
87
- if (forwardingInsts.isNull () || isa<TermInst>(user) ||
88
- !isGuaranteedForwardingInst (user) ||
87
+ if (isa<TermInst>(user) || !isGuaranteedForwardingInst (user) ||
89
88
1 != count_if (user->getOperandValues (
90
89
true /* ignore type dependent operands*/ ),
91
90
[&](SILValue v) {
@@ -98,7 +97,7 @@ static bool isDeadLiveRange(
98
97
// Ok, this is a forwarding instruction whose ownership we can flip from
99
98
// owned -> guaranteed. Visit its users recursively to see if the the
100
99
// users force the live range to be alive.
101
- forwardingInsts.get ()-> push_back (user);
100
+ forwardingInsts.push_back (user);
102
101
for (SILValue v : user->getResults ()) {
103
102
if (v.getOwnershipKind () != ValueOwnershipKind::Owned)
104
103
continue ;
@@ -298,6 +297,49 @@ static bool canHandleOperand(SILValue operand, SmallVectorImpl<SILValue> &out) {
298
297
return all_of (out, canHandleValue);
299
298
}
300
299
300
+ static void convertForwardingInstsFromOwnedToGuaranteed (
301
+ SmallVectorImpl<SILInstruction *> &guaranteedForwardingInsts) {
302
+ // Then change all of our guaranteed forwarding insts to have guaranteed
303
+ // ownership kind instead of what ever they previously had (ignoring trivial
304
+ // results);
305
+ while (!guaranteedForwardingInsts.empty ()) {
306
+ auto *i = guaranteedForwardingInsts.pop_back_val ();
307
+ assert (i->hasResults ());
308
+
309
+ for (SILValue result : i->getResults ()) {
310
+ if (auto *svi = dyn_cast<OwnershipForwardingSingleValueInst>(result)) {
311
+ if (svi->getOwnershipKind () == ValueOwnershipKind::Owned) {
312
+ svi->setOwnershipKind (ValueOwnershipKind::Guaranteed);
313
+ }
314
+ continue ;
315
+ }
316
+
317
+ if (auto *ofci = dyn_cast<OwnershipForwardingConversionInst>(result)) {
318
+ if (ofci->getOwnershipKind () == ValueOwnershipKind::Owned) {
319
+ ofci->setOwnershipKind (ValueOwnershipKind::Guaranteed);
320
+ }
321
+ continue ;
322
+ }
323
+
324
+ if (auto *sei = dyn_cast<OwnershipForwardingSelectEnumInstBase>(result)) {
325
+ if (sei->getOwnershipKind () == ValueOwnershipKind::Owned) {
326
+ sei->setOwnershipKind (ValueOwnershipKind::Guaranteed);
327
+ }
328
+ continue ;
329
+ }
330
+
331
+ if (auto *mvir = dyn_cast<MultipleValueInstructionResult>(result)) {
332
+ if (mvir->getOwnershipKind () == ValueOwnershipKind::Owned) {
333
+ mvir->setOwnershipKind (ValueOwnershipKind::Guaranteed);
334
+ }
335
+ continue ;
336
+ }
337
+
338
+ llvm_unreachable (" unhandled forwarding instruction?!" );
339
+ }
340
+ }
341
+ }
342
+
301
343
// Eliminate a copy of a borrowed value, if:
302
344
//
303
345
// 1. All of the copies users do not consume the copy (and thus can accept a
@@ -345,7 +387,7 @@ bool SemanticARCOptVisitor::performGuaranteedCopyValueOptimization(CopyValueInst
345
387
// value (e.x. storing into memory).
346
388
SmallVector<DestroyValueInst *, 16 > destroys;
347
389
SmallVector<SILInstruction *, 16 > guaranteedForwardingInsts;
348
- if (!isDeadLiveRange (cvi, destroys, & guaranteedForwardingInsts))
390
+ if (!isDeadLiveRange (cvi, destroys, guaranteedForwardingInsts))
349
391
return false ;
350
392
351
393
// Next check if we have any destroys at all of our copy_value and an operand
@@ -452,47 +494,8 @@ bool SemanticARCOptVisitor::performGuaranteedCopyValueOptimization(CopyValueInst
452
494
}
453
495
454
496
eraseAndRAUWSingleValueInstruction (cvi, cvi->getOperand ());
497
+ convertForwardingInstsFromOwnedToGuaranteed (guaranteedForwardingInsts);
455
498
456
- // Then change all of our guaranteed forwarding insts to have guaranteed
457
- // ownership kind instead of what ever they previously had (ignoring trivial
458
- // results);
459
- while (!guaranteedForwardingInsts.empty ()) {
460
- auto *i = guaranteedForwardingInsts.pop_back_val ();
461
-
462
- assert (i->hasResults ());
463
-
464
- for (SILValue result : i->getResults ()) {
465
- if (auto *svi = dyn_cast<OwnershipForwardingSingleValueInst>(result)) {
466
- if (svi->getOwnershipKind () == ValueOwnershipKind::Owned) {
467
- svi->setOwnershipKind (ValueOwnershipKind::Guaranteed);
468
- }
469
- continue ;
470
- }
471
-
472
- if (auto *ofci = dyn_cast<OwnershipForwardingConversionInst>(result)) {
473
- if (ofci->getOwnershipKind () == ValueOwnershipKind::Owned) {
474
- ofci->setOwnershipKind (ValueOwnershipKind::Guaranteed);
475
- }
476
- continue ;
477
- }
478
-
479
- if (auto *sei = dyn_cast<OwnershipForwardingSelectEnumInstBase>(result)) {
480
- if (sei->getOwnershipKind () == ValueOwnershipKind::Owned) {
481
- sei->setOwnershipKind (ValueOwnershipKind::Guaranteed);
482
- }
483
- continue ;
484
- }
485
-
486
- if (auto *mvir = dyn_cast<MultipleValueInstructionResult>(result)) {
487
- if (mvir->getOwnershipKind () == ValueOwnershipKind::Owned) {
488
- mvir->setOwnershipKind (ValueOwnershipKind::Guaranteed);
489
- }
490
- continue ;
491
- }
492
-
493
- llvm_unreachable (" unhandled forwarding instruction?!" );
494
- }
495
- }
496
499
++NumEliminatedInsts;
497
500
return true ;
498
501
}
@@ -735,7 +738,8 @@ bool SemanticARCOptVisitor::visitLoadInst(LoadInst *li) {
735
738
// -> load_borrow if we can put a copy_value on a cold path and thus
736
739
// eliminate RR traffic on a hot path.
737
740
SmallVector<DestroyValueInst *, 32 > destroyValues;
738
- if (!isDeadLiveRange (li, destroyValues))
741
+ SmallVector<SILInstruction *, 16 > guaranteedForwardingInsts;
742
+ if (!isDeadLiveRange (li, destroyValues, guaranteedForwardingInsts))
739
743
return false ;
740
744
741
745
// Then check if our address is ever written to. If it is, then we
@@ -760,6 +764,8 @@ bool SemanticARCOptVisitor::visitLoadInst(LoadInst *li) {
760
764
}
761
765
762
766
eraseAndRAUWSingleValueInstruction (li, lbi);
767
+ convertForwardingInstsFromOwnedToGuaranteed (guaranteedForwardingInsts);
768
+
763
769
++NumEliminatedInsts;
764
770
++NumLoadCopyConvertedToLoadBorrow;
765
771
return true ;
0 commit comments