总结LLVM-IR变化、PassManager的改进过程、逆向移植可行性分析
阅读官方文档,提取有用信息,总结LLVM-IR变化、PassManager的改进过程、逆向移植可行性分析
官方文档LLVM IR 变更汇总(v13.0.0 - v18.1.8)
13.0.0
LLVM IR 变更
inalloca属性现在必须包含类型字段(类似byval和sret)。- 引入不透明指针类型
ptr(尚未稳定,不建议使用)。 - 使用 legacy pass manager 进行优化的方式已被弃用,将在 LLVM 14 移除。
C API 更改
- 支持调用新的 pass manager。
- 删除了
LLVMPassBuilderOptionsSetCoroutines(协程 pass 默认启用)。
14.0.0
LLVM IR 变更
- 继续弃用 legacy pass manager,计划在 LLVM 14 后移除。
- 最大整数类型从
2^24-1位缩减为2^23位。 - 最大对齐值从
2^29增加到2^32。
15.0.0
LLVM IR 变更
- 使用不透明指针,所有具体类型的指针(如
i8*,i32*,void()**等)统一为ptr类型。 - 重命名 Intrinsic:
llvm.experimental.vector.extract→llvm.vector.extractllvm.experimental.vector.insert→llvm.vector.insert
- 移除常量表达式支持:如
udiv,fadd,insertvalue等。 atomicrmw支持新增:加入fmax和fmincallbr不再使用blockaddress,改为使用!引用目标块。
16.0.0
LLVM IR 变更
以下函数属性统一被替换为
memory(...):原属性 新属性表达式 readnonememory(none)readonlymemory(read)writeonlymemory(write)argmemonlymemory(argmem: readwrite)argmemonly readonlymemory(argmem: read)argmemonly writeonlymemory(argmem: write)inaccessiblememonlymemory(inaccessiblemem: readwrite)inaccessiblememonly readonlymemory(inaccessiblemem: read)inaccessiblememonly writeonlymemory(inaccessiblemem: write)inaccessiblemem_or_argmemonlymemory(argmem: readwrite, inaccessiblemem: readwrite)inaccessiblemem_or_argmemonly readonlymemory(argmem: read, inaccessiblemem: read)inaccessiblemem_or_argmemonly writeonlymemory(argmem: write, inaccessiblemem: write)删除常量表达式版本指令:
fneg
新增:
- Target extension types
uinc_wrap和udec_wrap用于atomicrmwllvm.flt.rounds更名为llvm.get.rounding
17.0.1
LLVM IR 变更
- Typed pointers 不再支持,移除
-opaque-pointers选项。 - 新增
nofpclass属性,用于优化浮点比较。 - 新增 intrinsic:
llvm.ldexpllvm.experimental.constrained.ldexpllvm.frexp
- 删除常量表达式版本指令:
select
- 新增实验性:
- convergence control intrinsics,用于控制并发语义
C API & Pass 管理器
- 完全移除 legacy pass manager 接口:
LLVMAddInstructionCombiningPassLLVMInitializeInstCombineLLVMPassManagerBuilderRefLLVMPassRegistryRef
- 删除 inline pass 中的 alloca 合并(由后端 stack coloring 代替)
18.1.8
LLVM IR 变更
llvm.stacksave和llvm.stackrestore现在支持重载指针类型(支持非 0 地址空间)。- 删除常量表达式版本指令:
and,or,lshr,ashr,zext,sextfptrunc,fpext,fptoui,fptosi,uitofp,sitofp
- 新增 intrinsic:
llvm.exp10
- 新增:
code_model属性(用于全局变量)
总结表
| 类别 | 内容 | 涉及版本 |
|---|---|---|
| 属性统一 | memory(...) 替换旧属性 | 16.0.0 |
| 浮点优化 | nofpclass 属性 | 17.0.1 |
| 指针类型 | ptr 引入 / typed pointers 删除 | 13.0.0 / 17.0.1 |
| 常量表达式删除 | 多个 IR 指令不再支持常量表达式 | 16.0.0 - 18.1.8 |
| Pass 管理器 | legacy pass manager 弃用并删除 | 13.0.0 - 17.0.1 |
| intrinsic 增补 | ldexp, frexp, exp10 等 | 17.0.1 - 18.1.8 |
LLVM 13.0.0 能否完全使用新的 Pass Manager?
不成熟。LLVM 13.0.0 提供了新的 Pass Manager,并允许你使用它,但某些功能(尤其是 C API 和部分 pass)在这个版本中尚未完全迁移或支持。
默认支持新的 Pass Manager,所以之前小节讲的必须要禁用新的PM模式。C API 对新 PM 的支持还比较初步。
LLVM 13的opt工具默认只支持Legacy PassManager的老式Pass,或者是静态编译进opt里的新PM Pass插件。
llvm::PassPluginLibraryInfo 和插件接口是 LLVM14+ 新增的。
对比新版PM和老版PM仓库源码
- 新增后端CodeGenPassBuilder.cpp
作用:为 LLVM 后端代码生成阶段的 MachineFunction 分析 Pass 注册唯一的 AnalysisKey。
- 新增OptimizationLevel.cpp
作用:定义了 LLVM 编译器支持的几个标准优化等级(O0, O1, O2, O3, Os, Oz)对应的优化级别(速度 vs 大小)。
特性 LLVM 19 LLVM 13 默认 PM 新 PM 旧 PM Pass 接口 PassInfoMixin<T>FunctionPass等Pipeline 注册方式 字符串表达式、PassBuilder 明确的 addPass()调用内部结构 模块化、按需构建 手动注册与依赖分析 部分 Pass 新增如 MLInlinerPass、LoopFlattenPass不存在
逆向移植高版本优化Pass至LLVM-13.0.0可行性分析
- 代码量大,依赖关系多。例如效果好的LoopIdiomVectorize这个Pass,cpp规模如下:

