本套课程大致的目录如下:长期更新中:
![](/upload/attach/201812/201812031421_XNSP3W7WDMNJDJS.png)
* [LLVM概论](#llvm概论)
* [起源与发展](#起源与发展)
* [苹果与`llvm`](#苹果与llvm)
* [LLVM主要的子项目](#llvm主要的子项目)
* [LLVM的功能介绍](#llvm的功能介绍)
* [LLVM的强项](#llvm的强项)
* [LLVM适合哪些人](#llvm适合哪些人)
* [更多内容,尽在`feicong@llvm`知识星球!](#更多内容尽在feicongllvm知识星球)
## LLVM概论
### 起源与发展
`LLVM`项目的起源也是来源于`Chris Lattner`个人对编译器的兴趣,这种模式在欧美非常普遍,比如`Linux`的诞生就是,当时还是大二学生的**大嘴巴**托瓦兹个人想要重新造一个`*nix`内核,结果一大堆人在群里讨论得津津有味,然后大家纷纷建言献策。说明对`kernel`感兴趣的人特别多,群众基础才是大基础,群众路线才是XXXXX,(此处省略马哲课文献100页)。
同样,很多大学生学完编译原理(`Complier Principles Technology & Tools`,龙书)之后,满身才华没有用武之地,(这浑身按耐不住的查克拉,是什么感觉。。。)所以想要找点类似的事情干,满足一下自己的好奇心,在老外眼里叫做 **“hack something”** ,当然这种文化在中国是没有的,`paper`、建模和导师是压在莘莘学子身上不断摩擦的三座大山。
越来越多的人提出了一大堆建议,并且还贡献了一堆代码,对于歪果仁来说,你这里做的不对,不指正你一下,是很难受的一件事情。所以越往后这个项目越来越大,`bug`也越来越少,可用性越来越强,然后很多商业机构看到这里这个编译器实现的挺好的嘛,而且还是开源的,我们也是鲁迅“拿来主义”的坚定奉行者,来来来,新来的你们仨,周末回家带上笔记本哈~下周一我们就决定 **"All IN"** `LLVM`!
其实在硅谷,很多高科技公司的创始人,本来就是学校的老师或教授。教授手下有几家科技企业,简直是硅谷教授的标配。教授看到越来越多的公司,在项目中使用`LLVM`编译器,巧了马上又要教龙书了(这本书封面是一批Dragon)(PS:外国文化的`Dragon`和中国龙不是一个物种)(龙书从1982年出版到现在,已经36年了,教授每年都要教),教授心里想,教泥煤的教,龙书自己去看,我们来聊聊`LLVM`!这才是`8102`年编译器该有的模样!
学生们本来就头很大,龙书里其实啥都有,也啥都没有,以前只能啃啃`GNU`的`gcc`,gcc的历史跟龙书一样悠久,那代码读起来那个酸爽,就跟老奶奶的裹脚布一样,同学们看一次吐一次。要不是因为其他没得选,开源的(貌似)就它一个!而且使用最广泛的也是它。尽管如此,长年累月积累下来的架构的更迭和设计的混乱,没个教授或者博士的经验,根本读起来都费劲。
那难道就没有一个现代一点的编译器了么?有,那就是llvm!
跟gcc比起来,llvm算是一个“人写的”、“给人看的”编译器。llvm清爽、干净、模块化,gcc用的是单体结构,这玩意儿已经不适合现代人来阅读了。llvm用的`C++`,gcc用的c,哪个更现代化一目了然。学生们非常欢迎llvm,通过学习llvm来理解编译原理往往事半功倍,倍儿轻松,用起来也得心应手,这才是llvm得以普及和迅速扩大影响的关键!llvm在学术界的成功可以说是实践与理论之间差距不断缩小的结果。
后来学生们走上了社会,比如去苹果公司上班儿了,当然还是继续使用llvm编译器啦,这时候就涉及到了许可证的问题。gcc用的是GPL许可证,GPL是有名的病毒协议,一日GPL,终身GPL,你用了它的作品,你自己也得免费开源,那我还用你个毛,我产品都送你好了。这在商业环境下是不可能的,而llvm自己的[协议](http://releases.llvm.org/7.0.0/LICENSE.TXT),几乎就是[Do What The Fuck You Want To Do Lisence](http://www.wtfpl.net/),你可以`do what the fuck you want to do` ,唯一的要求就是别忘了提一下他们的`LLVM lisence`。
在先进的“WTFPL” lisence帮助下,产业界迅速地扔掉了gcc,拥抱更加开放的、可以拿来随便改的llvm,影响迅速扩大,2012年llvm被授予ACM软件系统奖,正是对llvm的高度认可。反之由于产业界的高度认同及其回哺,llvm从学术界的懵懂、迅速成长为具有工业级稳定性、前所未有的成熟度和极高效率的编译器。
>趣闻:`Chris Latter`本来只是想写一个底层的虚拟机,这也是`LLVM`名字的由来,`low level virtual machine`,跟`Java`的`JVM`虚拟机一样,可是后来
llvm从来没有被用作过虚拟机,哪怕`LLVM`的名气已经传开了。所以人们决定仍然叫他`LLVM`,更多的时候只是当作“商标”一样的感觉在使用,其实它跟虚拟机没有半毛钱关系。
### 苹果与`llvm`
LLVM是Apple官方支持的编译器,而该编译器的前端是Clang,这两个工具都被集成到了Xcode里面。在这篇文章中,我们来了解一下LLVM和Clang背后的故事。
在很长一段时间里,Apple一直使用GCC作为官方的编译器。GCC作为开源世界的编译器标准一直做得不错,但Apple对编译工具提出了更高的要求。
仗着自己在开源社区的地位,GCC 开发者对Apple的Objective-C语言新增的很多特性不予理睬,甚至当Apple想做的很多功能需要用模块化的方式来调用 GCC时,GCC却一直不给做。一般的公司遇到这种情况,可能都有些受不了,何况是乔布斯领导的Apple呢?
与GCC的不和让Apple一直在寻找一个高效的、模块化的、协议更放松的开源的编译器替代品。最终,Apple相中了Chris Lattner的LLVM。
现在依然就职于Apple的Chris Lattner可是一位大神,他于2000年毕业于俄勒冈州波特兰大学计算机科学专业,同年前往UIUC(伊利诺伊大学厄巴纳香槟分校),攻读计算机科学硕士和博士学位。在UIUC期间,他的GPA是4.0(满分),并不断地研究探索关于编译器的未知领域,发表了多篇论文。在硕士毕业论文中,他提出了一套完整的在编译时、链接时、运行时甚至是在闲置时优化程序的编译思想,奠定了LLVM的基础。
LLVM在Chris Lattner念博士时更加的成熟。首先,LLVM使用GCC作为前端来对用户程序进行语义分析产生 IF(Intermidiate Format),然后,LLVM使用分析结果完成代码优化和生成。这项研究让Chris Lattner在2005年毕业的时候,成为了小有名气的编译器专家。他也因此早早地被Apple相中,成为其编译器项目的骨干。
进入Apple之后,Chris Lattner首先在OpenGL小组做代码优化,把LLVM运行时的编译架在OpenGL栈上,这样OpenGL栈能够产出更高效率的图形代码。这个强大的OpenGL实现被用在了后来发布的Mac OS X 10.5上。同时,LLVM 的链接优化被直接加入到Apple的代码链接器上。
一个好的工具,必须要有用武之地。几年之后,LLVM的机会就来了。Mac OS X 10.6 Snow Leopard的新功能,完全得益于LLVM的技术,而这一个版本,也是将LLVM推向真正成熟的重大机遇。
“一个篱笆三个桩,一个好汉三个帮”,LLVM能够实现很多华丽的功能,要归功于LLVM自身的新前端——Clang。
GCC系统庞大而笨重,因此,Apple决定从零开始写C、C++、Objective-C语言的前端Clang,以求完全替代掉GCC。
Clang于2007年开始开发,C编译器最早完成,在2009年的时候,Objective-C编译器已经完全可以用于生产环境,而在一年之后,Clang基本实现了对C++编译的支持。
Clang一个重要的特性是编译快速、占内存少,而代码质量还比GCC来得高。得益于本身健壮的架构和Apple的大力支持,Clang越来越全能,支持的项目越来越多,如`Mac OS X 10.6`时代的Xcode和Interface Builder等,皆由Clang编译。Clang的加入也代表着LLVM真正走向成熟。
此外,Clang有一个重要的衍生项目是静态分析工具,能够通过自动分析程序的逻辑,在编译时就找出程序可能的bug,这个功能叫做ARC。ARC的实现让当时的广大开发者们大为惊愕。
除了LLVM核心和Clang以外,LLVM还包括一些重要的子项目,比如一个原生支持调试多线程程序的调试器LLDB和一个C++的标准库libstdc++。不光是Apple,很多的项目和编程语言都从LLVM中取得了关键性的技术。
从`LLVM`的发展历程中可以看到,LLVM在短短五年内(2005年-2010年)取得了快速的发展,这充分反映了Apple对于产品技术的远见和超强的执行力。也正是因为这样,LLVM一跃成为了最领先的开源软件技术之一。而大神`Chris Lattner`也在2010年赢得了`Programming Languages Software Award`(程序设计语言软件奖)。
大神的故事还没有结束,Chris Lattner于2010年7月开始着手Swift编程语言的设计工作,他实现了该语言的大部分基础架构。2011年末,又有几位大神加入了该项目。2013年7月,Swift项目成为了苹果开发者工具部门的主要焦点。在2014年6月2日,Swift语言正式发布,Chris Lattner及其工作又一次赢得了广大开发者们惊愕的目光。目前,Chris Lattner是苹果公司开发者工具部门的主管,领导Xcode、Instruments和编译器团队。
我们来看下`Xcode`逐渐摈弃gcc和拥抱llvm的过程。
```
Xcode3之前,用的是GCC
Xcode3,GCC仍然保留,但是也推出了LLVM,苹果推荐LLVM-GCC混合编译器,但还不是默认编译器
Xcode4,LLVM-GCC成为默认编译器,但GCC仍保留
Xcode4.2,LLVM3.0成为默认编译器,纯用GCC不复可能
Xcode4.6,LLVM升级到4.2版本
Xcode5,LLVM-GCC被遗弃,新的编译器是LLVM5.0,从GCC过渡到LLVM的时代正式完成
```
### LLVM主要的子项目
前文阐述了,LLVM现在已经类似于一个商标,是 **一系列模块化和可重用的编译器和工具链技术的集合** 。那`LLVM`主要的子项目有哪些呢?
1. LLVM核心库提供了一个源代码无关和目标架构无关的独立配置器,以及许多流行CPU(以及一些不太常见的CPU)的架构后端生成支持。这些库是围绕一个称为LLVM中间码(IR)的的工具来构建的。`LLVM`核心库的文档特别详细,所以用LLVM作为优化器和代码生成器来形成自己的语言(或移植现有编译器)是非常容易的。
2. Clang是一个LLVM“原配”的`C/C ++/Objective-C`编译器,旨在提供高效快速的编译效率(**例如,在debug模式下编译Objective-C代码时比GCC快3倍**),风格良好的warning和error信息,以及作为开源库来构建第三方语言的编译器。`Clang Static Analyzer`是一个静态的自动查找代码中的错误的工具,是使用Clang前端作为依赖库来解析`C/C++`代码的工具类型的一个很好的例子。
![](/upload/attach/201811/223786_PR4Y6RQ6BXP7NJ9.png)
![](/upload/attach/201811/223786_NKBJWX5KPTDPB2Q.png)
3. LLDB项目以LLVM和Clang提供的库为基础,提供了一个出色的`native`级别调试器。它使用`Clang AST`和表达式解析器、LLVM JIT、LLVM反汇编器等元生组件,所以跟它们配合的很好。在加载调试符号时,它也比GDB快多了而且能够更好的节约内存。
4. `libc ++`和`libc ++ ABI`项目提供了符合`C ++`标准库的高性能实现,而且还包括对`C ++ 11`和`C ++ 14`的完整支持。
5. `compiler-rt`项目为动态测试工具(如AddressSanitizer,ThreadSanitizer,MemorySanitizer和DataFlowSanitizer)提供了运行时库的实现。它还为像`“__fixunsdfdi”`这样的低级代码生成器支持进程提供高层面的调整实现,也提供当目标没有用于实现核心IR操作的短序列本机指令时生成的其他调用。
6. `OpenMP`项目提供了一个OpenMP运行时,用于Clang中的OpenMP实现。
7. `polly`项目使用多面体模型实现一组缓存局部优化以及自动并行和矢量化。
8. `libclc`项目旨在实现OpenCL标准库。
9. `klee`项目实现了一个“符号虚拟机”,它使用一个定理证明器来尝试评估程序中的所有动态路径,以发现错误并证明函数的属性。 klee的一个主要特性是它可以在检测到错误时生成测试用例。
10. `SAFECode`项目是用于C / C ++程序的内存安全编译器。 它通过运行时检查来检测代码,以便在运行时检测内存安全错误(例如,缓冲区溢出)。 它可用于保护软件免受安全攻击,也可用作`Valgrind`等内存安全错误调试工具。
11. `LLD`项目是一个新的链接器。 可以作为系统链接器的直接替代品,有更快的运行速度。
除了LLVM的官方子项目之外,还有许多其他项目使用LLVM的组件来执行各种任务。通过这些外部项目,您可以使用LLVM来编译`Ruby`,`Python`,`Haskell`,`Java`,`D`,`PHP`,`Pure`,`Lua`和许多其他语言。 LLVM的主要优势就是它功能众多、灵活和模块化,这就是为什么它被用于各种各样的不同任务:从轻量级JIT编译嵌入式语言(如Lua)到编译Fortran代码以实现大规模超级电脑,它都可以胜任。
与其他开源项目一样,LLVM拥有广泛而友好的社区,如果读者有兴趣参与其中,可以先浏览LLVM博客然后注册`LLVM Developer`邮件列表。然后看如何发送补丁,获取提交权限以及版权和许可主题的信息,可以读一下LLVM开发人员政策。
### LLVM的功能介绍
以`C/C++`为例,LLVM编译系统包括以下内容:
- 一个良好的前端;`GCC 4.2解析器`能解析的语言,比如`C,C ++,Objective-C,Fortran`等,它都能提供同能能力的支持;另外它还能支持一些GCC的扩展插件。
- LLVM指令集的稳定实现;不管代码处于何种状态,都可以在汇编(ASCII)和字节码(二进制)之间自由转换。
- 一个功能强大的`Pass`管理系统,它根据它们的依赖性自动对`Pass`(包括分析,转换和代码生成Pass)进行排序,并将它们管道化以提高效率。
- 广泛的全局标量优化。
- 包含丰富的分析和转换的链接时过程优化框架,包括复杂的完整程序指针分析、调用图构建以及对配置文件引导优化的支持。
- 易于重定向的代码生成器,目前支持X86,X86-64,PowerPC,PowerPC-64,ARM,Thumb,SPARC,Alpha,CellSPU,MIPS,MSP430,SystemZ和XCore。
- Just-In-Time(JIT)即时编译器,目前支持X86,X86-64,ARM,AArch64,Mips,SystemZ,PowerPC和PowerPC-64。
- 支持生成DWARF调试信息。
>DWARF - Object files and linked products will use DWARF as the debug information format. [dwarf]
DWARF with dSYM File - Object files and linked products will use DWARF as the debug information format, and Xcode will also produce a dSYM file containing the debug information from the individual object files (except that a dSYM file is not needed and will not be created for static library or object file products). [dwarf-with-dsym]
- 用于测试和生成除上面列出的目标之外的目标的本机代码的C后端。
- 与gprof类似的分析系统。
- 具有许多基准代码和应用程序的测试框架。
- API和调试工具,以简化LLVM组件的快速开发。
![](/upload/attach/201811/223786_M9G9ETTWNHNZP65.png)
### LLVM的强项
1. LLVM使用具有严格定义语义的[简单低级语言](https://llvm.org/docs/LangRef.html)。
2. 它包括C和C++/Objective-C、Java,Scheme等众多的前端(其中也有一部分处于开发之中
![](/upload/attach/201811/223786_QWKMMDVWJAQZJ57.png)
3. 它包括一个优化器,支持标量、过程间、配置文件驱动和一些简单循环的优化。
4. 它支持完整编译模型,包括链接时,安装时,运行时和离线优化。
5. LLVM完全支持准确的垃圾回收。
6. LLVM代码生成器由于拥强大的目标描述语言所以可以支持众多架构。
7. LLVM拥有丰富的文档,各种项目的介绍都非常丰富。
8. 许多第三方用户声称LLVM易于使用和开发。例如,Stacker前端(现已不再维护)是在4天内由一个对LLVM小白编写的。此外,LLVM拥有很多帮助新手迅速上手的工具。
9. LLVM正在积极开发中,并且不断得到扩展,增强和改进。
10. LLVM 的条款非常开放,几乎是随意使用,只要别忘了带上他们的lisence就行。
11. LLVM目前由多个商业公司使用,他们开发并贡献了许多扩展和新功能。
### LLVM适合哪些人
- 对C和C ++程序的编译时,链接时(过程间)和运行时转换感兴趣的编译器研究人员;
- 对可移植的,与语言无关的指令集和编译框架感兴趣的虚拟机研究人员
- 对编译器/硬件技术感兴趣的架构研究员
- 对静态分析或插桩技术感兴趣的安全研究人员
- 想要快速开发编译器原型的教师或开发人员
- 希望获得更好性能的最终用户开发者
参考来源:
1. [Getting Started with LLVM Core Libraries](https://e.jd.com/30370568.html)
2. [简述 LLVM 与 Clang 及其关系](https://blog.csdn.net/xhhjin/article/details/81164076)
3. [LLVM与Clang的一些事儿](https://www.jianshu.com/p/7e2c65dcf632)
4. [LLVM和Clang背后的故事](https://blog.csdn.net/zhouzhaoxiong1227/article/details/52166942)
5. [你或许应该知道的LLVM](https://blog.csdn.net/khlljm/article/details/51822973)
6. [LLVM与Clang-开发者的惊愕](https://blog.csdn.net/sodaslay/article/details/44650339)
7. [llvm.org](https://llvm.org/)
或者欢迎加我的微信(ID:fe1c0ng)或微博(id:非虫)