LLVM每日谈之一 LLVM是什么

LLVM每日谈之一 LLVM是什么,第1张

写在前面的话:

最近接触llvm比较多,在这个上面花了不少的时间。感觉llvm要完全理解透是个很不容易的事情,需要在学习过程中好好的整理下自己的思路。刚好又阅读了开源项目Storm的作者Nathan Marz的博客《You should blog even if you have no readers》,就打开自己的blog,开始了这个llvm每日谈的系列。希望自己能坚持的久一点,多写写llvm的每个方面,多写写自己的理解。

llvm是low level virtual machine的简称,其实是一个编译器框架。llvm随着这个项目的不断的发展,已经无法完全的代表这个项目了,只是这种叫法一直延续下来。

llvm是一个开源的项目。它最早的时候是Illinois的一个研究项目,主要负责人是Chris Lattner,他现在就职于Apple. Apple 目前也是llvm项目的主要赞助者之一。

llvm的主要作用是它可以作为多种语言的后端,它可以提供可编程语言无关的优化和针对很多种CPU的代码生成功能。此外llvm目前已经不仅仅是个编程框架,它目前还包含了很多的子项目,比如最具盛名的clang.

llvm的优点是开源,有一个表达形式很好的IR语言,模块化作的特别好。

llvm这个框架目前已经有基于这个框架的大量的工具可以使用。

llvm的官方网站地址是:llvm.org。在这里可以下载最新的发布代码,也可以找到介绍llvm的相关文档。

附录:llvm目前支持的工具(描述来自网络)

llvm-as 将人类可读的 .ll 文件汇编成字节代码

llvm-dis 将字节代码文件反编成人类可读的 .ll 文件

opt 在一个字节代码文件上运行一系列的 LLVM 到 LLVM 的优化

llc 为一个字节代码文件生成本机器代码

lli 直接运行使用 JIT 编译器或者解释器编译成字节代码的程序

llvm-link 将几个字节代码文件连接成一个

llvm-ar 打包字节代码文件

llvm-ranlib 为 llvm-ar 打包的文件创建索引

llvm-nm 在 字节代码文件中打印名字和符号类型

llvm-prof 将 'llvmprof.out' raw 数据格式化成人类可读的报告

llvm-ld 带有可装载的运行时优化支持的通用目标连接器

llvm-config 打印出配置时 LLVM 编译选项、库、等等

llvmc 一个通用的可定制的编译器驱动

llvm-diff 比较两个模块的结构

bugpoint 自动案例测试减速器

llvm-extract 从 LLVM 字节代码文件中解压出一个函数

llvm-bcanalyzer 字节代码分析器 (分析二进制编码本身,而不是它代表的程序)

FileCheck 灵活的文件验证器,广泛的被测试工具利用

tblgen 目标描述阅读器和生成器

litLLVM 集成测试器,用于运行测试

LLVM工具通过调用LLVM的一部分库,实现库的功能,通常使用编译器或者开发编译器的人会用到这些工具。

这是一个在LLVM IR级别做程序优化的工具,输入和输出都是LLVM IR。编译器,或者基于LLVM做优化的开发者通常会使用这一标准工具来查看优化的效果。它也提供了很多option, 可以执行某一特定的pass。

这是微观意义上的LLVM编译器,不同于gcc的编译器,它的输入是LLVM IR,输出是汇编文件或者是目标文件。通过-filetype=asm或者-filetype=obj来指定输出是汇编文件还是目标文件,若生成是目标文件,llc会调用LLVM中的汇编输出的代码库来工作(注意这个汇编器和gcc的汇编器也不同,它输入的是MI,是一种后端的中间表示)。除此之外,还可以用-On来指定优化级别(llc默认优化级别是-O2),或者其他一些参数。

(.bc文件换成.ll文件也可以)

这是LLVM汇编器,它输入汇编文件,输出目标文件, 类似于gnu中的as命令。同时,它也可以反汇编,指定特殊参数(–disassemble)就行。可以发现,llc和llvm-mc都会调用到输出目标文件的库,也就是MCObjectStreamer。

这个工具是LLVM IR的解释器,也是一个JIT编译器。LLVM可以把C语言翻译成LLVM IR,然后解释执行,与Java的那一套类似,这也是最初LLVM编写时的实现(一个虚拟机运行IR)。

最早看到这个工具,以为是链接器,其实它是IR级别的链接器,链接的是IR文件。谈到这里,可以说一下LLVM针对多个源文件编译时的两种目标码输出方式。

第一种是LLVM先通过前端把每个源文件单独翻译成IR级别,然后用llvm-link链接成一个IR,然后再经过优化、后端等步骤生成目标文件,使用llvm-link的同时,可以使用链接时优化。不过需要注意,这种方式同样需要最终调用链接器,将这个目标文件链接成可执行文件。

第二种是LLVM通过前端把每个源文件单独翻译后,再单独经过优化、后端等工作,将每个源文件生成目标文件,之后再调用链接器,将所有目标文件链接成可执行文件。

这是针对LLVM IR的汇编器,其实名字里带as,实际上不是gcc那个as,它的功能是将.ll文件翻译为.bc文件,LLVM项目里,.ll称为LLVM汇编码,所以llvm-as也就是IR的汇编器了。

与llvm-as刚好相反,IR的反汇编器,用来将.bc文件翻译为.ll文件。

最后也提一下clang,它也是现在LLVM项目中一个很重要的前端工具。clang能够调用整个编译器的流程,也就是上边其他工具调用的库,它很多都同样会调用。clang通过指定-emit-llvm参数,可以配合-S或-c生成.ll或.bc文件,这样我们就能把Clang的部分和LLVM的后端分离开来独立运行,对于观察编译器流程来说,很实用。

还有一些其他工具,就不举例了,可以查看LLVM项目路径下/src/tools/中查看。

LLVM,全称为Low Level Virtual Machine,其实它就是底层编译框架,其执行效率要比Gcc等以速度快见长的编译器要快上很多。Google将它用于Android中也是因为它超高的效率。现在Android因为开始采用ART,所以用它做预编译(AOT),从而提高了程序的执行效率,其代价就是需要更大的空间,安装时间的增加。因此,LLVM现在基本上参与了Android应用的的编译工作,而在ART之前,Android3.0之后,LLVM主要用来进行3D渲染(RenderScript)


欢迎分享,转载请注明来源:内存溢出

原文地址: https://www.outofmemory.cn/yw/8113703.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-13
下一篇 2023-04-13

发表评论

登录后才能评论

评论列表(0条)

保存