@@ -60,6 +60,28 @@ namespace {
60
60
61
61
struct SILMoveOnlyWrappedTypeEliminatorVisitor
62
62
: SILInstructionVisitor<SILMoveOnlyWrappedTypeEliminatorVisitor, bool > {
63
+
64
+ // Instructions waiting to be visited.
65
+ llvm::SmallSetVector<SILInstruction *, 8 > &pendingInsts;
66
+ llvm::SmallVector<SILInstruction *, 8 > deferredInsts;
67
+
68
+ SILMoveOnlyWrappedTypeEliminatorVisitor (llvm::SmallSetVector<SILInstruction *, 8 > &pendingInsts):
69
+ pendingInsts (pendingInsts)
70
+ {}
71
+
72
+ // If 'user's operand is not yet visited, push it onto the end of
73
+ // 'pendingInsts' and pretend we didn't see it yet. This is only relevant for
74
+ // non-address operands in which ownership should be consistent.
75
+ bool waitFor (SILInstruction *user, SILValue operand) {
76
+ if (auto *def = operand.getDefiningInstruction ()) {
77
+ if (pendingInsts.contains (def)) {
78
+ deferredInsts.push_back (user);
79
+ return false ;
80
+ }
81
+ }
82
+ return true ;
83
+ }
84
+
63
85
bool visitSILInstruction (SILInstruction *inst) {
64
86
llvm::errs () << " Unhandled SIL Instruction: " << *inst;
65
87
llvm_unreachable (" error" );
@@ -79,13 +101,19 @@ struct SILMoveOnlyWrappedTypeEliminatorVisitor
79
101
}
80
102
81
103
bool visitStoreInst (StoreInst *si) {
104
+ if (!waitFor (si, si->getSrc ())) {
105
+ return false ;
106
+ }
82
107
if (!si->getSrc ()->getType ().isTrivial (*si->getFunction ()))
83
108
return false ;
84
109
si->setOwnershipQualifier (StoreOwnershipQualifier::Trivial);
85
110
return true ;
86
111
}
87
112
88
113
bool visitStoreBorrowInst (StoreBorrowInst *si) {
114
+ if (!waitFor (si, si->getSrc ())) {
115
+ return false ;
116
+ }
89
117
if (!si->getSrc ()->getType ().isTrivial (*si->getFunction ()))
90
118
return false ;
91
119
SILBuilderWithScope b (si);
@@ -332,6 +360,9 @@ bool SILMoveOnlyWrappedTypeEliminator::process() {
332
360
return true ;
333
361
};
334
362
363
+ // (1) Check each value's type for the MoveOnly wrapper, (2) strip the wrapper
364
+ // type, and (3) add all uses to 'touchedInsts' in forward order for
365
+ // efficiency.
335
366
for (auto &bb : *fn) {
336
367
for (auto *arg : bb.getArguments ()) {
337
368
bool relevant = visitValue (arg);
@@ -377,9 +408,18 @@ bool SILMoveOnlyWrappedTypeEliminator::process() {
377
408
madeChange = true ;
378
409
}
379
410
380
- SILMoveOnlyWrappedTypeEliminatorVisitor visitor;
381
- while (!touchedInsts.empty ()) {
382
- visitor.visit (touchedInsts.pop_back_val ());
411
+ SILMoveOnlyWrappedTypeEliminatorVisitor visitor{touchedInsts};
412
+ while (true ) {
413
+ while (!touchedInsts.empty ()) {
414
+ visitor.visit (touchedInsts.pop_back_val ());
415
+ }
416
+ if (visitor.deferredInsts .empty ())
417
+ break ;
418
+
419
+ for (auto *inst : visitor.deferredInsts ) {
420
+ touchedInsts.insert (inst);
421
+ }
422
+ visitor.deferredInsts .clear ();
383
423
}
384
424
385
425
return madeChange;
0 commit comments