LLVM IR总览
LLVM IR(Intermediate Representation)是一种中间语言表示,作为编译器前端和后端的分水岭。LLVM 编译器的前端——Clang 负责产生 IR,而其后端负责消费 IR。
编译器 IR 的设计体现了权衡
的计算思维。低级的 IR(即更接近目标代码的 IR)允许编译器更容易地生成针对特定硬件的优化代码,但不利于支持多目标代码的生成。高级的 IR 允许优化器更容易地提取源代码的意图,但不利于编译器根据不同的硬件特性进行代码优化。
LLVM IR 的设计采用common IR
和specific IR
相结合的方式。common IR
旨在不同的后端共享对源程序的相同理解,以将其转换为不同的目标代码。除此之外,也为多个后端之间共享一组与目标无关的优化提供了可能性。specific IR
允许不同的后端在不同的较低级别优化目标代码。这样做,既可以支持多目标代码的生成,也兼顾了目标代码的执行效率。
LLVM IR 有如下 3 种等价形式:
- 内存表示
- 类
llvm::Function
、llvm::Instruction
等用于表示common IR
。 - 类
llvm::MachineFunction
、llvm::MachineInstr
等用于表示specific IR
。
- 类
- 位码文件(Bitcode Files,存储在磁盘中)
- 汇编文件(Assembly Files,存储在磁盘中,便于人类可读)
注:这里的汇编文件
不是通常所说的汇编语言文件,而是 LLVM 位码文件的可读表示。
LLVM IR有三个主要特点:
- 采用静态单一赋值(Static Single Assignment,SSA),即每个值只有一个定义它的赋值操作。
- 代码被组织为三地址指令(Three-address Instructions)。
- 有无限多个寄存器。
LLVM IR总览
从种类上划分,LLVM IR大致可以分为:
Type System
Constants
MetaData
Intrinsic Global Variables
Instructions
Termination Instruction
Operation
- Unary Operation
- Binary Operation
- Bitwise Operation
- Vector Operation
- Aggregate Operation
- Memory Access & Addressing Operation
- Conversion Operation
- Other Operation
Intrinsic Function(内部函数)
变量参数处理内部函数
精确垃圾收集内部函数
代码生成内部函数
标准C/C++库内部函数
位操作内部函数
算数溢出内部函数
饱和运算内部函数
定点算数内部函数
特殊运算内部函数
硬件循环内部函数
向量运算内部函数
矩阵运算内部函数
半精度浮点运算内部函数
饱和浮点数转整数内部函数
调试器内部函数
异常处理内部函数
指针验证内部函数
Trampoline Intrinsics
向量预测内部函数
Masked Vector Expanding Load and Compressing Store Intrinsics
Type System类型系统