-
Notifications
You must be signed in to change notification settings - Fork 10.4k
/
Copy pathskip-non-inlinable-function-bodies.swift
253 lines (202 loc) · 8.64 KB
/
skip-non-inlinable-function-bodies.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
// RUN: %empty-directory(%t)
// 1. Make sure you can't -emit-ir or -c when you're skipping non-inlinable function bodies
// RUN: not %target-swift-frontend -emit-ir %s -experimental-skip-non-inlinable-function-bodies %s 2>&1 | %FileCheck %s --check-prefix ERROR
// RUN: not %target-swift-frontend -c %s -experimental-skip-non-inlinable-function-bodies %s 2>&1 | %FileCheck %s --check-prefix ERROR
// ERROR: -experimental-skip-non-inlinable-function-bodies does not support emitting IR
// 2. Emit the SIL for a module and check it against the expected strings in function bodies.
// If we're doing the right skipping, then the strings that are CHECK-NOT'd won't have been typechecked or SILGen'd.
// RUN: %target-swift-frontend -emit-sil -O -experimental-skip-non-inlinable-function-bodies -emit-sorted-sil %s 2>&1 | %FileCheck %s --check-prefixes CHECK,CHECK-SIL-ONLY
// 3. Emit the module interface while skipping non-inlinable function bodies. Check it against the same set of strings.
// RUN: %target-swift-frontend -typecheck %s -enable-library-evolution -emit-module-interface-path %t/Module.skipping.swiftinterface -experimental-skip-non-inlinable-function-bodies
// RUN: %FileCheck %s --check-prefixes CHECK,CHECK-INTERFACE-ONLY < %t/Module.skipping.swiftinterface
// 4. Emit the module interface normally. Also check it against the same set of strings.
// RUN: %target-swift-frontend -typecheck %s -enable-library-evolution -emit-module-interface-path %t/Module.swiftinterface
// RUN: %FileCheck %s --check-prefixes CHECK,CHECK-INTERFACE-ONLY < %t/Module.swiftinterface
// 5. The module interfaces should be exactly the same.
// RUN: diff -u %t/Module.skipping.swiftinterface %t/Module.swiftinterface
@usableFromInline
@inline(never)
func _blackHole(_ s: String) {}
// NOTE: The order of the checks below is important. The checks try to be
// logically grouped, but sometimes -emit-sorted-sil needs to break the logical
// order.
@inlinable public func inlinableFunc() {
_blackHole("@inlinable func body") // CHECK: "@inlinable func body"
}
@_fixed_layout
public class InlinableDeinit {
@inlinable deinit {
_blackHole("@inlinable deinit body") // CHECK: "@inlinable deinit body"
}
}
@_fixed_layout
public class InlineAlwaysDeinit {
@inline(__always) deinit {
_blackHole("@inline(__always) deinit body") // CHECK-NOT: "@inline(__always) deinit body"
}
}
public class NormalDeinit {
deinit {
_blackHole("regular deinit body") // CHECK-NOT: "regular deinit body"
}
}
@_transparent public func transparentFunc() {
_blackHole("@_transparent func body") // CHECK: "@_transparent func body"
}
@inline(__always) public func inlineAlwaysFunc() {
_blackHole("@inline(__always) func body") // CHECK-NOT: "@inline(__always) func body"
}
func internalFunc() {
_blackHole("internal func body") // CHECK-NOT: "internal func body"
}
public func publicFunc() {
_blackHole("public func body") // CHECK-NOT: "public func body"
}
private func privateFunc() {
_blackHole("private func body") // CHECK-NOT: "private func body"
}
@inline(__always) public func inlineAlwaysLocalTypeFunc() {
typealias InlineAlwaysLocalType = Int
_blackHole("@inline(__always) func body with local type") // CHECK-NOT: "@inline(__always) func body with local type"
func takesInlineAlwaysLocalType(_ x: InlineAlwaysLocalType) {
_blackHole("nested func body inside @inline(__always) func body taking local type") // CHECK-NOT: "nested func body inside @inline(__always) func body taking local type"
}
takesInlineAlwaysLocalType(0)
}
public func publicLocalTypeFunc() {
typealias LocalType = Int
_blackHole("public func body with local type") // CHECK-NOT: "public func body with local type"
func takesLocalType(_ x: LocalType) {
_blackHole("nested func body inside public func body taking local type") // CHECK-NOT: "nested func body inside public func body taking local type"
}
takesLocalType(0)
}
@inlinable
public func inlinableLocalTypeFunc() {
typealias InlinableLocalType = Int
_blackHole("@inlinable func body with local type") // CHECK: "@inlinable func body with local type"
func takesInlinableLocalType(_ x: InlinableLocalType) {
_blackHole("nested func body inside @inlinable func body taking local type") // CHECK: "nested func body inside @inlinable func body taking local type"
}
takesInlinableLocalType(0)
}
@_transparent public func _transparentLocalTypeFunc() {
typealias TransparentLocalType = Int
_blackHole("@_transparent func body with local type") // CHECK: "@_transparent func body with local type"
func takesTransparentLocalType(_ x: TransparentLocalType) {
_blackHole("nested func body inside @_transparent func body taking local type") // CHECK: "nested func body inside @_transparent func body taking local type"
}
takesTransparentLocalType(0)
}
@inlinable
public func inlinableNestedLocalTypeFunc() {
func nestedFunc() {
_blackHole("nested func body inside @inlinable func body") // CHECK: "nested func body inside @inlinable func body"
typealias InlinableNestedLocalType = Int
func takesLocalType(_ x: InlinableNestedLocalType) {
_blackHole("nested func body inside @inlinable func body taking local type") // CHECK: "nested func body inside @inlinable func body taking local type"
}
takesLocalType(0)
}
nestedFunc()
}
public struct Struct {
@inlinable public var inlinableVar: Int {
_blackHole("@inlinable getter body") // CHECK: "@inlinable getter body"
return 0
}
@inlinable public func inlinableFunc() {
_blackHole("@inlinable method body") // CHECK: "@inlinable method body"
}
@inline(__always)
public func inlineAlwaysFunc() {
_blackHole("@inline(__always) method body") // CHECK-NOT: "@inline(__always) method body"
}
@_transparent public var transparentVar: Int {
_blackHole("@_transparent getter body") // CHECK: "@_transparent getter body"
return 0
}
public var inlinableSetter: Int {
get { 0 }
@inlinable set {
_blackHole("@inlinable setter body") // CHECK: "@inlinable setter body"
}
}
@_transparent
public func transparentFunc() {
_blackHole("@_transparent method body") // CHECK: "@_transparent method body"
}
func internalFunc() {
_blackHole("internal method body") // CHECK-NOT: "internal method body"
}
public func publicFunc() {
_blackHole("public method body") // CHECK-NOT: "public method body"
}
private func privateFunc() {
_blackHole("private method body") // CHECK-NOT: "private method body"
}
@_transparent public init(b: Int) {
_blackHole("@_transparent init body") // CHECK: "@_transparent init body"
}
@inlinable public init() {
_blackHole("@inlinable init body") // CHECK: "@inlinable init body"
}
@inline(__always) public init(a: Int) {
_blackHole("@inline(__always) init body") // CHECK-NOT: "@inline(__always) init body"
}
init(c: Int) {
_blackHole("internal init body") // CHECK-NOT: "internal init body"
}
public init(d: Int) {
_blackHole("public init body") // CHECK-NOT: "public init body"
}
private init(e: Int) {
_blackHole("private init body") // CHECK-NOT: "private init body"
}
@inlinable public subscript() -> Int {
_blackHole("@inlinable subscript getter") // CHECK: "@inlinable subscript getter"
return 0
}
@inline(__always) public subscript(a: Int, b: Int) -> Int {
_blackHole("@inline(__always) subscript getter") // CHECK-NOT: "@inline(__always) subscript getter"
return 0
}
public subscript(a: Int, b: Int, c: Int) -> Int {
@_transparent get {
_blackHole("@_transparent subscript getter") // CHECK: "@_transparent subscript getter"
return 0
}
}
subscript(a: Int, b: Int, c: Int, d: Int) -> Int {
_blackHole("internal subscript getter") // CHECK-NOT: "internal subscript getter"
return 0
}
public subscript(a: Int, b: Int, c: Int, d: Int, e: Int) -> Int {
_blackHole("public subscript getter") // CHECK-NOT: "public subscript getter"
return 0
}
private subscript(e: Int) -> Int {
_blackHole("private subscript getter") // CHECK-NOT: "private subscript getter"
return 0
}
@inline(__always) public var inlineAlwaysVar: Int {
_blackHole("@inline(__always) getter body") // CHECK-NOT: "@inline(__always) getter body"
return 0
}
public var publicVar: Int {
_blackHole("public getter body") // CHECK-NOT: "public getter body"
return 0
}
public var inlineAlwaysSetter: Int {
get { 0 }
@inline(__always) set {
_blackHole("@inline(__always) setter body") // CHECK-NOT: "@inline(__always) setter body"
}
}
public var regularSetter: Int {
get { 0 }
set {
_blackHole("@inline(__always) setter body") // CHECK-NOT: "regular setter body"
}
}
}