mobile wallpaper 1mobile wallpaper 2mobile wallpaper 3mobile wallpaper 4
3633 字
10 分钟
系列导读
2026-03-24

系列简介#

编译器是软件开发的基础设施——你写的每一行代码,都要经过编译器的翻译才能变成机器能执行的指令。然而,大多数开发者对编译器的理解停留在 gcc main.ccargo build 的层面:输入源码,输出可执行文件,中间发生了什么?黑盒。

本系列就是要打开这个黑盒。从编译器的前端(词法分析、语法分析、语义分析)出发,经过中间表示(IR、SSA)和优化(常量折叠、循环优化、寄存器分配),到达后端(指令选择、代码生成、链接),然后深入三大工业级编译器基础设施(LLVM、V8、Go/Rust 编译器),最后探索前沿方向(WASM、AI 驱动优化)和综合实战。

每一章都配有可运行的 Python/C/LLVM IR 代码实验,让你不仅知道”是什么”,更理解”为什么”。

系列定位#

  • 不是:编译原理教科书(不会用大量数学推导折磨你)
  • 不是:LLVM 源码解读(不会逐行分析 C++ 代码)
  • :从原理到实践的编译器深入指南——理解每个阶段的设计动机核心算法工程权衡
  • :连接前端与后端、连接理论与实践的桥梁

场景驱动阅读路线#

不想按部就班地从第 1 章读到第 19 章?没问题。以下 5 条路线从你日常遇到的真实问题出发,按”你需要什么→编译器怎么实现”的顺序串联章节。每条路线可独立阅读,前置依赖已在路线内标注。

路线总览#

flowchart TB subgraph 路线A[" 路线A:我想写一个编程语言"] A1[Ch1 编译器全景] --> A2[Ch2 词法分析] A2 --> A3[Ch3 语法分析] A3 --> A4[Ch4 语义分析] A4 --> A5[Ch5 中间表示] A5 --> A6[Ch19 综合实战] end subgraph 路线B[" 路线B:我的程序为什么慢——编译优化视角"] B1[Ch1 编译器全景] --> B2[Ch5 中间表示] B2 --> B3[Ch6 优化基础] B3 --> B4[Ch7 循环优化] B4 --> B5[Ch8 寄存器分配] B5 --> B6[Ch11 LLVM架构] end subgraph 路线C[" 路线C:深入工业级编译器"] C1[Ch1 编译器全景] --> C2[Ch5 中间表示] C2 --> C3[Ch11 LLVM架构] C3 --> C4[Ch12 JIT编译] C4 --> C5[Ch14 V8引擎] C5 --> C6[Ch15 Go编译器] end subgraph 路线D[" 路线D:内存安全与运行时"] D1[Ch1 编译器全景] --> D2[Ch4 语义分析] D2 --> D3[Ch13 垃圾回收] D3 --> D4[Ch16 Rust编译器] D4 --> D5[Ch15 Go编译器] end subgraph 路线E[" 路线E:从源码到可执行文件的完整旅程"] E1[Ch1 编译器全景] --> E2[Ch2 词法分析] E2 --> E3[Ch9 指令选择与调度] E3 --> E4[Ch10 代码生成与链接] E4 --> E5[Ch17 WASM编译] E5 --> E6[Ch18 AI与编译优化] end style 路线A fill:#e3f2fd,stroke:#1565c0 style 路线B fill:#e8f5e9,stroke:#2e7d32 style 路线C fill:#fff3e0,stroke:#e65100 style 路线D fill:#fce4ec,stroke:#c62828 style 路线E fill:#f3e5f5,stroke:#6a1b9a

路线A:我想写一个编程语言#

场景:你有一个新语言的 idea,想从零开始实现——词法分析器怎么写?语法分析用 LL 还是 LR?类型检查怎么做?如何生成可执行代码?

顺序章节为什么读这章
1Ch1 编译器全景建立编译器整体架构认知——前端、优化、后端三段式
2Ch2 词法分析从字符流到 Token 流——手工编写 vs 工具生成
3Ch3 语法分析从 Token 流到 AST——递归下降 vs LR 分析
4Ch4 语义分析类型检查与作用域解析——让 AST 具备语义
5Ch5 中间表示IR 设计与 SSA 构造——连接前端与后端的桥梁
6Ch19 综合实战端到端构建一个迷你编程语言——综合运用前 5 章知识

