首页
社区
课程
招聘
[原创]LLVM了解篇剧场版
发表于: 2018-11-26 13:38 11832

[原创]LLVM了解篇剧场版

2018-11-26 13:38
11832

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年编译器该有的模样!

 

学生们本来就头很大,龙书里其实啥都有,也啥都没有,以前只能啃啃GNUgcc,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,跟JavaJVM虚拟机一样,可是后来,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的强项

  1. LLVM使用具有严格定义语义的简单低级语言
  2. 它包括C和C++/Objective-C、Java,Scheme等众多的前端(其中也有一部分处于开发之中
  3. 它包括一个优化器,支持标量、过程间、配置文件驱动和一些简单循环的优化。
  4. 它支持完整编译模型,包括链接时,安装时,运行时和离线优化。
  5. LLVM完全支持准确的垃圾回收。
  6. LLVM代码生成器由于拥强大的目标描述语言所以可以支持众多架构。
  7. LLVM拥有丰富的文档,各种项目的介绍都非常丰富。
  8. 许多第三方用户声称LLVM易于使用和开发。例如,Stacker前端(现已不再维护)是在4天内由一个对LLVM小白编写的。此外,LLVM拥有很多帮助新手迅速上手的工具。
  9. LLVM正在积极开发中,并且不断得到扩展,增强和改进。
  10. LLVM 的条款非常开放,几乎是随意使用,只要别忘了带上他们的lisence就行。
  11. LLVM目前由多个商业公司使用,他们开发并贡献了许多扩展和新功能。

LLVM适合哪些人

  • 对C和C ++程序的编译时,链接时(过程间)和运行时转换感兴趣的编译器研究人员;
  • 对可移植的,与语言无关的指令集和编译框架感兴趣的虚拟机研究人员
  • 对编译器/硬件技术感兴趣的架构研究员
  • 对静态分析或插桩技术感兴趣的安全研究人员
  • 想要快速开发编译器原型的教师或开发人员
  • 希望获得更好性能的最终用户开发者

llvm安装和编译

我们聊一下从源码环境中编译生成llvm套件的可执行文件。这种方式对于深入学习llvm的读者来说,是必须要掌握的。

 

下载源代码,然后使用编译工具进行编译。编译工具可以是llvm,也可以是gcc。我们分别介绍一下。

 

源代码在http://releases.llvm.org/download.html官网进行下载:

 

macOS:使用llvm单独编译llvm

llvmclang都作为单独的组件以开源形式提供,可以单独编译它们,也可以组全在一起编译。我们先来看下,如何单独编译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编译过程类似,首先下载llvmclang的源码包并解压,把解压后的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/目录下,即可找到llvmclang`的工具。

$ 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的前后端组件及特性,希望大家持续的关注与喜欢。

 

以下为了解篇中,前面内容的一个目录:

 





 

到这里,本篇就结束了!


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2018-11-26 14:52 被非虫编辑 ,原因:
收藏
免费 1
支持
分享
打赏 + 5.00雪花
打赏次数 1 雪花 + 5.00
 
赞赏  junkboy   +5.00 2018/11/26
最新回复 (14)
雪    币: 11716
活跃值: (133)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
虫神威武
2018-11-26 13:56
0
雪    币: 222
活跃值: (185)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
3
占位 支持
2018-11-26 13:57
0
雪    币: 1564
活跃值: (3572)
能力值: ( LV13,RANK:420 )
在线值:
发帖
回帖
粉丝
4
make,学习了
2018-11-26 14:13
0
雪    币: 6999
活跃值: (1826)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
5
感谢分享
2018-11-26 14:16
0
雪    币: 64
活跃值: (67)
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
6
不要提 啥 大数据、人工智能、区块链这些潮流概念。实实在在 呆老家,挣1线的N倍收入才是关键。管他 LLVM 还是 虚拟机加壳。APP前端 后端 会做。成为全栈工程师  就可以秒 LLVM那点收入 。
 谢谢 ,接着 说出你们的故事。。。。。
最后于 2018-11-26 14:29 被天气编辑 ,原因:
2018-11-26 14:27
0
雪    币: 3907
活跃值: (5822)
能力值: ( LV12,RANK:200 )
在线值:
发帖
回帖
粉丝
7
天气 不要提 啥 大数据、人工智能、区块链这些潮流概念。实实在在 呆老家,挣1线的N倍收入才是关键。管他 LLVM  ...
34岁下岗。下一个
2018-11-26 15:21
0
雪    币: 277
活跃值: (3358)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
8
rc/lib/Support/Unix/Process.inc:40:10: fatal error: 'malloc.h' file not
      found
刚试了下。。
2018-11-26 19:18
0
雪    币: 3425
活跃值: (1479)
能力值: ( LV9,RANK:320 )
在线值:
发帖
回帖
粉丝
9
GCC大量的全局变量和宏很无语,国内的编译原理主要讲述编译器前端,中端和后端很少涉及,有点像是把龙书当教材,实际上编译原理前端的词法语法分析并没有很新的内容,而中端和后端很关键,精通它们能实现代码混淆、虚拟机实现和还原、反编译器等,推荐鲸书当教材。
2018-11-27 00:37
0
雪    币: 3425
活跃值: (1479)
能力值: ( LV9,RANK:320 )
在线值:
发帖
回帖
粉丝
10
GCC唯一比Clang/LLVM好的地方是后端支持的处理器更多,插件机制能够注册attribute,好像Clang 5以上版本的插件机制也能注册attribute。GCC的相关文档比Clang/LLVM少的太太太太太多了。
2018-11-27 00:52
0
雪    币: 58
活跃值: (153)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
2018-11-27 14:12
0
雪    币: 2832
活跃值: (1065)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
默默的顶下
2019-1-26 22:19
0
雪    币: 2709
活跃值: (1632)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
13
顶一个吧
2019-1-29 09:45
0
雪    币: 15
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
14
定一个
2019-4-24 16:01
0
雪    币: 14633
活跃值: (17729)
能力值: ( LV12,RANK:290 )
在线值:
发帖
回帖
粉丝
15
mark,就是不知道llvm从哪里开始学习。。。
2019-6-1 16:07
0
游客
登录 | 注册 方可回帖
返回
//