4 min read
📟 What is Bitcode?

If you’ve ever wondered how your code transforms from human-readable text into something your iPhone can execute, you’re about to discover a fascinating intermediate step that Apple has cleverly leveraged for years.

⛰️ The Compilation Challenge

Most developers know the basic story: write code in a programming language, then use a compiler to turn it into machine-executable code. But the reality is more complex.

We live in a world of many programming languages and many processor architectures. The Intel processor in your Mac speaks a different machine code dialect than the ARM processor in your iPhone. In theory, you could write a separate compiler for every language-processor combination, but that would mean building hundreds of different compilers—and compiler development is notoriously difficult.

🧩 The Frontend-Backend Solution

Smart compiler developers solved this by creating a two-part system:

  • Frontends: Each reads one programming language
  • Backends: Each writes machine code for one processor architecture

Want a C compiler for Intel processors? Simply connect your C frontend to your Intel backend. This modular approach dramatically reduces the complexity of supporting multiple languages and architectures.

⚙️ LLVM and Bitcode

Apple’s compiler, LLVM, takes this concept to its logical extreme with exceptional design. LLVM introduces an intermediate representation called bitcode—essentially machine code for an imaginary, idealized processor.

Here’s how it works:

  1. Frontend compiles your Swift/Objective-C code to bitcode
  2. Optimization passes read bitcode and output improved bitcode
  3. Backend converts bitcode to actual machine code for your target processor

This design is brilliant because optimizations written once can benefit all languages and all processor architectures. An optimization that speeds up C code automatically speeds up Swift code too.

 Why Bitcode Matters for iOS

At WWDC 2015, Apple announced they would accept bitcode submissions to the App Store instead of fully compiled machine code. This decision unlocked powerful capabilities:

Not for processor switching: Despite initial speculation, bitcode won’t enable Apple to suddenly switch iPhone processors from ARM to Intel. The frontend still bakes in processor-specific details about memory layout and special features.

For incremental improvements: The real power lies in rolling out processor enhancements to existing apps. Consider this example: early iPhones lacked a “divide integer” instruction, forcing compilers to generate slow, multi-step division code. When the iPhone 5 introduced hardware integer division, developers had to recompile and resubmit their apps to benefit.

With bitcode, Apple could have automatically recompiled all App Store apps to use the new instruction, instantly speeding up every app without any developer effort.

✨ The Apple Advantage

This capability requires controlling the entire stack: processors, compilers, App Store, and devices. Apple is uniquely positioned to execute this strategy, while platforms like Android would require coordination between multiple companies.

Apple proved bitcode’s value in 2018 when they released 64-bit Apple Watches. They automatically recompiled existing 32-bit watch apps using a new “arm64_32” mode specifically designed to work with 32-bit bitcode—a seamless transition that required zero developer intervention.

Bitcode exemplifies Apple’s integrated approach: by controlling the full technology stack, they can deliver improvements that would be impossible in fragmented ecosystems.