pass简介
pass
:llvm pass 是 llvm 架构的重要组成部分。pass 的主要工作是:对代码进行分析、优化代码。所有 llvm pass 都是pass
的子类,通过通过重写从中继承的虚方法来实现功能Pass
。LLVM Pass框架的一个主要特性是它根据传递遇到的约束(由它们派生自哪个类来指示)来调度传递以高效的方式运行。
pass
大致可以分为两类:分析和转换。分析类的pass
以提供信息为主,转换类的则要修改中间代码。
pass
类如下:
ImmutablePass:不运行, 不改变状态也永不更新的
pass
, 一般情况下用于显示编译器的配置信息.ModulePass:用于执行任何非结构化的过程间优化。通用类型的
pass
,将整个程序示为一个单元处理。用virtual bool runOnModule(Module &M) = 0;
来实现ModulePass
.CallGraphSCCPass:用于被那些需要从底向上(bottom-up)遍历call graph的pass调用.
FunctionPass:是以单个函数为作用域的
pass
, 每个函数间是相互独立的, 相互之间无法影响LoopPass:是以单个
loop
为作用域的pass
, 每个loop
间相互独立.LoopPass
以嵌套方式处理循环, 外层循环最后处理.RegionPass:类似与
LoopPass
,但是在函数中的每个单入口单出口区域执行。RegionPass
以嵌套顺序处理,以便最后处理最外面的区域。pBasicBlockPass:用于实现本地优化,优化通常每次针对一个基本块或指令运行。
MachineFunctionPass:类似
FunctionPass
, 区别在于前者属于LLVM code generator
(后端), 生成架构相关代码,FunctionPass
属于LLVM optimizer
(中端), 生成通用的IR.
pass”入门”
编写/分析
1 | $ cd ~/llvm/llvm-7.0.1.src/lib/Transforms/Hello |
https://llvm.org/docs/WritingAnLLVMPass.html
可以参考官方教程再自己搞一个。
1 |
|
对上述代码的一些分析:
1 | namespace{ |
开始一个新的匿名命名空间。在C++
中匿名命名空间会引入静态全局作用域,类似C语言中的static
关键字,它使在匿名命名空间内声明的内容仅对当前文件可见。
接着,声明我们的Pass
:
1 | struct Hello : public FunctionPass { |
声明了一个Hello
类,它是FunctionPass
的子类。FunctionPass
类一次只操作一个函数。
1 | static char ID; |
声明一个 pass 的 ID,llvm 将会使用ID来定位这些pass。避免使用复杂的C++运行机制。
1 | bool runOnFunction(Function &F) override { |
定义runOnFunction
方法,覆写从FunctionPass
继承的虚函数。
1 | char Hello::ID = 0; |
初始化Pass ID。LLVM使用ID的地址来标识Pass,因此初始化值并不重要。
1 | static RegisterPass<Hello> X("hello", "Hello World Pass", |
注册类Hello
,第一个命令行参数hello
,并命名为Hello World Pass
。最后两个参数描述了它的行为:如果传递遍历CFG而不修改它,则第三个参数设置为true
; 如果pass 是分析 pass,那么将会有第四个参数,为true
,反之则为false
.
1 | $ cd build |
在我们刚刚创建的build
内,执行 make
,得到一个新文件LLVMHello.so
我们在~/llvm/build/lib
下可以找到对应的文件。
使用opt命令运行pass
1 | $ clang -S -O3 -emit-llvm hello.c |
我们可以使用opt命令通过您的Pass来运行LLVM程序。由于您已使用RegisterPass
注册了Pass,因此一旦加载,您就可以使用 opt 工具访问它。
-load
选项指定 Pass 作为共享对象加载,加载后-hello
才是有效的。(这也是注册Pass的原因之一)。因为 -hello
没有修改任何东西,所以直接查看结果即可。
也可以通过 opt -load LLVMHello.so-help |grep -i hello
来查看其他注册字符串,当然最后也可以查看一下运行时间。
大致了解了 pass
的流程和编写骨架吧。
参考: