5.2 · Devirtualisation, whole-module optimisation, inlining, exclusivity
What the Swift compiler can prove about your code decides how fast it runs. These questions are about what it needs to know, and how to see whether it managed.
Mental model. The optimiser can only do what it can prove. Every keyword that limits what a call could mean (final, private, a whole-module build) gives it a proof.
Proving a call is direct
Devirtualisation, and why the whole module matters.
- What is devirtualisation, and why does -O alone not remove a class method’s vtable lookup?
Devirtualisation replaces an indirect call (a vtable class_method or a witness-table lookup) with a direct one, which can then be inlined. To do it the… - What does whole-module optimisation change, and what does it cost?
Normally the compiler works per file (often in parallel), knowing about other files only through their declarations. WMO (-wmo, the Release default in Xcode…
Inlining and access rules
When a call disappears, and the exclusivity checks that cost you.
- How does the inliner decide, and what do @inline(never), @inline(__always) and @inlinable do?
The SIL inliner replaces a call with the callee’s body when its cost model says that is a win: small bodies, a body that becomes simpler once its arguments are… - What is exclusivity enforcement, and what does it cost at runtime?
Swift requires that a variable is not accessed in two overlapping ways when one of them is a modification: you cannot pass &x twice to a function with two…
More in Compiler & language internals
- 5.1 · From source to machine code, and how to look inside
- 5.3 · Specialisation, witness tables, and opaque vs existential in the compiled code
- 5.4 · Library evolution, module interfaces, and the ABI boundary
- 5.5 · How Swift macros work, and the roles they play
- 5.6 · Why it compiles slowly, and what rebuilds
- 5.7 · Swift 6 language mode and upcoming features
- 5.8 · Symbol names, linkage, lazy globals and reflection metadata: what is in the binary
- 5.9 · Optimisation levels, closure contexts, ownership conventions and value layout
- 5.10 · What property wrappers, result builders, async and throws compile to
- 5.11 · Package access, SPI, internal imports, strict memory safety and pre-specialisation