Skip to content

Commit 068437a

Browse files
committed
run the TargetConstantFolding pass also at -Onone
This is important for performance diagnostics: it’s assumed that (non-generic) MemoryLayout constants do not need to create metadata at runtime. At Onone this is only guaranteed if the TargetConstantFolding pass runs. rdar://94836837
1 parent 62ce764 commit 068437a

File tree

5 files changed

+67
-24
lines changed

5 files changed

+67
-24
lines changed

lib/SILOptimizer/IRGenTransforms/TargetConstantFolding.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,6 @@ class TargetConstantFolding : public SILModuleTransform {
6767
// Scan all instructions in the module for constant foldable instructions.
6868
for (SILFunction &function : *module) {
6969

70-
if (!function.shouldOptimize())
71-
continue;
72-
7370
bool changed = false;
7471
for (SILBasicBlock &block : function) {
7572
InstructionDeleter deleter;

lib/SILOptimizer/PassManager/PassPipeline.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -978,6 +978,9 @@ SILPassPipelinePlan::getOnonePassPipeline(const SILOptions &Options) {
978978
P.startPipeline("Rest of Onone");
979979
P.addUsePrespecialized();
980980

981+
// Needed to fold MemoryLayout constants in performance-annotated functions.
982+
P.addTargetConstantFolding();
983+
981984
// Has only an effect if the -assume-single-thread option is specified.
982985
if (P.getOptions().AssumeSingleThreaded) {
983986
P.addAssumeSingleThreaded();

test/SILOptimizer/memory-layout.swift

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// RUN: %target-swift-frontend -experimental-performance-annotations %s -O -sil-verify-all -module-name=test -emit-sil | %FileCheck %s
2+
3+
// Check that constant propagation of MemoryLayout is also done at -Onone to ensure that
4+
// no metadate is created at runtime - which would violate the performance annotation.
5+
6+
// CHECK-LABEL: sil [no_locks] @$s4test7getSizeSiyF
7+
// CHECK: [[I:%[0-9]+]] = integer_literal {{.*}}, 4
8+
// CHECK: [[S:%[0-9]+]] = struct {{.*}}([[I]]
9+
// CHECK: return [[S]]
10+
// CHECK: } // end sil function '$s4test7getSizeSiyF'
11+
@_noLocks
12+
public func getSize() -> Int {
13+
return MemoryLayout<Int32>.size
14+
}
15+
16+
// CHECK-LABEL: sil [no_locks] @$s4test12getAlignmentSiyF
17+
// CHECK: [[I:%[0-9]+]] = integer_literal {{.*}}, 4
18+
// CHECK: [[S:%[0-9]+]] = struct {{.*}}([[I]]
19+
// CHECK: return [[S]]
20+
// CHECK: } // end sil function '$s4test12getAlignmentSiyF'
21+
@_noLocks
22+
public func getAlignment() -> Int {
23+
return MemoryLayout<Int32>.alignment
24+
}
25+
26+
// CHECK-LABEL: sil [no_locks] @$s4test9getStrideSiyF
27+
// CHECK: [[I:%[0-9]+]] = integer_literal {{.*}}, 4
28+
// CHECK: [[S:%[0-9]+]] = struct {{.*}}([[I]]
29+
// CHECK: return [[S]]
30+
// CHECK: } // end sil function '$s4test9getStrideSiyF'
31+
@_noLocks
32+
public func getStride() -> Int {
33+
return MemoryLayout<Int32>.stride
34+
}
35+

test/SILOptimizer/performance-annotations.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,3 +139,12 @@ func callFuncWithMetatypeArg() {
139139
metatypeArg(Int.self, false) // expected-note {{called from here}}
140140
}
141141

142+
struct GenStruct<A> {
143+
var a: A
144+
}
145+
146+
@_noAllocation
147+
func memoryLayout() -> Int? {
148+
return MemoryLayout<GenStruct<Int>>.size
149+
}
150+

test/SILOptimizer/target-const-prop.swift

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -34,47 +34,46 @@ public func noConstantSize<T>(_ t: T.Type) -> Int {
3434
return MemoryLayout<T>.size
3535
}
3636

37-
// Check that there is not constant propagation if optimizations are disabled.
38-
// This is important for the runtime check to make sure that we are comparing
37+
// It's important to not constant propagate here to make sure that we are comparing
3938
// SIL constant propagated values with IRGen values.
4039

41-
// CHECK-LABEL: sil {{.*}} @$s4test7getSizeSiyF
42-
// CHECK: builtin "sizeof"<S>
43-
// CHECK: } // end sil function '$s4test7getSizeSiyF'
40+
// CHECK-LABEL: sil {{.*}} @$s4test7getSizeySixmlF
41+
// CHECK: builtin "sizeof"<T>
42+
// CHECK: } // end sil function '$s4test7getSizeySixmlF'
4443
@_optimize(none)
45-
func getSize() -> Int {
46-
return MemoryLayout<S>.size
44+
func getSize<T>(_ t: T.Type) -> Int {
45+
return MemoryLayout<T>.size
4746
}
4847

49-
// CHECK-LABEL: sil {{.*}} @$s4test12getAlignmentSiyF
50-
// CHECK: builtin "alignof"<S>
51-
// CHECK: } // end sil function '$s4test12getAlignmentSiyF'
48+
// CHECK-LABEL: sil {{.*}} @$s4test12getAlignmentySixmlF
49+
// CHECK: builtin "alignof"<T>
50+
// CHECK: } // end sil function '$s4test12getAlignmentySixmlF'
5251
@_optimize(none)
53-
func getAlignment() -> Int {
54-
return MemoryLayout<S>.alignment
52+
func getAlignment<T>(_ t: T.Type) -> Int {
53+
return MemoryLayout<T>.alignment
5554
}
5655

57-
// CHECK-LABEL: sil {{.*}} @$s4test9getStrideSiyF
58-
// CHECK: builtin "strideof"<S>
59-
// CHECK: } // end sil function '$s4test9getStrideSiyF'
56+
// CHECK-LABEL: sil {{.*}} @$s4test9getStrideySixmlF
57+
// CHECK: builtin "strideof"<T>
58+
// CHECK: } // end sil function '$s4test9getStrideySixmlF'
6059
@_optimize(none)
61-
func getStride() -> Int {
62-
return MemoryLayout<S>.stride
60+
func getStride<T>(_ t: T.Type) -> Int {
61+
return MemoryLayout<T>.stride
6362
}
6463

6564
@inline(never)
6665
func testit() {
6766
// CHECK-OUTPUT: size: true
68-
print("size: \(S.size == getSize())")
67+
print("size: \(S.size == getSize(S.self))")
6968

7069
// CHECK-OUTPUT: alignment: true
71-
print("alignment: \(S.alignment == getAlignment())")
70+
print("alignment: \(S.alignment == getAlignment(S.self))")
7271

7372
// CHECK-OUTPUT: stride: true
74-
print("stride: \(S.stride == getStride())")
73+
print("stride: \(S.stride == getStride(S.self))")
7574

7675
// CHECK-OUTPUT: doubleSize: true
77-
print("doubleSize: \(S.doubleSize == getSize() * 2)")
76+
print("doubleSize: \(S.doubleSize == getSize(S.self) * 2)")
7877
}
7978

8079
testit()

0 commit comments

Comments
 (0)