llvm入门篇

栏目: 服务器 · 编程工具 · 发布时间: 5年前

内容简介:首先介绍一下这个频道。为什么想要开这样一个频道,因为国内有关另一方面,现在已经全面进入了移动互联网时代,移动App的普及,带来的App安全保护和加固方面的需求也愈发强烈,安全从业人员与黑产的对抗早已上升到编译器层面,更何况现在都

首先介绍一下这个频道。为什么想要开这样一个频道,因为国内有关 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性能,其实是一件很有挑战的事情,这里面就涉及到了软硬件结合的问题,自古就是各种性能优化关注的重点问题。

llvm入门篇

让我们回到主题上来,编译器技术如此重要,国内资料却如此缺乏。资料基本上全是英语,《编译原理》本身也是一门 CS 专业需要到大三才会开始授学的专业课。而且说实话,国内的编译原理的教育可以说是非常失败的,学生上完课跟没上一个样的情况非常多,可能也跟连老师都没有动手操作过一个编译器有关。学生如果想要切实的学点知识的话,又面临着资料匮乏的问题,恶性循环,如此往复。

所以迫切需要有人来打破这个僵局,这也是我做这个频道的初衷,希望可以凭借我们大家的力量,将 feicong@llvm 这个圈子做好、运营好、运转好。我将在这个方向上持续地投入时间和精力,也希望大家可以支持我,加入到圈子中来,一起学习和讨论 llvm 知识。编译器是一门非常底层的技术,不管您是做科研、还是做框架,做开发、还是做安全,在编译器方向有所建树会为您的简历增光不少,评级评优也好,升职跳槽也好,会这门“手艺”都非常吃香,想象一下HR或者CTO或者技术leader拿着您的简历,上面写着“熟悉 llvm 编译器及编译原理”的场景,hold住二面现场从未如此简单。

这将是你这么多年来,花的最值的五十块钱!!

llvm入门篇

或者欢迎加我的微信(ID:fe1c0ng)或微博(id:非虫)

我们将会从实际的操作和代码的角度出发,对以下主题进行剖析。

llvm入门篇

未来也打算开一些线下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入门篇

LLVM的强项

  1. LLVM使用具有严格定义语义的简单低级语言。
  2. 它包括C和C++/Objective-C、Java,Scheme等众多的前端(其中也有一部分处于开发之中
    llvm入门篇
  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 。我们分别介绍一下。

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

llvm入门篇

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 命令。

llvm入门篇

然后再执行以下命令开始编译:

$ cmake --build
复制代码
llvm入门篇

然后就开始编译了。

llvm入门篇

CPU占用率一直不高,稳定在比较低的状态。一直到结束都不高,大概需要一小时左右。

llvm入门篇

完成之后进来看看:

$ 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 命令即可开始编译。

llvm入门篇

编译完成之后,在 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/.
复制代码

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

深度探索C++对象模型

深度探索C++对象模型

[美] Stanley B. Lippman / 侯捷 / 华中科技大学出版社 / 2001-5 / 54.00元

这本书探索“对象导向程序所支持的C++对象模型”下的程序行为。对于“对象导向性质之基础实现技术”以及“各种性质背后的隐含利益交换”提供一个清楚的认识。检验由程序变形所带来的效率冲击。提供丰富的程序范例、图片,以及对象导向观念和底层对象模型之间的效率测量。一起来看看 《深度探索C++对象模型》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具