本节摘要:中间表示(Intermediate Representation,IR)是编译器在完成前端解析之后、生成目标代码之前所使用的一种内部程序形式,它既摆脱了源语言的具体语法,也不绑定任何目标指令集。本节给出 IR 的严格定义、用一笔"乘法对加法"的账说明它为什么是现代编译器架构的经济基础,并列出一条合格 IR 应满足的四条判据。IR 是本册的主角,此后所有章节的内容都发生在 IR 之上。
有了语法树,为什么不直接从语法树生成机器码,还要引入 IR?把这个问题想透,IR 的定义和地位就都清楚了。
支持 m 种源语言、n 种目标平台的编译器族,如果走"每对语言-平台直接翻译"的路线,需要写 m×n 个完整翻译器。每增加一种新语言,工作量是重写 n 个后端;每支持一种新芯片,要为所有语言各写一个代码生成器。1970 年代 IBM 的 PL/I 编译器就吃过这个亏:为几十种目标机各配后端,维护成本失控。
垫上 IR 之后,架构变成 m 个前端 + n 个后端,中间共享同一个 IR 及架在它上面的全部优化器。新增语言只需写一个前端,新增芯片只需写一个后端,优化器全线复用。LLVM 就是这个架构最成功的实现:Clang、Rustc、Swiftc、Julia 共享同一套 LLVM IR 与优化管线,同一套 x86/ARM/RISC-V 后端服务所有语言。

给定架构坐标之后,可以给 IR 下一个工作定义:IR 是编译器内部使用的一种程序表示,它对上屏蔽源语言的语法细节,对下不承诺任何具体机器的指令形态,并且被设计成便于机器分析与变换的形式。 这句定义里每个短语都在排除一种"伪 IR":源代码本身不行(绑定语法),汇编不行(绑定机器),普通文本不行(不利于分析)。
一条合格的 IR 至少要同时满足四条判据:
这四条判据互相牵制。语义无损与表达力会诱惑 IR 变得庞大臃肿,而分析友好要求表示精简规整;贴近机器利于后端,却伤害前端复用。IR 设计的全部艺术,都在这组张力里找平衡点。
IR 落定后,编译器有了清晰的三段式分工:
| 阶段 | 输入 | 输出 | 职责 | 关心什么 |
|---|---|---|---|---|
| 前端 | 源代码 | IR | 词法、语法、语义分析与 IR 生成 | 语言规则 |
| 中端 | IR | 更好的 IR | 机器无关的分析与优化 | 程序共性规律 |
| 后端 | IR | 机器码 | 指令选择、寄存器分配、调度 | 硬件特性 |
中端能独立存在,正是因为 IR 的存在——它不需要知道程序来自 C 还是 Rust,也不需要知道要跑在哪个芯片上。本册第3、4、5章讲的都是中端的事情;第6章进入后端;第7章在 LLVM 里把三段式完整走一遍。
⚠️ 一个常见误解是"IR 只是编译器内部的临时数据结构,理解语言特性才是重点"。事实恰好相反:工业编译器的核心投入几乎都在 IR 及其变换上。判断一个编译团队对某个新语言的支持深度,看它前端产出的 IR 质量比看它的语法兼容清单更准。
本节要点回顾:
问:为什么不直接从 AST 开始优化,非要再造一层 IR? AST 里全是语言的"礼貌":括号、语法糖、优先级包装节点。同一份 for 循环在 AST 里是语法结构,在三地址码里是"标号、比较、跳转"的控制流事实——后者才是数据流分析能下嘴的形状。AST 服务"程序写得对不对",IR 服务"程序跑得快不快",两份工作没法挤在一张结构上完成。
问:IR 会丢信息吗? 会,而且是有意丢:变量名可以丢(调试信息另行保存)、源码行号可以丢、部分类型信息可以丢。丢什么是 IR 设计的核心决策——丢多了优化失去依据,丢少了表示臃肿。LLVM 的选择是把调试信息做成附着在 IR 上的元数据,主表示保持精瘦;这个取舍让它既能全速优化,又能生成可断点的代码。
问:一门新语言接 LLVM,前端要写多少东西? 到 IR 为止:词法、语法、语义分析与 IR 生成。之后两三千个优化 pass、十几种目标芯片的后端全部白得——这就是本章开头那笔"乘法变加法"的账在开发者体验上的样子。反过来看,语言语义与 IR 的贴合度决定了前端的难易:函数式语言的尾调用、闭包,映射到 SSA 形 IR 就比映射到栈式机 IR 自然得多。选 IR 也是选语言的"得体翻译腔"。
问:IR 层面的"语义无损"怎么验证? 三条常用手段。差分测试最朴素:同一输入在优化前后两个可执行版本上跑,比对可观测行为;验证器是结构化的:SSA 合法性、支配一致性、类型闭合,机器随时检查;等价性检查器(学术界的Alive2 就是范例)把"变换前后语义等价"做成可判定的判定题,对每个改写规则自动找反例。三层防线各管一段——这是"变换封闭性"从设计判据落成工程实践的样子。
下一节沿"抽象层次"这条轴把 IR 家族摊开看,你会发现三地址码、SSA、MLIR 各自站在光谱的不同位置上。