路线逻辑:按照编译器的流水线顺序,从源码输入到代码输出,逐步构建你的语言实现能力。


路线B:我的程序为什么慢——编译优化视角#

场景:你的 C/C++/Rust 程序运行缓慢,-O2-O3 有什么区别?循环为什么没有被向量化?寄存器溢出是怎么回事?如何读懂 LLVM 优化 Pass 的输出?

顺序章节为什么读这章
1Ch1 编译器全景理解编译优化在编译流水线中的位置
2Ch5 中间表示SSA 是所有优化的基础——理解 def-use 链
3Ch6 优化基础常量传播、死代码消除、公共子表达式消除
4Ch7 循环优化循环展开、向量化、不变量外提——性能提升的关键
5Ch8 寄存器分配图着色 vs 线性扫描——理解溢出的代价
6Ch11 LLVM架构Pass 框架与优化流水线——如何自定义优化

路线逻辑:从理解 IR 和 SSA 开始,逐步深入各类优化技术,最后掌握 LLVM 的优化框架。


路线C:深入工业级编译器#

场景:你想理解 V8 如何让 JavaScript 飞起来、Go 编译器为什么编译这么快、LLVM 的 Pass 框架如何工作、JIT 编译的懒编译策略是什么。

顺序章节为什么读这章
1Ch1 编译器全景AOT vs JIT 的设计权衡
2Ch5 中间表示LLVM IR 是工业级 IR 的标杆
3Ch11 LLVM架构核心:Pass 框架、IR 层次、后端代码生成
4Ch12 JIT编译运行时代码生成——ORC API、懒编译、内联缓存
5Ch14 V8引擎Ignition + TurboFan 双层架构——JIT 的工程实践
6Ch15 Go编译器编译速度优先的设计哲学——逃逸分析与 GC 协作

路线逻辑:先掌握 LLVM 这一基础设施,再理解 JIT 编译原理,然后深入 V8 和 Go 两个工业级实现。


路线D:内存安全与运行时#

场景:你想理解 Rust 的借用检查器如何在编译期保证内存安全、Go 的 GC 如何与编译器协作、垃圾回收的三色标记算法如何工作。

顺序章节为什么读这章
1Ch1 编译器全景编译期检查 vs 运行时检查的设计空间
2Ch4 语义分析类型系统是内存安全的基础——静态类型 vs 动态类型
3Ch13 垃圾回收核心:引用计数、标记-清除、分代 GC、三色标记
4Ch16 Rust编译器借用检查器 + 生命周期 + MIR——编译期内存安全
5Ch15 Go编译器逃逸分析决定堆/栈分配——编译器与 GC 的接口

路线逻辑:从类型系统出发,理解内存安全的理论基础,然后对比 GC(运行时安全)和 Rust(编译期安全)两种路径。


路线E:从源码到可执行文件的完整旅程#

场景:一个 .c 文件如何变成可执行的 ELF?链接器做了什么?WASM 是如何编译的?AI 能否自动优化编译?

顺序章节为什么读这章
1Ch1 编译器全景编译流水线全貌——从源码到机器码
2Ch2 词法分析源码的第一步转换——字符流到 Token 流
3Ch9 指令选择与调度IR 如何映射到目标机器指令
4Ch10 代码生成与链接核心:ELF 格式、重定位、符号解析、动态链接
5Ch17 WASM编译编译到 Web——WASM 字节码、Cranelift、WASI
6Ch18 AI与编译优化MLGO、AutoTVM——AI 驱动的编译优化前沿

路线逻辑:沿着编译流水线走完全程,从源码入口到可执行文件输出,再扩展到 WASM 和 AI 优化。


路线交叉参考#

同一章节在不同路线中的关注点不同:

章节路线A 关注点路线B 关注点路线C 关注点路线D 关注点路线E 关注点
Ch1前端-优化-后端三段式优化在流水线中的位置AOT vs JIT编译期 vs 运行时检查编译流水线全貌
Ch2手写词法分析器源码第一步转换
Ch4类型检查实现类型系统与安全
Ch5IR 设计SSA 与优化基础LLVM IR
Ch6常量传播/死代码消除
Ch7循环展开/向量化
Ch8图着色/溢出
Ch9指令映射
Ch10ELF/链接/重定位
Ch11Pass 框架核心章节
Ch12JIT 原理
Ch13核心章节
Ch14TurboFan+Ignition
Ch15Go 编译速度逃逸分析+GC
Ch16借用检查器
Ch17WASM 编译
Ch18AI 优化前沿
Ch19核心章节

