42
42
#include " swift/SIL/BasicBlockDatastructures.h"
43
43
#include " swift/SIL/BasicBlockUtils.h"
44
44
#include " swift/SIL/DebugUtils.h"
45
+ #include " swift/SIL/OwnershipUtils.h"
45
46
#include " swift/SIL/SILUndef.h"
46
47
#include " swift/SILOptimizer/Analysis/BasicCalleeAnalysis.h"
47
48
#include " swift/SILOptimizer/Analysis/DeadEndBlocksAnalysis.h"
@@ -263,6 +264,24 @@ static bool convertExtractsToDestructures(CanonicalDefWorklist &copiedDefs,
263
264
return changed;
264
265
}
265
266
267
+ // ===----------------------------------------------------------------------===//
268
+ // MARK: Eliminate redundant moves
269
+ // ===----------------------------------------------------------------------===//
270
+
271
+ // / If the specified move_value is redundant (there's no benefit to separating
272
+ // / the lifetime at it), replace its uses with uses of the moved-from value and
273
+ // / delete it.
274
+ static bool eliminateRedundantMove (MoveValueInst *mvi,
275
+ InstructionDeleter &deleter) {
276
+ if (!isRedundantMoveValue (mvi))
277
+ return false ;
278
+ mvi->replaceAllUsesWith (mvi->getOperand ());
279
+ // Call InstructionDeleter::forceDeleteWithUsers to avoid "fixing up"
280
+ // ownership of the moved-from value, i.e. inserting a destroy_value.
281
+ deleter.forceDeleteWithUsers (mvi);
282
+ return true ;
283
+ }
284
+
266
285
// ===----------------------------------------------------------------------===//
267
286
// MARK: Sink owned forwarding operations
268
287
// ===----------------------------------------------------------------------===//
@@ -419,15 +438,18 @@ void CopyPropagation::run() {
419
438
InstructionDeleter deleter (std::move (callbacks));
420
439
bool changed = false ;
421
440
422
- GraphNodeWorklist<BeginBorrowInst *, 16 > beginBorrowsToShrink;
441
+ StackList<BeginBorrowInst *> beginBorrowsToShrink (f);
442
+ StackList<MoveValueInst *> moveValues (f);
423
443
424
444
// Driver: Find all copied or borrowed defs.
425
445
for (auto &bb : *f) {
426
446
for (auto &i : bb) {
427
447
if (auto *copy = dyn_cast<CopyValueInst>(&i)) {
428
448
defWorklist.updateForCopy (copy);
429
449
} else if (auto *borrow = dyn_cast<BeginBorrowInst>(&i)) {
430
- beginBorrowsToShrink.insert (borrow);
450
+ beginBorrowsToShrink.push_back (borrow);
451
+ } else if (auto *move = dyn_cast<MoveValueInst>(&i)) {
452
+ moveValues.push_back (move);
431
453
} else if (canonicalizeAll) {
432
454
if (auto *destroy = dyn_cast<DestroyValueInst>(&i)) {
433
455
defWorklist.updateForCopy (destroy->getOperand ());
@@ -446,7 +468,7 @@ void CopyPropagation::run() {
446
468
// NOTE: We assume that the function is in reverse post order so visiting the
447
469
// blocks and pushing begin_borrows as we see them and then popping them
448
470
// off the end will result in shrinking inner borrow scopes first.
449
- while (auto *bbi = beginBorrowsToShrink. pop () ) {
471
+ for (auto *bbi : beginBorrowsToShrink) {
450
472
bool firstRun = true ;
451
473
// Run the sequence of utilities:
452
474
// - ShrinkBorrowScope
@@ -480,9 +502,13 @@ void CopyPropagation::run() {
480
502
hoistDestroysOfOwnedLexicalValue (folded, *f, deleter, calleeAnalysis);
481
503
// Keep running even if the new move's destroys can't be hoisted.
482
504
(void )hoisted;
505
+ eliminateRedundantMove (folded, deleter);
483
506
firstRun = false ;
484
507
}
485
508
}
509
+ for (auto *mvi : moveValues) {
510
+ eliminateRedundantMove (mvi, deleter);
511
+ }
486
512
for (auto *argument : f->getArguments ()) {
487
513
if (argument->getOwnershipKind () == OwnershipKind::Owned) {
488
514
hoistDestroysOfOwnedLexicalValue (argument, *f, deleter, calleeAnalysis);
0 commit comments