什么是LLVM
官方描述如下: The LLVM Project is a collection of modular and reusable compiler and toolchain technologies. Despite its name, LLVM has little to do with traditional virtual machines. The name "LLVM" itself is not an acronym; it is the full name of the project.
LLVM项目是一个模块化的、可重用的编译器和工具链集合。尽管它的名字-LLVM与传统虚拟机(low level virtual machine)名字相似。但“LLVM”这个名字本身不是一个缩略词,它就是这个项目的全称。所以,不要再把LLVM叫做low level virtual machine。 LLVM开始于伊利诺斯大学的一个研究项目。目的是提供一个现代的、基于SSA的、能够支持任意静态和动态编译的编程语言的编译策略。此后,LLVM成长为伞项目下的一个子项目。其中许多是被广泛用于各种各样的商业生产和开源代码项目以及学术研究中。LLVM项目源码采用“Apache 2.0许可协议”。 基于LLVM,又衍生出了一些强大的子项目,其中iOS开发者耳熟能详的是:Clang和LLDB。
传统编译器架构
传统的编译器架构(比如GCC)主要分为前端、优化器、后端(理论上优化器也是后端的一部分)。他们的作用如下: 前端:词法分析、语法分析、语义分析、生成中间代码。 优化器:中间代码作为输入,优化中间代码(与架构无关的代码优化),使代码运行更快,体积更小。 后端:生成机器码(根据不同架构x86、x64等生成不同架构的机器码)
LLVM架构
由上图可知,LLVM架构下,不同的前端和后端使用统一的中间代码LLVM InterMediate Representation(LLVM IR) 如果需要支持一门新的编程语言,只需要实现一个新的前端 如果需要支持一款新的硬件设备,只需要实现一个新的后端 优化阶段是一个通用的阶段,他针对的是统一的LLVM IR,不论是支持新的编程语言,还是支持新的硬件设备,都不需要对优化阶段做修改。 相比之下,GCC的前端后端没有实现分离,前端后端耦合在了一起,所以GCC为了支持一门新的编程语言,或者为了支持一个新的硬件设备,就变得特别困难。 LLVM现在被作为实现各种静态和运行时编译语言的通用基础结构(GCC家族、Java、.NET、Python、Ruby、Scheme、Haskell、D等)
什么是Clang
Clang是LLVM的项目的子项目。它是LLVM架构下的C/C Objective-C的编译器前端
。诞生之初是为了替代GCC,提供更快的编译速度。
相比较于GCC,Clang具有如下优点:
- 编译速度快。在某些平台上,Clang的编译速度明显快过GCC。Debug模式下,Clang编译OC的速度比GCC快3倍。
- 占用内存少。Clang生成的AST(抽象语法树)所占用的内存是GCC的五分之一左右
- 模块化设计。Clang作为LLVM项目下的一个子项目,采用基于库的模块化设计,易于IDE的集成及其他用途的重用。
- 诊断信息可读性强:在编译过程中,Clang 创建并保留了大量详细的元数据 (metadata),有利于调试和错误报告
- 设计清晰简单,容易理解,易于扩展增强
Clang与LLVM关系
上图呈现了Clang和LLVM的关系。Clang作为LLVM的前端,负责词法分析、语法分析、语义分析,然后生成中间代码。接下来把中间代码转交给优化器,优化器会对中间代码进行与架构无关的代码优化,优化后的代码体积更小、运行速度更快。最终LLVM后端会把优化后的中间代码转化为机器码。流程如下:
虽然Clang是LLVM的前端,但是LLVM的前端不只是Clang。Clang只是为C、C 、Objective-C设计的LLVM的编译器前端。除此之外,还有为Swift设计的编译器前端Swift(这里指编译器前端)。Clang、Swift、LLVM的关系如下:
PS: 广义的LLVM是指整个LLVM项目,包括Clang前端。狭义的LLVM是指LLVM后端。