LLVM

LLVM是一套编译器基础设施项目，为自由软件，以C++写成，包含一系列模块化的编译器组件和工具链，用来开发编译器前端和后端。任意一种程式语言通过它实作出来的编译器，都能利用上它在编译时期、链接时期、执行时期以及“闲置时期”进行的最佳化。

它最早以C/C++为实作对象，而目前它已支援包括ActionScript、Ada、D语言、Fortran、GLSL、Haskell、Java字节码、Objective-C、Swift、Python、Ruby、Crystal (程式语言)、Rust、Scala、Standard ML以及C#等语言。

## 历史

LLVM专案的发展起源于2000年伊利诺伊大学厄巴纳-香槟分校的维克拉姆·艾夫（Vikram Adve）与克里斯·拉特纳（Chris Lattner）的研究，他们想要为所有静态及动态语言创造出动态的编译技术。LLVM是以BSD授权来发展的开源软件。2005年，苹果电脑雇用了克里斯·拉特纳及他的团队为苹果电脑开发应用程序系统，LLVM为现今macOS及iOS开发工具的一部分。

LLVM的命名最早源自于底层虚拟机器（Low Level Virtual Machine）的首字母缩写，由于这个专案的范围并不局限于建立一个虚拟机器，这个缩写导致了广泛的疑惑。LLVM开始成长之后，成为众多编译工具及低阶工具技术的统称，使得这个名字变得更不贴切，开发者因而决定放弃这个缩写的意涵，现今LLVM已单纯成为一个系统，适用于LLVM下的所有专案，包含LLVM中间表示（LLVM IR）、LLVM除错工具、LLVM C++标准函式库等。

因LLVM对产业的贡献，计算机协会于2012年将ACM软件系统奖授与维克拉姆·艾夫、克里斯·拉特纳和Evan Cheng。

自9.0.0版本开始，LLVM使用带有LLVM额外条款的Apache许可证2.0进行授权。而从2019年10月开始，LLVM项目的代码托管正式迁移到了GitHub。

## 描述

LLVM提供了一套适合编译器系统的中间表示（Intermediate Representation，IR），有大量变换和优化都围绕其实现。经过变换和优化后的中间语言，可以转换为目标平台相关的汇编语言代码。LLVM可以和GCC工具链一起工作，允许它与为该项目编写的大量现有编译器一起使用。

LLVM还可以在编译、链接时生成重定位（Relocatable Code），甚至在运行时生成二进制机器码。

LLVM支援与语言无关的指令集架构及类型系统。每个指令都处在静态单赋值形式（SSA）下代表着，每个变数（被称为具有型别的暂存器）仅被赋值一次，这简化了变数间相依性的分析。LLVM允许程式码遵循传统GCC系统的方式而被静态的编译，或者以类似JAVA等后期编译的方式，通过即时编译（JIT）将IF编译成机器码。

LLVM的型别系统包含基本型别（整数或是浮点数）及五个复合型别（指标、阵列、向量、结构及函数），具体语言的型别，可以在LLVM中用基本型别的组合来表示，举例来说，C++所使用的类，可以被表示为结构、函数和函数指针的阵列的混合。

LLVM JIT编译器可以最佳化程式在执行期之时去除所不需要的静态分支，这在一些部分求值（Partial Evaluation）的案例中相当有效，即当程式有许多选项，而在特定环境下其中多数可被判断为是不需要的。这个特色被使用在Mac OS X Leopard（v10.5）底下OpenGL的管线，当硬件不支援某个功能时依然可以被成功地运作。

OpenGL堆栈下的绘图程式被编译为中间表示，接着在机器上执行时被编译，当系统拥有高阶GPU时，这段程式会进行极少的修改并将传递指令给GPU，当系统拥有低阶的GPU时，LLVM将会编译更多的程序，使这段GPU无法执行的指令在本地端的中央处理器执行。LLVM增进了使用Intel GMA芯片等低端机器的效能。一个类似的系统发展于Gallium3D LLVMpipe，它已被合并到GNOME，使其可运行在没有GPU的环境。

根据2011年的一项测试，GCC在执行时期的性能平均比LLVM高10%。而2013年测试显示，LLVM可以编译出接近GCC相同效能的执行码。

## 组件

LLVM已经成为多个编译器和代码生成相关子项目的母项目。

### 前端

LLVM最初被用来取代GCC中的程式码产生器，许多GCC的前端已经可以与其运行，LLVM目前支援Ada、C语言、C++、D语言、Fortran、Haskell、Julia、Objective-C、Rust及Swift的编译，它使用许多的编译器，有些来自4.0.1及4.2的GCC。

