llvm入门feicong@llvm
频道首先介绍一下这个频道。为什么想要开这样一个频道,因为国内有关llvm
的资料实在是太缺乏了,缺乏到什么程度,没有一本(中文)图书是讲llvm
的,网上可以搜集到的资料也非常的少,要么就都是高深莫测,不适合新手入门,或者晦涩难懂的机器翻译,佶屈聱牙,恍若天书。
另一方面,现在已经全面进入了移动互联网时代,移动App的普及,带来的App安全保护和加固方面的需求也愈发强烈,安全从业人员与黑产的对抗早已上升到编译器层面,Native
级别的花指令、字符串混淆和控制流混淆、虚拟机等加固等产品的出现,为厂商保护自己的知识产权,提高产品的安全级别,提高被破解的难度和成本,做出了不可磨灭的贡献。
更何况现在都8102
年了,移动战略那都是明日黄花,市面上最火热的已经是大数据
、人工智能
和NPU
了。在人工智能算法陷入性能瓶颈,大家都在思考如何将硬件的特性发挥到极致的今天,在编译器算法的研究上花点功夫,提高软硬件协同工作的性能,是今后未来芯片厂商所要关注的一个重点。这也是为什么高通、英特尔、ARM、华为等芯片公司长期占据着llvm
基金会赞助商榜首的原因。
昨天碰巧看到知乎大神蓝色刚刚出炉的一篇文章《手把手带你遨游TVM》 (当然他也是llvm
坚定地拥护者,写了很多llvm
的文章 ),介绍了多种AI
训练框架Training
之后的结果在不同硬件上的Inference
问题,如Intel CPU / Intel GPU / ARM CPU / ARM GPU / NV GPU / FPGA / AI
芯片等,而要在这多种多样的设备中都保持一个高效的Inference性能,其实是一件很有挑战的事情,这里面就涉及到了软硬件结合的问题,自古就是各种性能优化关注的重点问题。
让我们回到主题上来,编译器技术如此重要,国内资料却如此缺乏。资料基本上全是英语,《编译原理》本身也是一门CS
专业需要到大三才会开始授学的专业课。而且说实话,国内的编译原理的教育可以说是非常失败的,学生上完课跟没上一个样的情况非常多,可能也跟连老师都没有动手操作过一个编译器有关。学生如果想要切实的学点知识的话,又面临着资料匮乏的问题,恶性循环,如此往复。
所以迫切需要有人来打破这个僵局,这也是我做这个频道的初衷,希望可以凭借我们大家的力量,将feicong@llvm
这个圈子做好、运营好、运转好。我将在这个方向上持续地投入时间和精力,也希望大家可以支持我,加入到圈子中来,一起学习和讨论llvm
知识。编译器是一门非常底层的技术,不管您是做科研、还是做框架,做开发、还是做安全,在编译器方向有所建树会为您的简历增光不少,评级评优也好,升职跳槽也好,会这门“手艺”都非常吃香,想象一下HR或者CTO或者技术leader拿着您的简历,上面写着“熟悉llvm
编译器及编译原理”的场景,hold住二面现场从未如此简单。
这将是你这么多年来,花的最值的五十块钱!!
加入方法:可以直接在看雪学院学习:链接(https://www.kanxue.com/book-37.htm)
或者直接加我的知识星球,获取pdf
和源代码:
或者欢迎加我的微信(ID:fe1c0ng)或微博(id:非虫)
我们将会从实际的操作和代码的角度出发,对以下主题进行剖析。
未来也打算开一些线下meetup和现场教学,当然圈内的你肯定是享有优先体验权!还在等什么?赶紧拿起微信扫一扫吧!
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自己的协议 ,几乎就是Do What The Fuck You Want To Do Lisence ,你可以do what the fuck you want to do
,唯一的要求就是别忘了提一下他们的LLVM lisence
。
在先进的“WTFPL” license帮助下,产业界迅速地扔掉了gcc,拥抱更加开放的、可以拿来随便改的llvm,影响迅速扩大,2012年llvm被授予ACM软件系统奖,正是对llvm的高度认可。反之由于产业界的高度认同及其回哺,llvm从学术界的懵懂、迅速成长为具有工业级稳定性、前所未有的成熟度和极高效率的编译器。
趣闻:Chris Latter
本来只是想写一个底层的虚拟机,这也是LLVM
名字的由来,low level virtual machine
,跟Java
的JVM
虚拟机一样,可是后来,llvm从来没有被用作过虚拟机,哪怕LLVM
的名气已经传开了。所以人们决定仍然叫他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组件的快速开发。
LLVM的强项
LLVM使用具有严格定义语义的简单低级语言 。
它包括C和C++/Objective-C、Java,Scheme等众多的前端(其中也有一部分处于开发之中
它包括一个优化器,支持标量、过程间、配置文件驱动和一些简单循环的优化。
它支持完整编译模型,包括链接时,安装时,运行时和离线优化。
LLVM完全支持准确的垃圾回收。
LLVM代码生成器由于拥强大的目标描述语言所以可以支持众多架构。
LLVM拥有丰富的文档,各种项目的介绍都非常丰富。
许多第三方用户声称LLVM易于使用和开发。例如,Stacker前端(现已不再维护)是在4天内由一个对LLVM小白编写的。此外,LLVM拥有很多帮助新手迅速上手的工具。
LLVM正在积极开发中,并且不断得到扩展,增强和改进。
LLVM 的条款非常开放,几乎是随意使用,只要别忘了带上他们的lisence就行。
LLVM目前由多个商业公司使用,他们开发并贡献了许多扩展和新功能。
LLVM适合哪些人
对C和C ++程序的编译时,链接时(过程间)和运行时转换感兴趣的编译器研究人员;
对可移植的,与语言无关的指令集和编译框架感兴趣的虚拟机研究人员
对编译器/硬件技术感兴趣的架构研究员
对静态分析或插桩技术感兴趣的安全研究人员
想要快速开发编译器原型的教师或开发人员
希望获得更好性能的最终用户开发者
llvm
安装和编译我们聊一下从源码环境中编译生成llvm
套件的可执行文件。这种方式对于深入学习llvm
的读者来说,是必须要掌握的。
下载源代码,然后使用编译工具进行编译。编译工具可以是llvm
,也可以是gcc
。我们分别介绍一下。
源代码在http://releases.llvm.org/download.html 官网进行下载:
macOS
:使用llvm
单独编译llvm
llvm
与clang
都作为单独的组件以开源形式提供,可以单独编译它们,也可以组全在一起编译。我们先来看下,如何单独编译llvm
。
执行如下命令,下载与解压llvm
的源码。
$ wget http://releases.llvm.org/7.0.0/llvm-7.0.0.src.tar.xz
--2018-10-23 22:02:46-- http://releases.llvm.org/7.0.0/llvm-7.0.0.src.tar.xz
正在解析主机 releases.llvm.org (releases.llvm.org)... 151.101.42.49, 2a04:4e42:6::561
正在连接 releases.llvm.org (releases.llvm.org)|151.101.42.49|:80... 已连接。
已发出 HTTP 请求,正在等待回应... 302 Found
位置:http://117.143.109.133/cache/releases.llvm.org/7.0.0/llvm-7.0.0.src.tar.xz?ich_args2=139-23220102015663_6b4dad2fb2c1b96f7fc8786bd843192d_10001002_9c89602cd4c3f2d2973a518939a83798_c6988e40d0518b9e703b7a4f6f4dd23a [跟随至新的 URL]
--2018-10-23 22:02:47-- http://117.143.109.133/cache/releases.llvm.org/7.0.0/llvm-7.0.0.src.tar.xz?ich_args2=139-23220102015663_6b4dad2fb2c1b96f7fc8786bd843192d_10001002_9c89602cd4c3f2d2973a518939a83798_c6988e40d0518b9e703b7a4f6f4dd23a
正在连接 117.143.109.133:80... 已连接。
已发出 HTTP 请求,正在等待回应... 200 OK
长度:28324368 (27M) [application/octet-stream]
正在保存至: “llvm-7.0.0.src.tar.xz”
llvm-7.0.0.src.tar.xz 21%[======================> ] 5.86M 1.08MB/s 剩余 21s
$ tar -xvf llvm-7.0.0.src.tar.xz
注意:编译不可以在解压后的文件夹内部编译,需要在外部新建一个文件夹,否则编译会失败!
执行以下命令,新建mybuilder目录,并进行编译配置。
$ mkdir mybuilder
$ cd mybuilder
$ cmake ../llvm-7.0.0.src/
PS:如果没有cmake
可以先用brew install cmake
安装一下,然后再执行cmake
命令。
然后再执行以下命令开始编译:
$ cmake --build
然后就开始编译了。
CPU占用率一直不高,稳定在比较低的状态。一直到结束都不高,大概需要一小时左右。
完成之后进来看看:
$ cd bin
$ ls
FileCheck llvm-cat llvm-dwp llvm-modextract llvm-readobj not
bugpoint llvm-cfi-verify llvm-exegesis llvm-mt llvm-rtdyld obj2yaml
count llvm-config llvm-extract llvm-nm llvm-size opt
dsymutil llvm-cov llvm-go llvm-objcopy llvm-special-case-list-fuzzer sancov
llc llvm-cvtres llvm-isel-fuzzer llvm-objdump llvm-split sanstats
lli llvm-cxxdump llvm-lib llvm-opt-fuzzer llvm-stress verify-uselistorder
lli-child-target llvm-cxxfilt llvm-link llvm-opt-report llvm-strings yaml-bench
llvm-PerfectShuffle llvm-demangle-fuzzer llvm-lit llvm-pdbutil llvm-strip yaml2obj
llvm-ar llvm-diff llvm-lto llvm-profdata llvm-symbolizer
llvm-as llvm-dis llvm-lto2 llvm-ranlib llvm-tblgen
llvm-bcanalyzer llvm-dlltool llvm-mc llvm-rc llvm-undname
llvm-c-test llvm-dwarfdump llvm-mca llvm-readelf llvm-xray
$ ./llvm-as -version
LLVM (http://llvm.org/):
LLVM version 7.0.0
DEBUG build with assertions.
Default target: x86_64-apple-darwin16.7.0
Host CPU: broadwell
当然,llvm
后端要配合clang
前端才能使用,clang
前端的编译方法也跟llvm
类似。
macOS
:使用llvm
混合编译llvm
&&clang
大部分流程跟上文中macOS
系统下用llvm
编译过程类似,首先下载llvm
和clang
的源码包并解压,把解压后的clang
的源码包重命名,并移动到llvm-7.0.0.src/tools/
目录下,最终效果为llvm-7.0.0.src/tools/clang/
。
然后在build文件夹里运行$ cmake -G "Unix Makefiles" ../llvm-7.0.0.src
命令,cmake
会检查编译环境,如果没有报错(有报错的解决报错),直接运行make
命令即可开始编译。
编译完成之后,在build/bin/目录下,即可找到
llvm和
clang`的工具。
$ ls
FileCheck llc llvm-go llvm-size
arcmt-test lli llvm-isel-fuzzer llvm-special-case-list-fuzzer
bugpoint lli-child-target llvm-lib llvm-split
c-arcmt-test llvm-PerfectShuffle llvm-link llvm-stress
c-index-test llvm-ar llvm-lit llvm-strings
clang llvm-as llvm-lto llvm-strip
clang++ llvm-bcanalyzer llvm-lto2 llvm-symbolizer
clang-7 llvm-c-test llvm-mc llvm-tblgen
clang-check llvm-cat llvm-mca llvm-undname
clang-cl llvm-cfi-verify llvm-modextract llvm-xray
clang-cpp llvm-config llvm-mt not
clang-diff llvm-cov llvm-nm obj2yaml
clang-format llvm-cvtres llvm-objcopy opt
clang-func-mapping llvm-cxxdump llvm-objdump sancov
clang-import-test llvm-cxxfilt llvm-opt-fuzzer sanstats
clang-offload-bundler llvm-demangle-fuzzer llvm-opt-report scan-build
clang-refactor llvm-diff llvm-pdbutil scan-view
clang-rename llvm-dis llvm-profdata set-xcode-analyzer
clang-tblgen llvm-dlltool llvm-ranlib verify-uselistorder
count llvm-dwarfdump llvm-rc yaml-bench
diagtool llvm-dwp llvm-readelf yaml2obj
dsymutil llvm-exegesis llvm-readobj
hmaptool llvm-extract llvm-rtdyld
$ ./clang --version
clang version 7.0.0 (tags/RELEASE_700/final)
Target: x86_64-apple-darwin16.7.0
Thread model: posix
InstalledDir: /Users/userid/Desktop/mybuilder/bin/.
了解篇目录一览第一大部分的了解篇已经进入了尾声,可能后面还会有小的更新,但整体上,经过这几篇的讲解,相信大家对llvm的功能与能力已经有了比较基础的认知。在后面的上手篇内容当中,我们将深入讨论llvm的前后端组件及特性,希望大家持续的关注与喜欢。
以下为了解篇中,前面内容的一个目录:
到这里,本篇就结束了!
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2018-11-26 14:52
被非虫编辑
,原因: