文章目录
背景介绍
LLVM项目于2000年创立于伊利诺斯州大学,原本是一个为了静态及动态编程语言而生的现代的,基于静态单赋值(SSA)编译技术的研究项目。现在已经成长为一个包含许多子项目的大型项目,提供了一系列具有良好定义接口的可重用库。
LLVM采用C++语言实现,其最关键的部分是其提供的LLVM核心库。这些库提供开发者opt工具,与目标机器无关的优化器,以及对多种目标架构的代码生成支持。这些库围绕着LLVM中间表示(Intermediate Representation,IR)进行构建,几乎能够所有的高层级编程语言都能够映射成为LLVM IR。因此,要使用LLVM的优化器和代码生成技术,需要首先编写一个能够将高级语言转化生成LLVM IR的编译器前端。
内容简介
本文简单的总结了 LLVM essentials这本书的第一章内容,主要包括:
- LLVM库的集合以及模块化设计。
- 熟悉了解LLVM IR。
- 大致了解LLVM工具并在命令行中使用他们。
LLVM库的集合以及模块化设计
LLVM优化器的模块化设计
LLVM的优化器opt,优化器中定义了很多pass。在编译器的优化过程中,“pass” 是指一系列特定的优化步骤或阶段,这些步骤会逐一处理编译器生成的中间表示(例如,抽象语法树、中间代码),以改进程序的性能和效率。每个优化 pass 都有一个具体的任务,它可以执行一种或多种代码变换,以减少计算或内存消耗,提高程序的速度或减少代码大小等。
这些 pass按顺序运行,每个 pass 都在前一个 pass 的基础上进一步优化代码。每个pass都是由c++编写的一个类,该类原始继承自LLVM的Pass类。每个pass能够被编译成动态链接库xxx.o,随后被组合归档整理成为一个静态链接库xxx.a,该静态库包含opt工具中的所有pass,并且他们彼此之间是低耦合的,这些pass会显式地声明彼此之间的dependency(包括glue dependency,chain dependency,data flow dependency等)。
之所以称优化器是模块化设计的,是因为这种设计可以让开发者通过显示地声明依赖关系来控制pass执行的顺序,并能够控制哪些pass需要执行,哪些不需要。随后LLVM PassManger通过这些显式声明的依赖关系来以最优的方式运行这些pass,并且仅仅是需要运行的pass会被链接,而非每次都需要链接整个优化器。
下图引自[1],说明了不同的pass之间的关系。

图1 优化器pass的模块化设计
LLVM代码生成器的模块化设计
代码生成器也是用了像优化器一样的模块化设计,将整个代码生成过程分成一个个的pass,如指令选择,寄存器分配,调度,代码布局优化,发射汇编代码等等。
在代码生成的过程中,所有的目标架构都具有一些相同的步骤,如需要为虚拟寄存器分配可用的物理寄存器,但是对于不同的目标架构(目标机器),寄存器的集合又不尽相同。因此,编译器开发者可以按需调整每个pass,甚至可以根据目标机器的不同架构,创建自己的自定义pass。通过使用表