Skip to content

Commit 6b1bee7

Browse files
committed
[CopyPropagation] Canonicalize moved-from values.
If a move_value is determined to be redundant and removed, take the opportunity its removal makes available to canonicalize the moved-from value without the obstruction of the move_value.
1 parent f5e8fc2 commit 6b1bee7

File tree

2 files changed

+27
-4
lines changed

2 files changed

+27
-4
lines changed

lib/SILOptimizer/Transforms/CopyPropagation.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -282,13 +282,16 @@ static bool convertExtractsToDestructures(CanonicalDefWorklist &copiedDefs,
282282
/// the lifetime at it), replace its uses with uses of the moved-from value and
283283
/// delete it.
284284
static bool eliminateRedundantMove(MoveValueInst *mvi,
285-
InstructionDeleter &deleter) {
285+
InstructionDeleter &deleter,
286+
CanonicalDefWorklist &defWorklist) {
286287
if (!isRedundantMoveValue(mvi))
287288
return false;
288-
mvi->replaceAllUsesWith(mvi->getOperand());
289+
auto original = mvi->getOperand();
290+
mvi->replaceAllUsesWith(original);
289291
// Call InstructionDeleter::forceDeleteWithUsers to avoid "fixing up"
290292
// ownership of the moved-from value, i.e. inserting a destroy_value.
291293
deleter.forceDeleteWithUsers(mvi);
294+
defWorklist.updateForCopy(original);
292295
return true;
293296
}
294297

@@ -512,12 +515,12 @@ void CopyPropagation::run() {
512515
hoistDestroysOfOwnedLexicalValue(folded, *f, deleter, calleeAnalysis);
513516
// Keep running even if the new move's destroys can't be hoisted.
514517
(void)hoisted;
515-
eliminateRedundantMove(folded, deleter);
518+
eliminateRedundantMove(folded, deleter, defWorklist);
516519
firstRun = false;
517520
}
518521
}
519522
for (auto *mvi : moveValues) {
520-
eliminateRedundantMove(mvi, deleter);
523+
eliminateRedundantMove(mvi, deleter, defWorklist);
521524
}
522525
for (auto *argument : f->getArguments()) {
523526
if (argument->getOwnershipKind() == OwnershipKind::Owned) {

test/SILOptimizer/copy_propagation.sil

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -874,6 +874,26 @@ entry:
874874
return %retval : $()
875875
}
876876

877+
// Canonicalize the moved-from value when a move_value is deemed redundant and
878+
// eliminated.
879+
// CHECK-LABEL: sil [ossa] @canonicalize_source_of_redundant_move_value : {{.*}} {
880+
// CHECK: [[GET_OWNED_C:%[^,]+]] = function_ref @getOwnedC
881+
// CHECK: [[TAKE_OWNED_C:%[^,]+]] = function_ref @takeOwnedC
882+
// CHECK: [[C:%[^,]+]] = apply [[GET_OWNED_C]]() : $@convention(thin) () -> @owned C
883+
// CHECK: apply [[TAKE_OWNED_C]]([[C]]) : $@convention(thin) (@owned C) -> ()
884+
// CHECK-LABEL: } // end sil function 'canonicalize_source_of_redundant_move_value'
885+
sil [ossa] @canonicalize_source_of_redundant_move_value : $@convention(thin) () -> () {
886+
%getOwnedC = function_ref @getOwnedC : $@convention(thin) () -> (@owned C)
887+
%takeOwnedC = function_ref @takeOwnedC : $@convention(thin) (@owned C) -> ()
888+
%c = apply %getOwnedC() : $@convention(thin) () -> (@owned C)
889+
%c2 = move_value %c : $C
890+
%c3 = copy_value %c2 : $C
891+
apply %takeOwnedC(%c3) : $@convention(thin) (@owned C) -> ()
892+
destroy_value %c2 : $C
893+
%retval = tuple ()
894+
return %retval : $()
895+
}
896+
877897
// Verify that a dead copy_value is deleted.
878898
// CHECK-LABEL: sil [ossa] @delete_dead_reborrow_copy : {{.*}} {
879899
// CHECK-NOT: copy_value

0 commit comments

Comments
 (0)