背景图

LLVM简介

什么是LLVM

官方的解释是:LLVM可以被看作是一系列的编译器和工具链技术的集合,而且它们是模块化并且是可重用的。官方网站是:http://llvm.org/ 。 不过从名称上看像一个虚拟机,然而与虚拟机没有一点关系,LLVM是这个项目的名称而已。

LLVM最初是伊利诺伊大学的一个研究项目,其目标是提供一种现代的,基于SSA(static single assignment form,静态单赋值形式)的编译策略,能够支持任意编程语言的静态和动态编译。 从那时起,LLVM已经发展成为一个由多个子项目组成的综合项目,其中许多子项目正在各种商业和开源项目的生产中使用,并且被广泛用于学术研究。 LLVM项目中的代码遵循“UIUC”BSD-Style许可证.

LLVM的主要子项目有:

  1. LLVM核心库提供了一个独立于现代的源和目标的优化器,以及支持许多流行CPU的代码生成(以及一些不太常见的CPU)。这些库是围绕一个良好规范的代码表示而建立的,称为LLVM中间语言(“LLVM IR”)。 LLVM Core库有详细的文档,并且使用LLVM用作优化器和代码生成器,将使你特别容易地将创建自己的语言(或移植现有的编译器)。
  2. Clang是一种“LLVM原生”的C/C++/Objective-C编译器,它旨在提供惊人的快速编译(例如,在编译调试配置中编译Objective-C代码时比GCC快大约3倍),非常有用的错误和警告消息,为构建优秀的源代码级工具提供了一个平台。Clang静态分析器是一个可以自动发现代码中的错误的工具,并且它是使用Clang前端作为库来解析C/C++代码的工具。
  3. LLDB项目建立在由LLVM和Clang提供的库上,以提供一个出色的本地调试器。 它使用Clang AST和表达式解析器,LLVM JIT,LLVM反汇编器等,以便提供“正常工作”的体验。 在加载符号时,它比GDB更快速,内存效率更高。
  4. libc++libc++ ABI项目提供了C++标准库的标准一致性和高性能实现,包括对C++11的全面支持。
  5. 编译器rt项目提供高级优化的低级代码生成器支持例程的实现,例如“__fixunsdfdi”以及当目标没有执行核心IR操作的短序列本机指令时生成的其他调用。 它还为动态测试工具(如AddressSanitizerThreadSanitizerMemorySanitizerDataFlowSanitizer)提供了运行时库的实现。
  6. OpenMP子项目提供OpenMP Runtime,以便与Clang中的OpenMP实现一起使用。
  7. polly项目实现了一套缓存局部优化以及使用多面体模型的自动并行和向量化。
  8. libclc项目旨在实现OpenCL标准库。
  9. klee项目实现了一个“符号虚拟机”,它使用定理证明器来尝试评估程序中的所有动态路径,以努力寻找错误并证明函数的属性。 klee的一个主要特点是它可以在检测到错误的情况下生成一个测试用例。
  10. SAFECode项目是用于C/C++程序的内存安全编译器。它使用运行时检查代码来检测运行时的内存安全错误(例如,缓冲区溢出)。它可以用来保护软件免受安全攻击,也可以用作Valgrind之类的内存安全错误调试工具。
  11. lld项目旨在成为clang/llvm的内置链接器。目前,clang必须调用系统链接器来生成可执行文件。

除了LLVM的官方子项目之外,还有各种各样使用LLVM组件执行各种任务的其他项目。 通过这些外部项目,您可以使用LLVM编译Ruby,Python,Haskell,Java,D,PHP,Pure,Lua和一些其他语言。 LLVM的一个主要优势是其多功能性,灵活性和可重用性,这就是为什么它被用于如此广泛的各种不同任务的原因:从Lua等嵌入式语言的轻量级JIT编译到编译Fortran代码以实现大规模超级电脑。

