@@ -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
48
- isDeadLiveRange ( SILValue v, SmallVectorImpl<DestroyValueInst *> &destroys,
49
- SmallVectorImpl<SILInstruction *> & forwardingInsts) {
47
+ static bool isDeadLiveRange (
48
+ SILValue v, SmallVectorImpl<DestroyValueInst *> &destroys,
49
+ NullablePtr< SmallVectorImpl<SILInstruction *>> forwardingInsts = nullptr ) {
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,7 +84,8 @@ isDeadLiveRange(SILValue v, SmallVectorImpl<DestroyValueInst *> &destroys,
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 (isa<TermInst>(user) || !isGuaranteedForwardingInst (user) ||
87
+ if (forwardingInsts.isNull () || isa<TermInst>(user) ||
88
+ !isGuaranteedForwardingInst (user) ||
88
89
1 != count_if (user->getOperandValues (
89
90
true /* ignore type dependent operands*/ ),
90
91
[&](SILValue v) {
@@ -97,7 +98,7 @@ isDeadLiveRange(SILValue v, SmallVectorImpl<DestroyValueInst *> &destroys,
97
98
// Ok, this is a forwarding instruction whose ownership we can flip from
98
99
// owned -> guaranteed. Visit its users recursively to see if the the
99
100
// users force the live range to be alive.
100
- forwardingInsts.push_back (user);
101
+ forwardingInsts.get ()-> push_back (user);
101
102
for (SILValue v : user->getResults ()) {
102
103
if (v.getOwnershipKind () != ValueOwnershipKind::Owned)
103
104
continue ;
@@ -297,49 +298,6 @@ static bool canHandleOperand(SILValue operand, SmallVectorImpl<SILValue> &out) {
297
298
return all_of (out, canHandleValue);
298
299
}
299
300
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
-
343
301
// Eliminate a copy of a borrowed value, if:
344
302
//
345
303
// 1. All of the copies users do not consume the copy (and thus can accept a
@@ -387,7 +345,7 @@ bool SemanticARCOptVisitor::performGuaranteedCopyValueOptimization(CopyValueInst
387
345
// value (e.x. storing into memory).
388
346
SmallVector<DestroyValueInst *, 16 > destroys;
389
347
SmallVector<SILInstruction *, 16 > guaranteedForwardingInsts;
390
- if (!isDeadLiveRange (cvi, destroys, guaranteedForwardingInsts))
348
+ if (!isDeadLiveRange (cvi, destroys, & guaranteedForwardingInsts))
391
349
return false ;
392
350
393
351
// Next check if we have any destroys at all of our copy_value and an operand
@@ -494,8 +452,47 @@ bool SemanticARCOptVisitor::performGuaranteedCopyValueOptimization(CopyValueInst
494
452
}
495
453
496
454
eraseAndRAUWSingleValueInstruction (cvi, cvi->getOperand ());
497
- convertForwardingInstsFromOwnedToGuaranteed (guaranteedForwardingInsts);
498
455
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
+ }
499
496
++NumEliminatedInsts;
500
497
return true ;
501
498
}
@@ -738,8 +735,7 @@ bool SemanticARCOptVisitor::visitLoadInst(LoadInst *li) {
738
735
// -> load_borrow if we can put a copy_value on a cold path and thus
739
736
// eliminate RR traffic on a hot path.
740
737
SmallVector<DestroyValueInst *, 32 > destroyValues;
741
- SmallVector<SILInstruction *, 16 > guaranteedForwardingInsts;
742
- if (!isDeadLiveRange (li, destroyValues, guaranteedForwardingInsts))
738
+ if (!isDeadLiveRange (li, destroyValues))
743
739
return false ;
744
740
745
741
// Then check if our address is ever written to. If it is, then we
@@ -764,8 +760,6 @@ bool SemanticARCOptVisitor::visitLoadInst(LoadInst *li) {
764
760
}
765
761
766
762
eraseAndRAUWSingleValueInstruction (li, lbi);
767
- convertForwardingInstsFromOwnedToGuaranteed (guaranteedForwardingInsts);
768
-
769
763
++NumEliminatedInsts;
770
764
++NumLoadCopyConvertedToLoadBorrow;
771
765
return true ;
0 commit comments