编译流水线 Pass
设计目的(问题与语言特性)
前端
- SimplExpr(Csyntax → Clight)
- 目的:消除表达式副作用,保证 Clight 的“表达式无副作用”特性。
- 解决问题:短路、赋值表达式、volatile、bitfield 等语义展开。
- SimplLocals(Clight → Clight)
- 目的:提升未取地址的局部变量为临时变量。
- 解决问题:减少内存读写、便于后端分析与优化。
- Cshmgen(Clight → Csharpminor)
- 目的:显式化类型转换与内存访问。
- 解决问题:将结构体/联合体、bitfield、memcpy
等抽象语义转成明确操作。
- Cminorgen(Csharpminor → Cminor)
- 目的:显式栈布局与变量寻址。
- 解决问题:为后端指令选择准备显式地址与栈帧结构。
后端(RTL 阶段优化)
- Selection(Cminor → CminorSel)
- 目的:利用目标 ISA 的复合指令与寻址模式。
- 解决问题:将高层运算与内存访问映射为目标可识别模式。
- RTLgen(CminorSel → RTL)
- 目的:生成 CFG 形式的 RTL。
- 解决问题:结构化控制流 → 显式跳转图,便于数据流分析。
- Tailcall(RTL → RTL)
- 目的:识别尾调用,避免多余栈增长。
- 解决问题:符合条件的调用改为 tailcall。
- Inlining(RTL → RTL)
- 目的:消除调用开销,暴露更多优化机会。
- 解决问题:将小函数内联并调整 CFG、寄存器、栈偏移。
- Renumber(RTL → RTL)
- 目的:后序编号 CFG 节点,提高数据流分析精度。
- 解决问题:改善 Kildall 求解器的精度与收敛。
- Constprop(RTL → RTL)
- 目的:常量传播与强度削弱。
- 解决问题:减少冗余计算,提升后续 CSE/Deadcode 效果。
- CSE(RTL → RTL)
- 目的:公共子表达式消除。
- 解决问题:消除重复计算与重复 load(在别名安全条件下)。
- Deadcode(RTL → RTL)
- 目的:删除不影响语义的计算与赋值。
- 解决问题:清理无用寄存器结果与冗余指令。
- Unusedglob(RTL 程序级)
- 目的:删除未被引用的静态全局定义。
- 解决问题:减少程序体积,避免无用符号。
后端(寄存器/控制流/栈/汇编)
- Allocation(RTL → LTL)
- 目的:寄存器分配 + 验证。
- 解决问题:将伪寄存器映射到物理寄存器/栈槽,满足 ABI 约束。
- Tunneling(LTL → LTL)
- 目的:消除跳转到跳转的链。
- 解决问题:缩短控制流路径,减少不必要分支。
- Linearize(LTL → Linear)
- 目的:CFG 线性化。
- 解决问题:将图结构转为指令序列,显式标签与分支。
- CleanupLabels(Linear → Linear)
- 目的:删除未引用标签。
- 解决问题:简化线性代码,减少冗余。
- Debugvar(Linear → Linear)
- 目的:插入调试信息范围。
- 解决问题:记录变量生存期用于 DWARF 生成。
- Stacking(Linear → Mach)
- 目的:栈帧布局与保存/恢复。
- 解决问题:生成符合 ABI 的栈与调用约定实现。
- Asmgen(Mach → Asm)
- 目的:生成目标汇编指令。
- 解决问题:将 Mach 操作映射到 ISA 指令序列。
- Asmexpand(Asm → Asm)
- 目的:展开 builtin 与伪指令。
- 解决问题:补齐调试/ABI/平台细节,生成可汇编指令序列。