和其他所有事情一样,LLVM拥有广泛而友好的社区,他们对构建优秀的底层工具感兴趣。如果您有兴趣参与,首先要浏览LLVM博客并注册LLVM Developer邮件列表。 有关如何发送补丁程序,获取提交权限以及版权和许可证主题的信息,请参阅LLVM开发者规则

关于LLVM

看上面的说明可能有点懵,但其实就是LLVM定义了一种中间语言或称通用中间语言,提供了丰富的中间码(IR),这样就为我们创建自己的语言提供了极大的便利,其实就是感觉自己用IR去生成自己的命令,类似于CPU中的微指令了。另外就是将自己的语言转成对应的LLVM IR,那么就可以直接使用LLVM子项目中的JIT,这样你就不用自己写虚拟机了,的确是带来了极大的遍历。

再比如像solidity这样的语言需要运行在以太坊的CPP节点,Go节点,Parity的Scala节点,这样的话我们要写很多的编译器和虚拟机,但是有了LLVM后,一切都不用担心了,实现起来还是比较靠谱的,不是吗?

另外通过LLVM我们可以实现不同语言之间的互转,比如C++代码转成node代码。中间只要通过LLVM就可以了。以前不明白微软怎么支持多种语言实现在win10上安装,现在终于有思路了,只是微软要写多种编译器,可能这个过程比较难吧,他们放弃了。还有就比如以太坊的solc-bin里面有用的文件只有一个7M多的js文件,而且还是压缩的,从ReadMe中我们可以发现,这个项目中的文件都是通过emscripten生成的;而emscripten是将LLVM中间语言转化为node代码,一切已然明了。

所以我觉得学习LLVM语言还是很有必要的过程,应该深入去学习一下。

关于emscripten

这是一个很棒的项目,将LLVM中间语言转化为node的代码。更多的东西就不用多介绍了,也不进行深入地学习了,这要精通node的编译器和语法知识才行,我就读读Readme、WIKI和api文档就好了。下面列一下学习的资料吧!
官方github项目
Emscripten Wiki
Emscripten 文档

LLVM的命令指南

以下文档是所有LLVM工具的命令描述。 这些页面描述如何使用LLVM命令以及它们的选项。 请注意,这些页面没有描述所有工具可用的所有选项。 要获得完整列表,请将–help(常规选项)或–help-hidden(常规和调试选项)参数传递给您感兴趣的工具。

基础命令

  • llvm-as - LLVM汇编程序
  • llvm-dis - LLVM反汇编程序
  • opt - LLVM优化器
  • llc - LLVM静态编译器
  • lli - 直接从LLVM位码执行程序
  • llvm-link - LLVM位码链接器
  • llvm-ar - LLVM归档打包 archiver
  • llvm-lib - LLVM lib.exe lib.exe兼容库工具
  • llvm-nm - 列出LLVM位码和目标文件的符号表
  • llvm-config - 打印LLVM编译选项
  • llvm-diff - LLVM结构差异
  • llvm-cov - 发布覆盖信息
  • llvm-profdata - 配置数据工具
  • llvm-stress - 生成随机的.ll文件
  • llvm-symbolizer - 将地址转换为源代码位置
  • llvm-dwarfdump - 转储并验证DWARF调试信息
  • dsymutil - 处理归档的DWARF调试符号文件
  • llvm-mca - LLVM机器代码分析器

调试工具

  • bugpoint - 自动测试案例缩减工具
  • llvm-extract - 从LLVM模块中提取函数
  • llvm-bcanalyzer - LLVM位码分析器

开发工具

  • FileCheck - 灵活的模式匹配文件验证器
  • tblgen - 目标描述到C ++代码生成器
  • lit - LLVM综合测试仪
  • llvm-build - LLVM项目构建实用程序
  • llvm-exegesis - LLVM机器指令基准
  • llvm-pdbutil - PDB文件取证和诊断
  • llvm-readobj - LLVM对象读取器

参考和引用

The LLVM Compiler Infrastructure
LLVM Command Guide
LLVM每日谈之七 Clang
七天LLVM零基础入门(Linux版本)——第一天

0%