前言
在熟悉LLVM的编译以后,我们将从以下几个方面对LLVM进行深入的探究:
- LLVM核心库基本设计原则
- 编译器驱动程序如何工作
- LLVM驱动程序的交互
- 独立组件的应用
- 了解LLVM基本库
- 介绍LLVM中的C++实践
- 编写第一个LLVM项目
1.LLVM基本设计原则
LLVM设计的一个核心方面是IR(SSA:单静态赋值),具有如下两个特征:
- 它被组织成三地址指令
- 有无限个寄存器
LLVM在不同的编译阶段使用以下额外的数据结构:
- 当将C或C++转换为LLVM IR时,Clang通过使用抽象语法树(AST)结构代表其在内存中的表示形式(TranslationUnitDecl class)。
- 当将LLVM IR转换成机器专用的汇编语言时,LLVM将首先将程序转换为有向无环图(DAG)表单,其将允许简单的指令选择 (SelectionDAG class),然后它转换回一个三地址形式,以允许指令调度(MachineFunction class)。
- 为了实现汇编器和链接器,LLVM在形式对象的上下文中使用第四种中介数据结构(MCModule class)来保存程序。
2.LLVM编译器驱动程序如何工作
图1:LLVM的执行流程如上图所示
这些编译器部件之间的交互可以在下面两种方式下进行:
- 在内存中:这发生在通过一个单一的管理组件,例如Clang。利用LLVM组件作为库,并依赖于数据结构在内存中的分配, 将一个阶段的输出提供给另一个阶段的输入。
- 通过文件:这发生在一个启动较小独立组件的用户,将特定组件的结果写入磁盘文件。并将文件作为下一个组件的输入。
图2:LLVM库介绍
在上面的例子中:LLVM后端工具llc,使用libLLVMCodeGen库实现它的部分功能,与此同时只负责启动LLVM IR级优化器的opt命令使用另一个库(libLLVMipa)来实现与目标无关的过程间优化。然而,我们看到clang更强大之处是,它使用两个库覆盖llc和opt并向用户呈现一个更简单的界面。通过这样的高级工具执行任何任务可以分解成一系列的低级工具执行结果的组合。
3.LLVM编译器驱动程序的交互