Home
avatar

230

总结LLVM-IR变化、PassManager的改进过程、逆向移植可行性分析

阅读官方文档,提取有用信息,总结LLVM-IR变化、PassManager的改进过程、逆向移植可行性分析

官方文档LLVM IR 变更汇总(v13.0.0 - v18.1.8)

13.0.0

LLVM IR 变更

  • inalloca 属性现在必须包含类型字段(类似 byvalsret)。
  • 引入不透明指针类型 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.extractllvm.vector.extract
    • llvm.experimental.vector.insertllvm.vector.insert
  • 移除常量表达式支持:如 udiv, fadd, insertvalue 等。
  • atomicrmw 支持新增:加入 fmaxfmin
  • callbr 不再使用 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_wrapudec_wrap 用于 atomicrmw
    • llvm.flt.rounds 更名为 llvm.get.rounding

17.0.1

LLVM IR 变更

  • Typed pointers 不再支持,移除 -opaque-pointers 选项
  • 新增 nofpclass 属性,用于优化浮点比较。
  • 新增 intrinsic:
    • llvm.ldexp
    • llvm.experimental.constrained.ldexp
    • llvm.frexp
  • 删除常量表达式版本指令:
    • select
  • 新增实验性:
    • convergence control intrinsics,用于控制并发语义

C API & Pass 管理器

  • 完全移除 legacy pass manager 接口
    • LLVMAddInstructionCombiningPass
    • LLVMInitializeInstCombine
    • LLVMPassManagerBuilderRef
    • LLVMPassRegistryRef
  • 删除 inline pass 中的 alloca 合并(由后端 stack coloring 代替)

18.1.8

LLVM IR 变更

  • llvm.stacksavellvm.stackrestore 现在支持重载指针类型(支持非 0 地址空间)。
  • 删除常量表达式版本指令:
    • and, or, lshr, ashr, zext, sext
    • fptrunc, 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, exp1017.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 19LLVM 13
默认 PM新 PM旧 PM
Pass 接口PassInfoMixin<T>FunctionPass
Pipeline 注册方式字符串表达式、PassBuilder明确的 addPass() 调用
内部结构模块化、按需构建手动注册与依赖分析
部分 Pass新增如 MLInlinerPassLoopFlattenPass不存在

逆向移植高版本优化Pass至LLVM-13.0.0可行性分析

  • 代码量大,依赖关系多。例如效果好的LoopIdiomVectorize这个Pass,cpp规模如下:

image-20250624124451801

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

image-20250624125910011

image-20250624125938003

结论:依赖关系少的分析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 名称路径简介
ModuleInlinerIPO/ModuleInliner.{cpp,h}模块级内联器(替代原有的内联行为控制方式)
CodeLayoutUtils/CodeLayout.{cpp,h}代码布局优化器,用于基本块重排序等
SampleProfileInferenceUtils/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 名称路径简介
CoroConditionalWrapperCoroutines/CoroConditionalWrapper.{cpp,h}协程条件包装器,优化协程状态切换
TLSVariableHoistScalar/TLSVariableHoist.{cpp,h}提升线程局部变量访问至更高作用域
LowerAtomicUtils/LowerAtomic.{cpp,h}降低原子操作至平台兼容的实现
LowerGlobalDtorsUtils/LowerGlobalDtors.{cpp,h}降低全局析构函数处理逻辑
MemoryTaggingSupportUtils/MemoryTaggingSupport.{cpp,h}内存打标签支持,配合内存安全相关工具(如 HWASAN)
MisExpectUtils/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 名称路径简介
KCFIInstrumentation/KCFI.{cpp,h}内核控制流完整性支持,增强内核 CFI 防护
SanitizerBinaryMetadataInstrumentation/SanitizerBinaryMetadata.{cpp,h}添加二进制级元数据支持(如 ASAN/MSAN 等)
LowerIFuncUtils/LowerIFunc.{cpp,h}降低 indirect function(IFunc)语义
ExtractGV(头文件)IPO/ExtractGV.h全局变量抽取 Pass 接口
FunctionSpecialization(头文件)IPO/FunctionSpecialization.h函数专用化机制接口
VPlanCFG(头文件)Vectorize/VPlanCFG.hVPlan 向量化控制流图结构(辅助向量化)

总结:

LLVM 版本新增 Pass 数量(含辅助模块)
14.0.04
15.0.07
16.0.06

部分模块(如 VPlanRecipes, VPlanCFG)可能不直接作为 Pass 注册,而是作为 Pass 的内部工具或辅助结构出现。

移植:

优先级Pass
1️⃣FunctionSpecialization
2️⃣LowerAtomic
3️⃣FlattenCFG(增强)
4️⃣TLSVariableHoist
5️⃣LowerIFunc
LLVM

喜欢这篇文章嘛,觉得文章不错的话,奖励奖励我!

支付宝打赏支付宝微信打赏 微信