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.

  1. What is devirtualisation, and why does -O alone not remove a class method’s vtable lookup? 5.2.1 · L5
    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…
  2. What does whole-module optimisation change, and what does it cost? 5.2.2 · L5
    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.

  1. How does the inliner decide, and what do @inline(never), @inline(__always) and @inlinable do? 5.2.3 · L5
    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…
  2. What is exclusivity enforcement, and what does it cost at runtime? 5.2.4 · L5
    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