LLVM is not a single compiler, but a collection of modular and reusable compiler and toolchain technologies. For a compiler engineer, its value lies in its strict separation of concerns, allowing you to build a language frontend that compiles to a universal Intermediate Representation (IR), letting LLVM handle the heavy lifting of target independent optimization and target specific machine code generation.
1. The Three Phase Architecture
LLVM enforces a strict three phase design:
1. Frontend: Parses source code, performs semantic analysis, builds an Abstract Syntax Tree (AST), and generates LLVM IR. (e.g., Clang for C/C++, Rustc for Rust, Zig's compiler).
2. Optimizer (Middle End): Takes LLVM IR, applies a series of target independent optimizations (passes) to improve runtime performance or reduce code size, and outputs optimized LLVM IR.
3. Backend (Code Generator): Takes the optimized LLVM IR and lowers it to target specific assembly code or machine code (e.g., x86 64, ARM, RISC V, WebAssembly).
2. LLVM Intermediate Representation (IR)
The heart of LLVM is its IR. It is a strictly typed, Static Single Assignment (SSA) based representation. Every variable is assigned exactly once, making data flow analysis trivial for optimization passes.