Skip to content

Aggressive CMO can force the serialization of the bodies of @export(interface) functions#88446

Open
DougGregor wants to merge 3 commits intoswiftlang:mainfrom
DougGregor:code-generation-model
Open

Aggressive CMO can force the serialization of the bodies of @export(interface) functions#88446
DougGregor wants to merge 3 commits intoswiftlang:mainfrom
DougGregor:code-generation-model

Conversation

@DougGregor
Copy link
Copy Markdown
Member

@DougGregor DougGregor commented Apr 13, 2026

  • Explanation: Aggressive Cross-Module Optimization (and the variant of it used in Embedded Swift) mark additional functions as serialized. However, it does not respect @export(interface) as introduced by SE-0497, causing those function definitions to be serialized if they're needed by other serialized functions. Make CMO honor @export(interface).
  • Scope: This change centralizes the logic for determining the code generation model to use for a function, which can be @export(interface), @export(implementation), @inlineable, or the default, and extends the SIL function definition to include these options as well. This ensures that (1) we have more consistent computation of this information, and (2) it is always available to CMO, even after deserialization.
  • Issues: rdar://174749515
  • Risk: Low-to-moderate risk, because it does centralize all "always emit into client" checks in the compiler. It's plausible that there is an edge case that will change behavior in a manner that causes a build breakage.
  • Testing: Tests updated to ensure that the attributes propagate to SIL and the right definitions are serialized (or not).

… & SIL

For a given function, we might end up emitting it's definition as
object code, serialized SIL, or both. The @export, @inlinable, and
@inline(always) attributes provide control of this behavior at the
declaration level.

Centralize the query function that will look for each of these
attributes and map down to a specific "code generation model", whose 3
options follow the naming from SE-0497: interface, inlinable, and
implementation. Use this one computation to back the queries for
"always emit into client", "never emit into client", and "inlinable"
so we can't get inconsistent results from places that are doing
one-off checks for these attributes.
@DougGregor
Copy link
Copy Markdown
Member Author

@swift-ci please smoke test

…ctions

The `@export(interface)` and `@export(implementation)` attributes
SE-0497 are queried directly on AST nodes in several places within the
SIL pipeline. However, they don't persist when SIL functions are
serialized, meaning that clients of the original module might make
different assumptions about the availability of a given function's
definition.

Represent these attributes in a SIL function (as an optional
CodeGenerationModel), (de-)serialize them into the module, and add a
textual representation as SIL function attributes `[export_interface]`
and `[export_implementation]`.
@DougGregor
Copy link
Copy Markdown
Member Author

@swift-ci please test

@DougGregor DougGregor marked this pull request as ready for review April 14, 2026 16:19
@DougGregor DougGregor requested a review from a team as a code owner April 14, 2026 16:19
@DougGregor DougGregor changed the title Code generation model Aggressive CMO can force the serialization of the bodies of @export(interface) functions Apr 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant