后端Pass简介——MachineCombiner
MachineCombiner
一个基于机器级 trace 度量,将多条指令合并为更高效指令序列的 LLVM 机器指令合并优化 Pass。对应的中端 Pass 就是 InstCombiner。但是该 Pass 的逻辑比较简单,只有六百多行。
基本概念如下:
- 目标:在不延长关键路径、不增加资源压力(或优化代码体积)的前提下,将可组合的指令序列(如 MUL+ADD)替换为单条复合指令(如 MADD),以提高生成代码的执行效率或减小代码体积。
- 依赖分析:利用 MachineTraceMetrics 提供的“深度(Depth)”、“延迟(Latency)”和“Slack”信息,评估新旧指令序列对关键路径的影响。
- 资源分析:基于调度模型(TSchedModel)和硬件资源模型,比较合并前后资源使用长度(Resource Length)。
- 启发式:优先尝试减少关键路径深度,再尝试减少资源长度;在代码大小优化模式下,只要新序列短即替换;在循环中若检测到吞吐模式也可替换。
最简单的例子就是一个 FMA 指令:
; 原始序列
MUL r1, r2, r3 ; 乘法
ADD r4, r1, r5 ; 加法(Root)
; 合并后
MADD r4, r2, r3, r5 ; 乘加复合指令
这个 Pass 也是可以调参的:
是的,通过命令行选项控制:
- -machine-combiner-inc-threshold=<N>:基本块指令数超过 N 时启用增量深度更新(默认为 500)。
- -machine-combiner-dump-subst-intrs:打印被删除与插入的指令序列以便调试。
- -machine-combiner-verify-pattern-order:开启后将验证所有模式按延迟改进程度升序排列,以检测子最优模式顺序。
// The motivating example is:
//
// MUL Other MUL_op1 MUL_op2 Other
// \ / \ | /
// ADD/SUB => MADD/MSUB
// (=Root) (=NewRoot)
该 Pass 依赖的分析还是比较多的:
- MachineLoopInfoWrapperPass
- MachineTraceMetricsWrapperPass
- ProfileSummaryInfoWrapperPass
- LazyMachineBlockFrequencyInfoPass
这个 TraceMetrics 是一个用于在后端收集机器指令级“静态执行轨迹”信息的分析 Pass,为后续的 MachineCombiner 等优化提供关键路径、延迟、Slack 和资源压力等度量。
主函数是combineInstructions,逻辑如下,在给定 MBB(机器基本块)中,对每条机器指令:
- 查询目标定义的指令组合模式;
- 枚举每种组合方式;
- 使用 TraceMetrics 判断是否可替换(不会恶化关键路径/资源);
- 若合适,则插入优化指令,删除原始序列。
评论