知识导图#

以下导图展示 19 章知识之间的网络关系。与线性目录不同,这里强调跨阶段的连接——一个类型检查器同时牵动语义分析和内存安全;一个 SSA 构造同时服务于优化和寄存器分配。

概念关系图#

graph TB subgraph 前端[" 编译器前端 — 源码理解"] LEX["词法分析<br/>Ch2"] SYN["语法分析<br/>Ch3"] SEM["语义分析<br/>Ch4"] end subgraph 中端[" 编译器中端 — IR 与优化"] IR["中间表示<br/>Ch5"] OPT["优化基础<br/>Ch6"] LOOP["循环优化<br/>Ch7"] REG["寄存器分配<br/>Ch8"] end subgraph 后端[" 编译器后端 — 代码生成"] ISEL["指令选择<br/>Ch9"] CG["代码生成与链接<br/>Ch10"] end subgraph 工业实现[" 工业级实现"] LLVM["LLVM 架构<br/>Ch11"] JIT["JIT 编译<br/>Ch12"] GC["垃圾回收<br/>Ch13"] V8["V8 引擎<br/>Ch14"] GO["Go 编译器<br/>Ch15"] RUST["Rust 编译器<br/>Ch16"] end subgraph 前沿[" 前沿方向"] WASM["WASM 编译<br/>Ch17"] AI["AI 编译优化<br/>Ch18"] end subgraph 实战[" 综合实战"] PRACTICE["构建迷你语言<br/>Ch19"] end LEX --> SYN --> SEM --> IR IR --> OPT --> LOOP IR --> REG LOOP --> ISEL --> CG REG --> ISEL IR --> LLVM --> JIT LLVM --> V8 LLVM --> GO SEM --> RUST SEM --> GC GC --> V8 GC --> GO CG --> WASM LLVM --> AI OPT --> AI LEX --> PRACTICE SYN --> PRACTICE SEM --> PRACTICE IR --> PRACTICE style 前端 fill:#e8eaf6,stroke:#283593 style 中端 fill:#e0f2f1,stroke:#00695c style 后端 fill:#fff3e0,stroke:#e65100 style 工业实现 fill:#fce4ec,stroke:#880e4f style 前沿 fill:#f3e5f5,stroke:#6a1b9a style 实战 fill:#e8f5e9,stroke:#2e7d32

章节网络关系图#

graph LR Ch0["Ch0 导读"] --> Ch1["Ch1 全景"] Ch1 --> Ch2["Ch2 词法分析"] Ch1 --> Ch5["Ch5 中间表示"] Ch1 --> Ch13["Ch13 垃圾回收"] Ch2 --> Ch3["Ch3 语法分析"] Ch3 --> Ch4["Ch4 语义分析"] Ch4 --> Ch5 Ch4 --> Ch16["Ch16 Rust"] Ch5 --> Ch6["Ch6 优化基础"] Ch5 --> Ch8["Ch8 寄存器分配"] Ch5 --> Ch11["Ch11 LLVM"] Ch6 --> Ch7["Ch7 循环优化"] Ch6 --> Ch18["Ch18 AI优化"] Ch7 --> Ch9["Ch9 指令选择"] Ch8 --> Ch9 Ch9 --> Ch10["Ch10 代码生成"] Ch10 --> Ch17["Ch17 WASM"] Ch11 --> Ch12["Ch12 JIT"] Ch11 --> Ch14["Ch14 V8"] Ch11 --> Ch15["Ch15 Go"] Ch12 --> Ch14 Ch13 --> Ch14 Ch13 --> Ch15 Ch2 --> Ch19["Ch19 实战"] Ch3 --> Ch19 Ch4 --> Ch19 Ch5 --> Ch19 style Ch0 fill:#bbdefb,stroke:#1565c0 style Ch5 fill:#c8e6c9,stroke:#2e7d32 style Ch11 fill:#fff9c4,stroke:#f9a825 style Ch13 fill:#ffe0b2,stroke:#e65100 style Ch19 fill:#ffcdd2,stroke:#c62828

知识关联参考表#

