湖南大学SCCI并行计算组
LLVM 入门 01
LLVM概述
LLVM 入门 01
LLVM概述
一、LLVM介绍
LLVM 13.0.0 于2021年10月4日发布
LLVM 是什么?
LLVM的命名最早源自于底层虚拟机(Low Level Virtual Machine)的首字母缩写。
但是由于这个项目的范围并不局限于创建一个虚拟机,在LLVM开始成长之后,成为众多编译工具及低端工具技术的统称,使得这个名字变得更不贴切,开发者因而决定放弃这个缩写的意涵,现今LLVM已单纯成为一个品牌,适用于LLVM下的所有项目,包含LLVM中介码(LLVM IR)、LLVM调试工具、LLVM C++标准库等。
LLVM是一个以C++写成编译框架,其中包含一系列模块化的编译器组件和工具链,用来开发编译器前端和后端。
LLVM 历史
LLVM项目的发展起源于2000年伊利诺伊大学厄巴纳-香槟分校维克拉姆·艾夫 Vikram Adve 与克里斯·拉特纳(Chris Lattner)的研究,他们想要为所有静态及动态语言创造出动态的编译技术。LLVM是以BSD许可来发展的开源软件。
2005年,苹果公司雇用了克里斯·拉特纳及他的团队为苹果产品开发应用程序系统,LLVM 为现今 macOS 及 iOS 开发工具的一部分。
自9.0.0版本开始,LLVM使用带有LLVM额外条款的Apache许可证2.0进行授权。
2019年10月,LLVM项目的代码托管正式迁移到了GitHub。
LLVM功能简介
-
LLVM提供了一套适合编译器系统的中间语言(Intermediate Representation,IR)可以转换为目标平台相关的汇编语言代码。
-
LLVM可以和GCC工具链一起工作,允许它与为该项目编写的大量现有编译器一起使用。
-
LLVM还可以在编译、链接时生成可重新定位的代码(Relocatable Code),甚至在运行时生成二进制机器码。
LLVM性能
根据2011年的一项测试,GCC在执行时期的性能平均比LLVM高10%[13][14]。
根据2013年的一项测试,LLVM可以编译出接近GCC相同性能的执行码[15]。
二、LLVM子项目
- The LLVM Core libraries
- The Clang project
- The LLDB project
- The libc++ and libc++ ABI projects
- The compiler-rt project
- The MLIR subproject
- The OpenMP subproject
- The polly project
- The libclc project
- The klee project
- The LLD project
1. LLVM Core
LLVM最核心的部分。
包含了一个独立的 optimizer 并且支持代码生成。
以及最最核心的 LLVM IR。
2. Clang
(发音为/ˈklæŋ/)
是一个C、C++、Objective-C和Objective-C++编程语言的编译器前端。
它采用了LLVM作为其后端,由LLVM2.6开始,一起发布新版本。
它的目标是提供一个GNU编译器套装(GCC)的替代品,支持了GNU编译器大多数的编译设置以及非官方语言的扩展。
作者是克里斯·拉特纳(Chris Lattner),在苹果公司的赞助支持下进行开发,而源代码许可是使用类BSD的伊利诺伊大学厄巴纳-香槟分校开源码许可。
3.LLDB
LLDB项目构建在LLVM和Clang提供的库的基础上,以提供一个优秀的本地调试器 (native debugger)。
它使用了:
- Clang ASTs
- 表达式解析器
- LLVM JIT
- LLVM反汇编程序
在加载符号时,它比GDB速度更快,内存效率更高。
4. libc++ & libc++ ABI
LBC+++和LBC++ABI项目提供了C++标准库的标准一致性和高性能实现,包括对C++ 11和C++ 14的完全支持。
5. compiler-rt
compiler-rt(rt 指 runtime)用于为硬件不支持的低级功能提供特定于目标的支持。比如在32位的平台上实现64位的除法指令。
6. MLIR
MLIR 全称 Multi-Level Intermediate Representation for Compiler Infrastructure。
MLIR 深受 LLVM 的影响,并不折不扣地重用LLVM中许多优秀理念。
MLIR 由google团队于2019年提出并维护,用于tensorflow。
MLIR是一种表示格式和编译器实用工具库,介于模型表示和低级编译器/执行器(二者皆可生成硬件特定代码)之间。
预计 MLIR 会引起许多团队的注意,包括:
- 希望优化机器学习模型性能与内存消耗的编译器研究者和实现者
- 正在寻找一种方式将硬件连接至 TensorFlow 的硬件制造商,例如 TPU、手机中可移植的神经网络硬件以及其他自定义专用集成电路 (ASIC)
- 编写语言绑定的人士,他们希望能充分利用优化编译器和硬件加速
7.OpenMP
OpenMP子项目提供了一个OpenMP运行时支持,用于Clang中的OpenMP实现。
8.Polly
polly项目使用Polly模型实现了一系列缓存位置优化以及自动并行和矢量化的实现。
9.libclc
libclc项目旨在实现OpenCL标准库。
10.klee
klee的一个主要特性是,它可以在检测到错误时生成测试用例。
11.LLD
LLD项目是一个新的链接器。这是操作系统链接器的一个替代品,只是运行速度会更快。
三、LLVM组成
![[LLVM概述01.png]]
前端
Clang,它是一个新的编译器,同时支持C、Objective-C以及C++。
主要来自苹果电脑的支持,Clang的目的用以取代GCC系统底下的C/Objective-C编译器,在当代的系统,他较为容易与集成开发环境(IDE)集成,而且对于线程有更好的支持。
Clang从3.8版本开始已经支持OpenMP[17]。
中端
LLVM的核心是中间端表达式(Intermediate Representation,IR),一种类似汇编的底层语言。
IR是一种强类型的精简指令集(Reduced Instruction Set Computing,RISC),并对目标指令集进行了抽象。
例如,目标指令集的函数调用惯例被抽象为call和ret指令加上明确的参数。
另外,IR采用无限个数的暂存器,使用如%0,%1等形式表达。
LLVM支持三种表达形式:
- 人类可读的汇编
- 在C++中对象形式
- 序列化后的bitcode形式
例如一个"HelloWorld"程序的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
}
后端
至11.0版本,LLVM已经支持多种后端指令集,包括ARM、Qualcomm Hexagon(高通的DSP)、MIPS、Nvidia指令集(LLVM中称为NVPTX),PowerPC、AMD TeraScale、AMDGPU、RISC-V、x86。