LLVM引发一些人来为许多语言开发新的编译器，其中一个最引发注意的就是Clang，它是一个新的编译器，同时支援C、Objective-C以及C++。主要来自苹果电脑的支持，Clang的目的用以取代GCC系统底下的C/Objective-C编译器，在当代的系统，他较为容易与集成开发环境（IDE）整合，而且对于线程有更好的支援。Clang从3.8版本开始已经支持OpenMP。GCC底下Objective-C的开发已经停滞，而苹果电脑已经将其支援移至其他的维护分支。

Utrecht Haskell编译器可以产生LLVM使用的程式码，但它还在初期的开发阶段，并且在许多案例，展示他比起C程式码产生器拥有更好的效率Glasgow Haskell Compiler（GHC）拥有一个可以运作的LLVM后端，程式执行效能对比起原先的编译器可以达到30%的加速，它仅比一个由GHC所实现，并拥有多项最佳化技术的编译器还慢

还有其他的元件在不同的开发阶段，包含（但不限于）Java字节码、通用中间语言（CIL）、MacRuby（Ruby 1.9实现）、Standard ML及新的图着色寄存器分配器。

### 中间表示

LLVM的核心是中间表示（Intermediate Representation，IR），一种类似汇编的底层语言。IR是一种强类型的精简指令集（RISC），并对目标指令集进行了抽象。例如，目标指令集的函数调用惯例被抽象为`call`和`ret`指令加上明确的参数。另外，IR采用无限个数的暂存器，使用如`%0`，`%1`等形式表达。LLVM支持三种表达形式：人类可读的汇编格式，适合前端的在内存中的格式和用作序列化的紧密bitcode格式。

例如，一个简单的Hello World程序可以表达为如下的汇编形式。对IR语言的完整描述请参考LLVM官方文档：

```llvm
@.str = internal constant [14 x i8] c"hello, world\0A\00"

declare i32 @printf(i8*, ...)

define i32 @main(i32 %argc, i8** %argv) nounwind {
entry:
    %tmp1 = getelementptr [14 x i8], [14 x i8]* @.str, i32 0, i32 0
    %tmp2 = call i32 (i8*, ...) @printf( i8* %tmp1 ) nounwind
    ret i32 0
}
```

LLVM计划还介入了另一种类型的中间表示名为MLIR编译器框架，它通过采用叫做“方言”的插件架构来帮助建造可重用且可扩展的编译器下部构造。

### 后端

截至版本16，LLVM已经支持多种后端指令集，包括IA-32、x86-64、ARM、Qualcomm Hexagon、LoongArch、M68K、MIPS、Nvidia 并行线程执行（在LLVM文档中也称为NVPTX）、PowerPC、AMD TeraScale微架构、新近的AMD GPU（在LLVM文档中也叫做AMDGPU）、SPARC、SystemZ、RISC-V、z/Architecture和XMOS。

LLVM还支持WebAssembly为其目标，使得编译后的程序可以在启用WebAssembly的环境中运行，比如Google Chrome/Chromium、Firefox、Microsoft Edge、Apple Safari或WAVM虚拟机。合规于LLVM的WebAssembly编译器，典型的支持多种语言的几乎不需修改的源代码，包括：C、C++、D、Rust、Nim、Kotlin和其它一些语言。

LLVM包含一个专门的MC模块，将机器指令在文字形式和机器码形式间相互转换。在之前LLVM依靠系统或是平台专门的工具链将汇编翻译为机器码。LLVM机器码的集成汇编器已经支持绝大多数LLVM的目标平台。

### 链接器

lld链接器子项目旨在为LLVM开发一个内置的，平台独立的链接器，去除对所有第三方链接器的依赖。在2017年5月，lld已经支持ELF、PE/COFF、Mach-O和WebAssembly。在lld支持不完全的情况下，用户可以使用其他项目，如GNU ld链接器。

lld支持链接时优化。当LLVM链接时优化被启用时，LLVM可以输出bitcode而不是本机代码，而本机代码生成由链接器优化处理。

### C++标准库

LLVM项目包含一个C++标准库的实现（libcxx），具有MIT许可证和UIUC许可证的双许可协议。

## 外部链接

- LLVM计划官方网站
- LLVM Project Blog
- LLVM: A Compilation Framework for Lifelong Program Analysis & Transformation —a published paper by Chris Lattner and Vikram Adve.
- LLVM Language Reference Manual —describes the LLVM intermediate representation.
- LLVM 2.0 Presentation —Google Tech Talk Presentation on LLVM 2.0
- Discussion of LLVM by John Siracusa at Ars Technica
- LLVM内部结构（The Architecture of Open Source Applications, Volume II - ISBN 9781105571817）
- LLVMLinux专案

## 基本资料

- 作者：Chris Lattner, Vikram Adve
- 开发者：LLVM开发团队
- 发行日期：2003年
- 软件版本周期：22.1.8
- 预览版本：22.1.8
- 操作系统：跨平台
- 类型：编译器
- 编程语言：C++
- 许可协议：带有LLVM例外的Apache许可证2.0