|
3 | 3 | * Proposal: [SE-NNNN](NNNN-inline-always.md)
|
4 | 4 | * Authors: [Arnold Schwaighofer](https://github.com/aschwaighofer)
|
5 | 5 | * Implementation: [swiftlang/swift#84178](https://github.com/swiftlang/swift/pull/84178)
|
| 6 | +* Pitch thread: https://forums.swift.org/t/pitch-inline-always-attribute/82040 |
6 | 7 |
|
7 | 8 | ## Introduction
|
8 | 9 |
|
@@ -149,18 +150,55 @@ be possible?
|
149 | 150 |
|
150 | 151 | ### Interaction with `@inlinable`
|
151 | 152 |
|
152 |
| -Function bodies of functions referenceable outside of the defining module are |
153 |
| -only available to the outside module if the definition is marked `@inlinable`. |
154 |
| - |
155 |
| -Therefore, a function marked with `@inline(always)` must be marked `@inlinable` |
156 |
| -if it has `open`, `public`, or `package` level access. |
| 153 | +`@inlinable` and `@_alwaysEmitIntoClient` make the function body available to |
| 154 | +clients (callers in other modules) in library evolution mode. `@inlinable` makes |
| 155 | +the body of the function available to the client and causes an ABI entry point |
| 156 | +in the vending module to vended. `@_alwaysEmitIntoClient` makes the body of the |
| 157 | +function available for clients but does not cause emission of an ABI entry |
| 158 | +point. Functions with `open`, `public`, or `package` level access cause emission |
| 159 | +of an ABI entry point for clients to call but in the absence of aforementioned |
| 160 | +attributes do not make the body available to the client. |
| 161 | + |
| 162 | +`@inline(always)` intention is to be able to guarantee that inlining will happen |
| 163 | +for any caller inside or outside the defining module therefore it makes sense to |
| 164 | +require the use some form of "inline-ability" attribute with them. This |
| 165 | +attribute could be required to be explicitly stated. And for it to be an error |
| 166 | +when the attribute is omitted. |
157 | 167 |
|
158 | 168 | ```swift
|
| 169 | +@inline(always) |
| 170 | +@inlinable // or @_alwaysEmitIntoClient |
| 171 | +public func caller() { ... } |
| 172 | + |
159 | 173 | @inline(always) // error: a public function marked @inline(always) must be marked @inlinable
|
160 | 174 | public func callee() {
|
161 | 175 | }
|
162 | 176 | ```
|
163 | 177 |
|
| 178 | +Alternatively, the attribute could be implicitly implied by the usage of |
| 179 | +`@inline(always)`. In this proposal, we take the position that it should be |
| 180 | +implied to avoid the redundancy of spelling this out. The intention of |
| 181 | +`@inline(always)` is for it to inline in all contexts. Instead of an error in the |
| 182 | +absence of the attribute we should imply "inline-ability". The question is what |
| 183 | +should we default to? |
| 184 | + |
| 185 | +`@_alwaysEmitIntoClient`'s semantics seems preferable for new functions. We |
| 186 | +intend for the function to be always inlined, why should there be an ABI entry |
| 187 | +point? |
| 188 | + |
| 189 | +`@inlinable` semantics allows for annotating existing functions with |
| 190 | +`@inline(always)` without breaking ABI compatibility. `@inlinable` keeps an |
| 191 | +entry point in the vending module for older code that assumed the existence of |
| 192 | +an entry point. |
| 193 | + |
| 194 | +This proposals takes the position to give `@inline(always)` the semantics of |
| 195 | +`@inlineable` and provide an alternative spelling for the case when we desire |
| 196 | +`@_alwaysEmitIntoClient` semantics: `@inline(only)`. |
| 197 | + |
| 198 | +For access levels equal and lower than `internal` `@inlinable` should not be |
| 199 | +implied. |
| 200 | + |
| 201 | + |
164 | 202 | ### Interaction with `@usableFromInline`
|
165 | 203 |
|
166 | 204 | A `public` `@inlinable` function can reference a function with `internal` access
|
@@ -297,7 +335,9 @@ changes to inlining heuristic).
|
297 | 335 |
|
298 | 336 | ## ABI compatibility
|
299 | 337 |
|
300 |
| -The addition of the attribute has no effect on ABI compatibility. |
| 338 | +The addition of the attribute has no effect on ABI compatibility. We chose to |
| 339 | +imply `@inlinable` for `public` (et al.) declarations which will continue to |
| 340 | +emit an entry point for existing binary clients. |
301 | 341 |
|
302 | 342 | ## Implications on adoption
|
303 | 343 |
|
@@ -342,6 +382,11 @@ This would deliver less predictable optimization behavior in cases where authors
|
342 | 382 | overlooked requirements for inlining to happen such as not marking a public
|
343 | 383 | function as `@inlinable`.
|
344 | 384 |
|
| 385 | +With respect to `@inlinable` an initial draft of the proposal suggested to |
| 386 | +require spelling the `@inlinable` attribute on `public` declarations or an error |
| 387 | +would be displayed. The argument was that this would ensure that authors would |
| 388 | +be aware of the additional semantics implied by the attribute: the body is |
| 389 | +exposed. |
345 | 390 |
|
346 | 391 | ## Acknowledgments
|
347 | 392 |
|
|
0 commit comments