LLVM IR(Intermediate Representation)是一种中间语言表示,作为编译器前端和后端的分水岭。LLVM 编译器的前端——Clang 负责产生 IR,而其后端负责消费 IR。

编译器 IR 的设计体现了权衡的计算思维。低级的 IR(即更接近目标代码的 IR)允许编译器更容易地生成针对特定硬件的优化代码,但不利于支持多目标代码的生成。高级的 IR 允许优化器更容易地提取源代码的意图,但不利于编译器根据不同的硬件特性进行代码优化。

LLVM IR 的设计采用common IRspecific IR相结合的方式。common IR旨在不同的后端共享对源程序的相同理解,以将其转换为不同的目标代码。除此之外,也为多个后端之间共享一组与目标无关的优化提供了可能性。specific IR允许不同的后端在不同的较低级别优化目标代码。这样做,既可以支持多目标代码的生成,也兼顾了目标代码的执行效率。

LLVM IR 有如下 3 种等价形式:

  • 内存表示
    • llvm::Functionllvm::Instruction等用于表示common IR
    • llvm::MachineFunctionllvm::MachineInstr等用于表示specific IR
  • 位码文件(Bitcode Files,存储在磁盘中)
  • 汇编文件(Assembly Files,存储在磁盘中,便于人类可读)

注:这里的汇编文件不是通常所说的汇编语言文件,而是 LLVM 位码文件的可读表示。

LLVM IR有三个主要特点:

  • 采用静态单一赋值(Static Single Assignment,SSA),即每个值只有一个定义它的赋值操作。
  • 代码被组织为三地址指令(Three-address Instructions)。
  • 有无限多个寄存器。

LLVM IR总览

从种类上划分,LLVM IR大致可以分为:

Type System类型系统

参考资料

  1. LLVM 之 IR 篇(1):零基础快速入门 LLVM IR
  2. LLVM Language Reference Manual