编译器进阶
可视化实验室
以 8 个交互式 SVG 模块,将编译器从中间表示到代码生成的核心阶段逐一拆解:寄存器分配的图着色、指令调度的数据依赖、循环与全局优化、JIT 内联、别名分析直至指令选择与 Phase Ordering —— 全部可在浏览器中实时驱动。
中间表示 IR
同一段程序在编译器内部以不同抽象层级存在:高层 IR(HIR)贴近源码语义,中层 IR(MIR)面向优化,SSA 引入 φ 节点保证单赋值,规范 IR 则为后续阶段统一形式。切换层级观察表示如何逐步精炼。
寄存器分配 Register Allocation
把无限虚拟寄存器映射到有限的物理寄存器。图着色将冲突图着色,相邻节点异色;线性扫描按活跃区间顺序分配,更快但次优。当寄存器不足时,部分活跃区间被 Spill 到栈内存。
指令调度 Instruction Scheduling
重排指令以填充流水线空隙。列表调度按优先级(关键路径优先)将就绪指令逐周期发射;VLIW 则把多条无依赖指令打包到同一指令字并行执行。数据依赖(RAW)必须被保留。
循环优化 Loop Optimization
循环是性能关键。展开(Unroll)复制循环体减少分支开销并暴露指令级并行;向量化(Vectorization)把标量运算提升为 SIMD;Loop Fusion 合并相邻循环减少迭代开销与提升数据局部性。
全局优化 Global Optimization
跨越基本块的数据流分析。常量传播沿控制流前向传播已知常量;死代码消除删除结果未被使用的指令;部分冗余消除(PRE)把在部分路径上重复计算的表达式上提,使每条路径只算一次。
内联与特化 Inlining & JIT
内联把被调函数体复制到调用点,消除调用开销并暴露跨函数优化;特化针对已知参数生成定制版本。JIT 在运行时按热点分层编译:解释器 → 基线 JIT → 优化 JIT,并支持基于类型反馈的去优化。
别名分析 Alias Analysis
判断两个内存访问是否指向同一对象。TBAA(基于类型的别名分析)按类型层级保守判断;流敏感分析结合程序点精确追踪指针指向集合。消歧越准,越能删除冗余加载、重排内存操作。
代码生成 Code Generation
把规范 IR 降低为目标机指令。指令选择用树覆盖模式匹配最优指令;窥孔优化在局部窗口做模式改写(如强度削减、合并);Phase Ordering 关注各优化遍的先后顺序如何影响最终代码质量。