Skip to content

Commit 11a641f

Browse files
committed
Enable mandatory copy propagation SIL pass.
This shortens -Onone lifetimes. To eliminate ARC traffic, the optimizer reorders object destruction. This changes observable program behavior. If a custom deinitializer produces side effects, code may observe those side effects earlier after optimization. Similarly, code that dereferences a weak reference may observe a 'nil' reference after optimization, while the unoptimized code observed a valid object. Developers have overwhelmingly requested that object lifetimes have similar behavior in -Onone and -O builds in order to find and diagnose program bugs involving weak references and other lifetime assumptions. Enabling the copy propagation at -Onone is simply a matter of flipping a switch. -Onone runtime and code size will improve. By design, copy propagation, has no direct affect on compile time. It will indirectly improve optimized compile times, but in debug builds, it simply isn't a factor. To support debugging, a "poison" flag was (in prior commits) added to new destroy_value instructions generated by copy propagation. When OwnershipModelEliminator lowers destroy_value [poison] it will generate new debug_value instructions with a “poison” flag. These additional poison stores to the stack could increase both code size and -Onone runtime. rdar://75012368 (-Onone compiler support for early object deinitialization with sentinel dead references)
1 parent 8ba6868 commit 11a641f

File tree

4 files changed

+9
-6
lines changed

4 files changed

+9
-6
lines changed

lib/SILOptimizer/PassManager/PassPipeline.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -845,7 +845,7 @@ SILPassPipelinePlan::getOnonePassPipeline(const SILOptions &Options) {
845845
P.startPipeline("non-Diagnostic Enabling Mandatory Optimizations");
846846
P.addForEachLoopUnroll();
847847
P.addMandatoryCombine();
848-
if (P.getOptions().EnableCopyPropagation) {
848+
if (!P.getOptions().DisableCopyPropagation) {
849849
// MandatoryCopyPropagation should only be run at -Onone, not -O.
850850
P.addMandatoryCopyPropagation();
851851
}

test/IRGen/unmanaged_objc_throw_func.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,16 @@ import Foundation
3636

3737
// CHECK: [[L2]]: ; preds = %entry
3838
// CHECK-NEXT: %[[T4:.+]] = phi %TSo10CFArrayRefa* [ %[[T0]], %entry ]
39+
// CHECK-NEXT: %[[T4a:.+]] = bitcast %T25unmanaged_objc_throw_func9SR_9035_CC* %{{.+}} to i8*
40+
// CHECK-NEXT: call void @llvm.objc.release(i8* %[[T4a]])
3941
// CHECK-NEXT: %[[T5:.+]] = ptrtoint %TSo10CFArrayRefa* %[[T4]] to i{{32|64}}
4042
// CHECK-NEXT: br label %[[L3:.+]]
4143

4244
// CHECK: [[L1]]: ; preds = %entry
4345
// CHECK-NEXT: %[[T6:.+]] = phi %swift.error* [ %[[T2]], %entry ]
4446
// CHECK-NEXT: store %swift.error* null, %swift.error** %swifterror, align {{[0-9]+}}
47+
// CHECK-NEXT: %[[T6a:.+]] = bitcast %T25unmanaged_objc_throw_func9SR_9035_CC* %{{.+}} to i8*
48+
// CHECK-NEXT: call void @llvm.objc.release(i8* %[[T6a]])
4549
// CHECK-NEXT: %[[T7:.+]] = icmp eq i{{32|64}} %{{.+}}, 0
4650
// CHECK-NEXT: br i1 %[[T7]], label %[[L4:.+]], label %[[L5:.+]]
4751

@@ -66,7 +70,5 @@ import Foundation
6670

6771
// CHECK: [[L3]]: ; preds = %[[L2]], %[[L7]]
6872
// CHECK-NEXT: %[[T12:.+]] = phi i{{32|64}} [ 0, %[[L7]] ], [ %[[T5]], %[[L2]] ]
69-
// CHECK-NEXT: %[[T13:.+]] = bitcast %T25unmanaged_objc_throw_func9SR_9035_CC* %{{.+}} to i8*
70-
// CHECK-NEXT: call void @llvm.objc.release(i8* %[[T13]])
7173
// CHECK-NEXT: %[[T14:.+]] = inttoptr i{{32|64}} %[[T12]] to %struct.__CFArray*
7274
// CHECK-NEXT: ret %struct.__CFArray* %[[T14]]

test/Interpreter/builtin_bridge_object.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ if true {
6565
// CHECK-NEXT: true
6666
print(x === x2)
6767
// CHECK-OPT-NEXT: deallocated
68+
// CHECK-DBG-NEXT: deallocated
6869

6970
print(nonPointerBits(bo) == 0)
7071
// CHECK-NEXT: true
@@ -78,7 +79,6 @@ if true {
7879
_fixLifetime(bo3)
7980
_fixLifetime(bo4)
8081
}
81-
// CHECK-DBG-NEXT: deallocated
8282
// CHECK-NEXT: deallocated
8383

8484
// Try with all spare bits set.
@@ -94,6 +94,7 @@ if true {
9494
// CHECK-NEXT: true
9595
print(x === x2)
9696
// CHECK-OPT-NEXT: deallocated
97+
// CHECK-DBG-NEXT: deallocated
9798

9899
print(nonPointerBits(bo) == NATIVE_SPARE_BITS)
99100
// CHECK-NEXT: true
@@ -107,7 +108,6 @@ if true {
107108
_fixLifetime(bo3)
108109
_fixLifetime(bo4)
109110
}
110-
// CHECK-DBG-NEXT: deallocated
111111
// CHECK-NEXT: deallocated
112112

113113

test/sil-passpipeline-dump/basic.test-sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22

33
// CHECK: ---
44
// CHECK: name: non-Diagnostic Enabling Mandatory Optimizations
5-
// CHECK: passes: [ "for-each-loop-unroll", "mandatory-combine", "mandatory-arc-opts" ]
5+
// CHECK: passes: [ "for-each-loop-unroll", "mandatory-combine", "mandatory-copy-propagation",
6+
// CHECK: "mandatory-arc-opts" ]
67
// CHECK: ---
78
// CHECK: name: Serialization
89
// CHECK: passes: [ "serialize-sil", "ownership-model-eliminator" ]

0 commit comments

Comments
 (0)