用户可见概念对应章节编译器机制对应章节共享基础对应章节
gcc -O2 编译优化Ch6常量传播 + 死代码消除Ch6SSA def-use 链Ch5
循环自动向量化Ch7SIMD 指令生成Ch7依赖分析与别名分析Ch6
Rust 所有权检查Ch16借用检查器 + 生命周期Ch16类型系统与语义分析Ch4
Go 编译速度极快Ch15简化前端 + 无泛型优化Ch15递归下降解析Ch3
V8 JIT 热点优化Ch14Ignition + TurboFanCh14内联缓存 + 类型反馈Ch12
Java/C# GC 暂停Ch13分代 GC + 写屏障Ch13三色标记不变式Ch13
WASM 跨平台运行Ch17字节码验证 + CraneliftCh17指令选择 + 代码生成Ch9, Ch10
链接错误 undefined referenceCh10符号解析 + 重定位Ch10ELF 格式与段Ch10
clang -emit-llvm 输出 IRCh11LLVM IR 生成Ch11SSA 构造Ch5
MLGO 自动优化策略Ch18强化学习 + 编译特征Ch18优化 Pass 框架Ch11

系列大纲#

以下是按章节编号排列的完整目录。建议结合上方的场景驱动阅读路线知识导图选择适合你的阅读顺序。

章节标题核心内容
0系列导读系列定位、场景路线、知识导图、环境搭建
1编译器全景编译器 vs 解释器 vs JIT、三段式架构、编译流水线
2词法分析正则表达式 → NFA → DFA、手工词法分析器、Token 设计
3语法分析LL/LR/递归下降、AST 设计、算符优先、错误恢复
4语义分析类型检查、符号表、作用域、类型推导
5中间表示IR 层次、SSA 构造、基本块、控制流图、LLVM IR
6优化基础常量折叠/传播、死代码消除、公共子表达式、值编号
7循环优化循环展开、向量化、不变量外提、强度消减
8寄存器分配图着色、线性扫描、溢出处理、合并
9指令选择与调度DAG 覆盖、TableGen、指令调度、流水线
10代码生成与链接ELF 格式、重定位、符号解析、动态链接
11LLVM 架构深入Pass 框架、IR 层次、后端 Pipeline、调试信息
12JIT 编译ORC API、懒编译、内联缓存、Speculation
13垃圾回收引用计数、标记-清除、分代 GC、三色标记、写屏障
14V8 引擎深入Ignition、TurboFan、内联缓存、隐藏类
15Go 编译器深入编译流程、逃逸分析、Go GC、调度器与编译器协作
16Rust 编译器与借用检查器借用检查器、MIR、生命周期、HIR → MIR → LLVM IR
17WebAssembly 编译WASM 字节码、Cranelift、WASI、浏览器编译流水线
18AI 驱动的编译优化MLGO、AutoTVM、TVM、编译特征、强化学习
19综合实战端到端构建一个迷你编程语言

开发环境搭建#

Python 环境(前端实验)#

本系列前端的词法分析、语法分析、语义分析实验使用 Python 3.10+ 实现:

# 确认 Python 版本
python3 --version # 需要 3.10+
# 安装依赖
pip3 install lark-parser graphviz
# 可选:安装 ANTLR4 Python 运行时
pip3 install antlr4-python3-runtime

LLVM 环境(后端实验)#

# Ubuntu/Debian
sudo apt install llvm llvm-dev clang lld
# macOS
brew install llvm
# 确认版本(需要 LLVM 15+)
llvm-config --version
clang --version
# 查看 LLVM IR 输出
clang -emit-llvm -S -o - hello.c

C/C++ 编译工具链#

# 安装 GCC 和构建工具
sudo apt install build-essential gcc g++ make cmake
# 安装 binutils(包含 objdump、readelf、nm 等工具)
sudo apt install binutils
# 查看 ELF 文件
readelf -h a.out
objdump -d a.out
nm a.out

Rust 与 Go 环境#

# 安装 Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# 查看 Rust 中间表示
rustc --emit=mir hello.rs
rustc --emit=llvm-ir hello.rs
# 安装 Go
wget https://go.dev/dl/go1.22.0.linux-amd64.tar.gz
sudo tar -C /usr/local -xzf go1.22.0.linux-amd64.tar.gz
# 查看 Go 编译器 SSA 输出
GOSSAFUNC=main go build -o hello hello.go

WASM 环境#

# 安装 Emscripten(WASM 编译工具链)
git clone https://github.com/emscripten-core/emsdk.git
cd emsdk && ./emsdk install latest && ./emsdk activate latest
# 安装 WABT(WASM 二进制工具)
sudo apt install wabt
# 编译到 WASM
emcc hello.c -o hello.js
wasm2wat hello.wasm # 反汇编 WASM