依赖的头文件有差异需要逐层修改、工作量很大


结论:依赖关系少的分析Pass逆向移植成功性可能大,但不确定是否有意义。优化效果好的优化Pass逆向迁移,依赖关系多太过复杂、成功性低。
对比不同版本LLVM新增的Pass(统计14-16版本,旧PM废除之前)
git diff --name-status llvmorg-13.0.0 llvmorg-14.0.0 -- llvm/lib/Transforms/ | grep '^A'
git diff --name-status llvmorg-13.0.0 llvmorg-14.0.0 -- llvm/include/llvm/Transforms/ | grep '^A'14.0.0:
A llvm/lib/Transforms/IPO/ModuleInliner.cpp
A llvm/lib/Transforms/Utils/CodeLayout.cpp
A llvm/lib/Transforms/Utils/SampleProfileInference.cpp
A llvm/include/llvm/Transforms/IPO/ModuleInliner.h
A llvm/include/llvm/Transforms/Scalar/FlattenCFG.h
A llvm/include/llvm/Transforms/Utils/CodeLayout.h
A llvm/include/llvm/Transforms/Utils/SampleProfileInference.h| Pass 名称 | 路径 | 简介 |
|---|---|---|
ModuleInliner | IPO/ModuleInliner.{cpp,h} | 模块级内联器(替代原有的内联行为控制方式) |
CodeLayout | Utils/CodeLayout.{cpp,h} | 代码布局优化器,用于基本块重排序等 |
SampleProfileInference | Utils/SampleProfileInference.{cpp,h} | 通过抽样信息进行性能导向的路径推断 |
FlattenCFG(头文件) | Scalar/FlattenCFG.h | 控制流图扁平化(虽为头文件,可能表示结构或辅助功能) |
15.0.0:
A llvm/lib/Transforms/Coroutines/CoroConditionalWrapper.cpp
A llvm/lib/Transforms/Scalar/TLSVariableHoist.cpp
A llvm/lib/Transforms/Utils/LowerAtomic.cpp
A llvm/lib/Transforms/Utils/LowerGlobalDtors.cpp
A llvm/lib/Transforms/Utils/MemoryTaggingSupport.cpp
A llvm/lib/Transforms/Utils/MisExpect.cpp
A llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
A llvm/include/llvm/Transforms/Coroutines/CoroConditionalWrapper.h
A llvm/include/llvm/Transforms/Scalar/TLSVariableHoist.h
A llvm/include/llvm/Transforms/Utils/LowerAtomic.h
A llvm/include/llvm/Transforms/Utils/LowerGlobalDtors.h
A llvm/include/llvm/Transforms/Utils/MemoryTaggingSupport.h
A llvm/include/llvm/Transforms/Utils/MisExpect.h| Pass 名称 | 路径 | 简介 |
|---|---|---|
CoroConditionalWrapper | Coroutines/CoroConditionalWrapper.{cpp,h} | 协程条件包装器,优化协程状态切换 |
TLSVariableHoist | Scalar/TLSVariableHoist.{cpp,h} | 提升线程局部变量访问至更高作用域 |
LowerAtomic | Utils/LowerAtomic.{cpp,h} | 降低原子操作至平台兼容的实现 |
LowerGlobalDtors | Utils/LowerGlobalDtors.{cpp,h} | 降低全局析构函数处理逻辑 |
MemoryTaggingSupport | Utils/MemoryTaggingSupport.{cpp,h} | 内存打标签支持,配合内存安全相关工具(如 HWASAN) |
MisExpect | Utils/MisExpect.{cpp,h} | 检测 __builtin_expect 使用是否合理 |
VPlanRecipes(辅助) | Vectorize/VPlanRecipes.cpp | 向量化计划表示的实现模块,辅助 LoopVectorize |
16.0.0
A llvm/lib/Transforms/Instrumentation/KCFI.cpp
A llvm/lib/Transforms/Instrumentation/SanitizerBinaryMetadata.cpp
A llvm/lib/Transforms/Utils/LowerIFunc.cpp
A llvm/lib/Transforms/Vectorize/VPlanCFG.h
A llvm/include/llvm/Transforms/IPO/ExtractGV.h
A llvm/include/llvm/Transforms/IPO/FunctionSpecialization.h
A llvm/include/llvm/Transforms/Instrumentation/KCFI.h
A llvm/include/llvm/Transforms/Instrumentation/SanitizerBinaryMetadata.h
A llvm/include/llvm/Transforms/Utils/LowerIFunc.h| Pass 名称 | 路径 | 简介 |
|---|---|---|
KCFI | Instrumentation/KCFI.{cpp,h} | 内核控制流完整性支持,增强内核 CFI 防护 |
SanitizerBinaryMetadata | Instrumentation/SanitizerBinaryMetadata.{cpp,h} | 添加二进制级元数据支持(如 ASAN/MSAN 等) |
LowerIFunc | Utils/LowerIFunc.{cpp,h} | 降低 indirect function(IFunc)语义 |
ExtractGV(头文件) | IPO/ExtractGV.h | 全局变量抽取 Pass 接口 |
FunctionSpecialization(头文件) | IPO/FunctionSpecialization.h | 函数专用化机制接口 |
VPlanCFG(头文件) | Vectorize/VPlanCFG.h | VPlan 向量化控制流图结构(辅助向量化) |
总结:
| LLVM 版本 | 新增 Pass 数量(含辅助模块) |
|---|---|
| 14.0.0 | 4 |
| 15.0.0 | 7 |
| 16.0.0 | 6 |
部分模块(如 VPlanRecipes, VPlanCFG)可能不直接作为 Pass 注册,而是作为 Pass 的内部工具或辅助结构出现。
移植:
| 优先级 | Pass |
|---|---|
| 1️⃣ | FunctionSpecialization |
| 2️⃣ | LowerAtomic |
| 3️⃣ | FlattenCFG(增强) |
| 4️⃣ | TLSVariableHoist |
| 5️⃣ | LowerIFunc |