LLVM Pass学习(1)
因为不想再在这种题上爆零,所以开了这个系列😭
LLVM Pass概述
LLVM Pass 是一个在 LLVM 编译框架中执行的独立的代码变换或优化步骤。LLVM 本身是一个开源的编译器框架,广泛用于生成机器代码、优化代码和进行程序分析。Pass 是 LLVM 中处理中间表示(IR, Intermediate Representation)的基本单位。
具体概念解释:
-
中间表示(IR):
LLVM 使用一种称为中间表示(IR)的低级代码格式,介于源代码和机器代码之间。IR 更加抽象,不依赖于任何特定的硬件架构,便于进行优化和转换。 -
Pass:在 LLVM 中,Pass 是对 IR 进行某种操作的单元。每个 Pass 会执行特定的任务,如优化、分析或者代码转换。Pass 会遍历 IR,并对其进行修改或分析,生成更有效的代码。
Pass 可以分为两大类:
-
分析 Pass:这类 Pass 只对程序进行分析,不会修改代码。例如,分析程序的控制流、数据流、依赖关系等。
-
变换 Pass:这类 Pass 会对代码进行修改,通常用于优化。比如,消除无用代码(Dead Code Elimination)、循环展开(Loop Unrolling)等。
-
-
优化:
LLVM Pass 的重要功能之一是优化,优化可以帮助生成运行更高效的代码。优化的类型有很多,包括:- 常量传播(Constant Propagation):用已知的常量值替换表达式。
- 循环优化:对循环进行优化,如循环合并、循环展开等。
- 死代码消除(Dead Code Elimination):删除不影响程序结果的代码。
- 内联(Inlining):将函数调用替换为函数体,以减少函数调用的开销。
-
Pass 管理器:在 LLVM 中,多个 Pass 会被组合在一起,形成一个 Pass 管理器(Pass Manager)。Pass 管理器负责管理和执行所有的 Pass,并确保它们按照正确的顺序执行。Pass 可以是一个独立的步骤,也可以按需组合执行。
-
优化级别:
LLVM 提供不同的优化级别(如-O1
、-O2
、-O3
)来控制 Pass 的应用程度。不同的级别表示不同的优化强度,高级别可能会使用更复杂的优化,但也可能会增加编译时间。
人话:
假设有一段程序,它做了很多重复的计算。如果使用 LLVM Pass 来优化代码,Pass 可能会发现这些计算是冗余的(例如,两个相同的加法操作),然后将其优化成更简单的代码,从而加速程序的执行。
总结来说,LLVM Pass 是一种对代码进行优化和变换的机制,通过多个独立的 Pass 对中间表示进行操作,最终帮助生成更加高效的机器代码。
小试牛刀
环境为Ubuntu20.04,llvm版本为llvm-9
首先准备一段官方资料给的测试代码
1 |
|
其中,Hello模块的功能为输出程序所有的函数名接着将其编译为so文件
1 | clang `llvm-config --cxxflags` -Wl,-znodelete -fno-rtti -fPIC -shared myFirstLLVMpass.cpp -o LLVMFirst.so `llvm-config --ldflags` |
现在再随便准备一个C语言程序,将其编译为.ll
文件
1 | clang -emit-llvm -S test.c -o test.ll |
最后使用opt加载so文件,测试下hello模块
1 | opt -load ./LLVMFirst.so -hello test.ll |