本系列的实践方法论#

本系列遵循 理解原理 → 动手实现 → 工具验证 的学习方法:

  1. 理解原理:通过图解和伪代码理解算法的核心思想
  2. 动手实现:用 Python/C 手写核心算法的简化版本
  3. 工具验证:使用 LLVM/GCC/Rust/Go 等工具验证理解是否正确

每章的「动手实践」部分都遵循这一方法论,让你不仅知道”是什么”,更理解”为什么”。

开发环境搭建#

Warning

以下环境搭建步骤基于 Ubuntu 22.04 LTS。其他发行版的包名和路径可能不同,请参考各项目官方文档。编译器开发涉及大量 C/C++/Python 工具链,建议在虚拟机或 Docker 容器中操作。

编译器开发工具架构#

graph TB subgraph 词法分析["词法分析工具"] RE2["re2<br/>正则引擎"] FLEX["Flex<br/>词法生成器"] end subgraph 语法分析["语法分析工具"] BISON["Bison<br/>语法生成器"] ANTLR["ANTLR4<br/>多语言解析器"] end subgraph IR与优化["IR 与优化"] LLVM["LLVM 15+<br/>优化与代码生成"] GCC["GCC Plugin<br/>GIMPLE IR"] end subgraph 运行时["运行时工具"] V8DBG["V8 --allow-natives-syntax<br/>JIT 调试"] GDB["GDB + Python<br/>运行时调试"] end RE2 --> BISON FLEX --> BISON BISON --> LLVM ANTLR --> LLVM LLVM --> V8DBG LLVM --> GDB style 词法分析 fill:#e8eaf6,stroke:#283593 style 语法分析 fill:#e0f2f1,stroke:#00695c style IR与优化 fill:#fff3e0,stroke:#e65100 style 运行时 fill:#fce4ec,stroke:#880e4f

Python 编译器开发环境#

# 安装 Python 3.11+(推荐使用 pyenv)
curl https://pyenv.run | bash
pyenv install 3.11.5
pyenv global 3.11.5
# 安装编译器开发常用库
pip install lark-parser # 解析器组合子
pip install llvmlite # Python LLVM 绑定
pip install rpython # PyPy 的翻译工具链

LLVM 开发环境#

# 安装 LLVM 15(包含 clang、llc、opt 等工具)
sudo apt install llvm-15 llvm-15-dev clang-15 libpolly-15-dev
# 验证安装
llvm-as-15 --version
opt-15 --version
# 编译 LLVM Pass 示例
git clone https://github.com/llvm/llvm-project.git
cd llvm-project && mkdir build && cd build
cmake -G Ninja -DLLVM_ENABLE_PROJECTS=clang -DCMAKE_BUILD_TYPE=Release ../llvm
ninja -j$(nproc)
Note

LLVM 从源码编译需要约 30GB 磁盘空间和 16GB+ 内存。如果资源有限,可以使用预编译的二进制包(apt install llvm-15-dev),或使用 Docker 镜像 silkeh/clang

推荐参考资料#

经典教材#

书籍作者特点
《Crafting Interpreters》Robert Nystrom手写两个完整解释器,实践性极强,适合入门
《Engineering a Compiler》Keith D. Cooper 等工程视角,算法清晰,适合深入
《编译原理》(龙书)Alfred V. Aho 等理论权威,数学推导详尽,适合查阅
《LLVM Cookbook》Mayur Pandey 等LLVM 实践指南,Pass 开发详解
《GC Handbook》Richard Jones 等垃圾回收的百科全书
《Programming Language Pragmatics》Michael L. Scott语言设计视角,广度与深度兼备

在线资源#

实用工具#

  • Compiler Explorer (Godbolt):在线对比不同编译器的输出,无需本地安装
  • LLVM opt:运行单个优化 Pass,观察 IR 变化
  • clang -emit-llvm:生成 LLVM IR,理解前端到中端的转换
  • readelf / objdump:分析 ELF 文件结构,理解链接过程
  • wasm2wat:WASM 二进制反汇编为 WAT 文本格式

准备好开始了吗?从 编译器全景 开始你的编译器深入之旅吧!


参考#

支持与分享

如果这篇文章对你有帮助,欢迎支持作者或分享给更多人

系列导读
https://blog.souloss.com/posts/compiler/compiler-series-guide/
作者
Souloss
发布于
2026-03-24
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时