自动化与脚本
用 LLVM 工具链生成、优化、检查 IR…
当需要直接查看/生成 LLVM IR、用 opt 跑优化 pass、用 llc 降级到汇编,或排查某个优化(如自动向量化)为什么没生效时使用。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 49/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 85/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 60/100 ×0.15
适用场景
用 LLVM 工具链生成、优化、检查 I通用
解决思路
- 用 clang 生成 IR:`clang -O0 -emit-llvm -S src.c -o src.ll` 生成文本 IR(.ll);`clang -O2 -emit-llvm -c src.c -o src.bc` 生成 bitcode(.bc);用 `llvm-dis src.bc -o src.ll` 把 bitcode 反汇编成文本 IR。
- 用 opt 施加指定优化 pass:`opt -passes='mem2reg,instcombine,simplifycfg' src.ll -S -o out.ll`;跑标准流水线用 `opt -passes='default<O2>' src.ll -S -o out.ll` 或 `default<O3>`;用 `opt --print-passes 2>&1 | less` 列出所有可用 pass。
- 用 `--print-before=<pass>` / `--print-after=<pass>` 对比某个 pass 前后的 IR:`opt -passes='instcombine' --print-before=instcombine --print-after=instcombine src.ll -S -o out.ll 2>&1 | less`。
- 用 llc 把 IR 降级到底层:`llc -filetype=obj src.ll -o src.o` 生成目标文件;`llc -filetype=asm -masm-syntax=intel src.ll -o src.s` 生成 Intel 语法汇编;`llc -mcpu=skylake -mattr=+avx2 src.ll -o src.s` 指定目标 CPU 与特性;`llc --version` 查看可用目标。
- 读 IR 时识别关键构造:`alloca`=栈分配(SSA 前形态,`mem2reg` 会提升为寄存器)、`load`/`store`=内存访问、`getelementptr`(GEP)=指针运算/字段访问、`phi`=SSA φ 节点(合并前驱基本块的值)、`call`/`invoke`=函数调用(`invoke` 带异常边)、`icmp`/`fcmp`=整数/浮点比较、`br`=分支(条件或无条件)、`ret`=返回、`bitcast`=按位重解释(codegen 中为空操作)、`ptrtoint`/`inttoptr`=指针与整数互转(尽量避免)。
- 掌握常用 pass 的作用以组合流水线:`mem2reg`(alloca 提升为 SSA 寄存器)、`instcombine`(指令合并/窥孔优化)、`simplifycfg`(CFG 清理、删除死块)、`loop-vectorize`(自动向量化)、`slp-vectorize`(超字级并行,直线代码向量化)、`inline`(函数内联)、`gvn`(全局值编号,公共子表达式消除)、`licm`(循环不变量外提)、`loop-unroll`(循环展开)、`argpromotion`(把指针参数提升为值)、`sroa`(聚合体的标量替换)。
- 排查错过的优化:用 `clang -O2 -Rpass-missed=loop-vectorize -Rpass-analysis=loop-vectorize src.c` 看循环为什么没被向量化;用 `clang -O2 -mllvm -debug-pass=Structure src.c -o /dev/null 2>&1 | less` 打印 pass 流水线结构;用 `opt -passes='default<O2>' -print-after-all src.ll -S 2>&1 | less` 打印每个 pass 之后的 IR(输出极其冗长)。
- 按用途选用 LLVM 小工具:`llvm-dis`(bitcode→文本 IR)、`llvm-as`(文本 IR→bitcode)、`llvm-link`(链接多个 bitcode)、`llvm-lto`(独立 LTO)、`llvm-nm`(列出 bitcode/目标文件符号)、`llvm-objdump`(反汇编目标文件)、`llvm-profdata`(合并/查看 PGO profile)、`llvm-cov`(覆盖率报告)、`llvm-mca`(机器码分析,看吞吐/延迟);binutils 的等价工具另见相关技能。
适用边界 · 注意事项
- 需要编写/测试自定义 LLVM pass(PassPlugin、llvm-lit)时,应改用 llvm-passes 技能。
- 只需要源码级 Clang 编译选项、或在链接期做 LTO、或需要 JIT 执行时,应分别改用 clang、linkers-lto、jit-compilation 等技能。