Skip to content

Commit d4b1172

Browse files
authored
Merge pull request #70233 from eeckstein/fix-cow-simplification
SimplifyBeginCOWMutation: don't eliminate `end_cow_mutation` instructions with the `[keep_unique]` flag
2 parents 956acc1 + c829d5b commit d4b1172

File tree

5 files changed

+57
-4
lines changed

5 files changed

+57
-4
lines changed

SwiftCompilerSources/Sources/Optimizer/InstructionSimplification/SimplifyBeginCOWMutation.swift

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,13 @@ private extension BeginCOWMutationInst {
7474
return false
7575
}
7676
let buffer = instanceResult
77-
if buffer.uses.ignoreDebugUses.contains(where: { !($0.instruction is EndCOWMutationInst) }) {
77+
guard buffer.uses.ignoreDebugUses.allSatisfy({
78+
if let endCOW = $0.instruction as? EndCOWMutationInst {
79+
return !endCOW.doKeepUnique
80+
}
81+
return false
82+
}) else
83+
{
7884
return false
7985
}
8086

@@ -91,7 +97,8 @@ private extension BeginCOWMutationInst {
9197
if !uniquenessResult.uses.ignoreDebugUses.isEmpty {
9298
return false
9399
}
94-
guard let endCOW = instance as? EndCOWMutationInst else {
100+
guard let endCOW = instance as? EndCOWMutationInst,
101+
!endCOW.doKeepUnique else {
95102
return false
96103
}
97104
if endCOW.uses.ignoreDebugUses.contains(where: { $0.instruction != self }) {

lib/SILOptimizer/SILCombiner/SILCombinerCastVisitors.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -592,7 +592,8 @@ SILInstruction *SILCombiner::visitEndCOWMutationInst(EndCOWMutationInst *ECM) {
592592

593593
SingleValueInstruction *refCast = cast<SingleValueInstruction>(op);
594594
auto *newECM = Builder.createEndCOWMutation(ECM->getLoc(),
595-
refCast->getOperand(0));
595+
refCast->getOperand(0),
596+
ECM->doKeepUnique());
596597
ECM->replaceAllUsesWith(refCast);
597598
refCast->setOperand(0, newECM);
598599
refCast->moveAfter(newECM);

test/SILOptimizer/reverse-array.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public func reverseArray(_ a: [Int]) -> [Int] {
3636
// CHECK: begin_cow_mutation
3737
// CHECK-NOT: {{.*(_cow_mutation|cond_fail)}}
3838
// CHECK: end_cow_mutation
39-
// CHECK-NOT: {{.*(_cow_mutation|cond_fail)}}
39+
// CHECK: end_cow_mutation
4040

4141
// In SIL we fail to eliminate the bounds check of the input array.
4242
// But that's okay, because LLVM can do that.

test/SILOptimizer/sil_combine_inst_passes.sil

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,17 @@ bb0(%0 : @owned $Buffer):
4848
return %t : $(Builtin.Int1, Buffer)
4949
}
5050

51+
// CHECK-LABEL: sil [ossa] @dont_remove_end_begin_cow_pair3
52+
// CHECK: end_cow_mutation
53+
// CHECK: begin_cow_mutation
54+
// CHECK: } // end sil function 'dont_remove_end_begin_cow_pair3'
55+
sil [ossa] @dont_remove_end_begin_cow_pair3 : $@convention(thin) (@owned Buffer) -> @owned Buffer {
56+
bb0(%0 : @owned $Buffer):
57+
%e = end_cow_mutation [keep_unique] %0 : $Buffer
58+
(%u, %b) = begin_cow_mutation %e : $Buffer
59+
return %b : $Buffer
60+
}
61+
5162
// CHECK-LABEL: sil [ossa] @remove_begin_end_cow_pair
5263
// CHECK-NOT: end_cow_mutation
5364
// CHECK-NOT: begin_cow_mutation
@@ -87,6 +98,16 @@ bb0(%0 : @owned $Buffer):
8798
return %t : $(Builtin.Int1, Buffer)
8899
}
89100

101+
// CHECK-LABEL: sil [ossa] @dont_remove_begin_end_cow_pair3
102+
// CHECK: begin_cow_mutation
103+
// CHECK: end_cow_mutation
104+
// CHECK: } // end sil function 'dont_remove_begin_end_cow_pair3'
105+
sil [ossa] @dont_remove_begin_end_cow_pair3 : $@convention(thin) (@owned Buffer) -> @owned Buffer {
106+
bb0(%0 : @owned $Buffer):
107+
(%u, %b) = begin_cow_mutation %0 : $Buffer
108+
%e = end_cow_mutation [keep_unique] %b : $Buffer
109+
return %e : $Buffer
110+
}
90111
// CHECK-LABEL: sil @optimize_empty_cow_singleton
91112
// CHECK: [[I:%[0-9]+]] = integer_literal $Builtin.Int1, 0
92113
// CHECK: begin_cow_mutation

test/SILOptimizer/sil_combine_ossa.sil

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1067,6 +1067,30 @@ bb0(%0 : @owned $C1):
10671067
return %9999 : $()
10681068
}
10691069

1070+
// CHECK-LABEL: sil [ossa] @end_cow_mutation_of_cast :
1071+
// CHECK: %1 = end_cow_mutation %0
1072+
// CHECK-NEXT: %2 = upcast %1
1073+
// CHECK-NEXT: return %2
1074+
// CHECK: } // end sil function 'end_cow_mutation_of_cast'
1075+
sil [ossa] @end_cow_mutation_of_cast : $@convention(thin) (@owned C2) -> @owned C1 {
1076+
bb0(%0 : @owned $C2):
1077+
%1 = upcast %0 : $C2 to $C1
1078+
%2 = end_cow_mutation %1 : $C1
1079+
return %2 : $C1
1080+
}
1081+
1082+
// CHECK-LABEL: sil [ossa] @end_cow_mutation_of_cast2 :
1083+
// CHECK: %1 = end_cow_mutation [keep_unique] %0
1084+
// CHECK-NEXT: %2 = upcast %1
1085+
// CHECK-NEXT: return %2
1086+
// CHECK: } // end sil function 'end_cow_mutation_of_cast2'
1087+
sil [ossa] @end_cow_mutation_of_cast2 : $@convention(thin) (@owned C2) -> @owned C1 {
1088+
bb0(%0 : @owned $C2):
1089+
%1 = upcast %0 : $C2 to $C1
1090+
%2 = end_cow_mutation [keep_unique] %1 : $C1
1091+
return %2 : $C1
1092+
}
1093+
10701094
struct XS {
10711095
var m: Int
10721096
var k: Float

0 commit comments

Comments
 (0)