From 851bfeb3188a956f96e464c8b16441521f38cfa2 Mon Sep 17 00:00:00 2001 From: Andrew Trick Date: Sat, 8 May 2021 18:56:45 -0700 Subject: [PATCH] Fix copy_value to have 'None' side-effects. Copies can be moved as much as you like as long as OSSA is legal. This fixes some instruction deletion utilities for OSSA and any other utilities that check side effects. Copies are common. It also finally allows pure functions to be CSE'd! --- include/swift/SIL/SILNodes.def | 4 +++- test/SILOptimizer/cse_apply_ossa.sil | 12 ++++++------ test/SILOptimizer/sil_combine_ossa.sil | 8 ++++++-- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/include/swift/SIL/SILNodes.def b/include/swift/SIL/SILNodes.def index 71bc90f71c013..6198af4227367 100644 --- a/include/swift/SIL/SILNodes.def +++ b/include/swift/SIL/SILNodes.def @@ -582,8 +582,10 @@ ABSTRACT_VALUE_AND_INST(SingleValueInstruction, ValueBase, SILInstruction) SingleValueInstruction, MayHaveSideEffects, DoesNotRelease) SINGLE_VALUE_INST(CopyBlockWithoutEscapingInst, copy_block_without_escaping, SingleValueInstruction, MayHaveSideEffects, DoesNotRelease) + // A copy_value's retain semantics are fully encapsulated in OSSA + // invariants. It has no side effects relative to other OSSA values. SINGLE_VALUE_INST(CopyValueInst, copy_value, - SingleValueInstruction, MayHaveSideEffects, DoesNotRelease) + SingleValueInstruction, None, DoesNotRelease) #define UNCHECKED_REF_STORAGE(Name, name, ...) \ SINGLE_VALUE_INST(StrongCopy##Name##ValueInst, strong_copy_##name##_value, \ SingleValueInstruction, MayHaveSideEffects, DoesNotRelease) diff --git a/test/SILOptimizer/cse_apply_ossa.sil b/test/SILOptimizer/cse_apply_ossa.sil index 3713a24328181..eac5f22c51e3c 100644 --- a/test/SILOptimizer/cse_apply_ossa.sil +++ b/test/SILOptimizer/cse_apply_ossa.sil @@ -122,11 +122,11 @@ bb0(%0 : $Int64): return %14 : $Int64 } -// CHECK-LABEL: sil [ossa] @dont_cse_retain_only_apply : -// CHECK: %{{[0-9]+}} = apply -// CHECK: %{{[0-9]+}} = apply -// CHECK-LABEL:} // end sil function 'dont_cse_retain_only_apply' -sil [ossa] @dont_cse_retain_only_apply : $@convention(thin) () -> () { +// CHECK-LABEL: sil [ossa] @cse_retain_only_apply : +// CHECK: apply +// CHECK-NOT: apply +// CHECK-LABEL:} // end sil function 'cse_retain_only_apply' +sil [ossa] @cse_retain_only_apply : $@convention(thin) () -> () { bb0: %f = function_ref @retain_only : $@convention(thin) () -> @owned XX %a1 = apply %f() : $@convention(thin) () -> @owned XX @@ -169,7 +169,7 @@ bb0(%0 : @guaranteed $Klass): // CHECK-LABEL: sil [ossa] @apply_nontrivial_test2 : // CHECK: apply -// CHECK: apply +// CHECK-NOT: apply // CHECK-LABEL:} // end sil function 'apply_nontrivial_test2' sil [ossa] @apply_nontrivial_test2 : $@convention(thin) (@guaranteed Klass) -> () { bb0(%0 : @guaranteed $Klass): diff --git a/test/SILOptimizer/sil_combine_ossa.sil b/test/SILOptimizer/sil_combine_ossa.sil index dfef85df1f402..08405102d04f5 100644 --- a/test/SILOptimizer/sil_combine_ossa.sil +++ b/test/SILOptimizer/sil_combine_ossa.sil @@ -772,14 +772,18 @@ sil [ossa] @unbalanced_closure : $@convention(thin) (@guaranteed B) -> () // CHECK-NOT: partial_apply // Check that the arguments of the closure are released after its last use // CHECK-NEXT: destroy_value %0 : $B -// CHECK-NEXT: unreachable +// CHECK-NEXT: tuple +// CHECK-NEXT: return // CHECK: } // end sil function 'partial_apply_unbalanced_retain_release' sil [ossa] @partial_apply_unbalanced_retain_release : $@convention(thin) (@owned B) -> () { bb0(%0 : @owned $B): %1 = function_ref @unbalanced_closure : $@convention(thin) (@guaranteed B) -> () %2 = partial_apply %1(%0) : $@convention(thin) (@guaranteed B) -> () %2a = copy_value %2 : $@callee_owned () -> () - unreachable + destroy_value %2 : $@callee_owned () -> () + destroy_value %2a : $@callee_owned () -> () + %99 = tuple () + return %99 : $() } class C1 {}