LLVM & Clang

来源:互联网 发布:linux下网络配置文件 编辑:程序博客网 时间:2024/03/29 17:29

http://www.llvm.org/

http://clang.llvm.org/

http://baike.baidu.com/item/LLVM

http://www.aosabook.org/en/llvm.html 

http://www.cnblogs.com/zuopeng/p/4141467.html

http://blog.csdn.net/snsn1984/article/details/47039035

http://blog.csdn.net/snsn1984/article/details/17716261

http://blog.csdn.net/snsn1984/article/details/8037414

LLVM(Low Level Virtual Machine)是构架编译器(compiler)的框架系统,以C++编写而成,用于优化以任意程序语言编写的程序的编译时间(compile-time)、链接时间(link-time)、运行时间(run-time)以及空闲时间(idle-time),对开发者保持开放,并兼容已有脚本。

LLVM到底是什么?

  • LLVM是一个编译器;
  • LLVM是一个编译器框架;
  • LLVM是一系列的编译器工具;
  • LLVM是一个编译器工具链;
  • LLVM是一个C++实现的开源软件;

这几种对LLVM的理解都对,但是也都是LLVM的一个方面,综合起来就是一个完整的LLVM。所以,从狭义上来说,可以简单的把LLVM理解为一个编译器,但是也必须知道,这个编译器可不仅仅是个编译器,它包含了编译相关的各种工具链,并且有一些相对独立的工具,而且它还是开源的。关键一点不要再搞混了,LLVM是搞编译的,跟虚拟机已经完全没关系了。

LLVM 是 Illinois 大学发起的一个开源项目,和之前为大家所熟知的JVM 以及 .net Runtime这样的虚拟机不同,这个虚拟系统提供了一套中立的中间代码和编译基础设施,并围绕这些设施提供了一套全新的编译策略(使得优化能够在编译、连接、运行环境执行过程中,以及安装之后以有效的方式进行)和其他一些非常有意思的功能。

llvm的目的不是运行而是编译生成代码,也就是说这个llvm是编译器的后端。clang简单来说就是llvm一个C语言家族的前端,它的责任就是把C家族语言翻译成llvm认识的中间代码,然后再由llvm后端生成具体架构的汇编代码,最后由系统中的汇编器、连接器生成某一个架构下的可执行文件。


语言无关的中间代码
一方面,这使得透过LLVM能够将不同的语言相互连结起来;也使得LLVM能够紧密地与IDE交互和集成。
另一方面,发布中间代码而非目标代码能够在目标系统上更好地发挥其潜能而又不伤害可调试性(i.e. 在目标系统上针对本机的硬件环境产生目标代码,但又能够直接通过中间代码来进行行级调试)
作为工具和函数库
使用LLVM提供的工具可以比较容易地实现新的编程语言的优化编译器或VM,或为现有的编程语言引入一些更好的优化/调试特性。


一个现代编译器的主要工作流程:源代码 (source code) → 预处理器 (preprocessor) → 编译器 (compiler) → 目标代码 (object code) → 链接器(Linker) → 可执行程序 (executables)

前端负责解析源代码,检查语法错误,并将其翻译为抽象的语法树(Abstract Syntax Tree)。优化器对这一中间代码进行优化,试图使代码更高效。后端则负责将优化器优化后的中间代码转换为目标机器的代码,这一过程后端会最大化的利用目标机器的特殊指令,以提高代码的性能。G++是GCC编译器集合的一个前端。

[Three Major Components of a Three-Phase Compiler]

常见的编译分析有函数调用树(call tree),控制流程图(Control flow graph),以及在此基础上的 变量定义-使用,使用-定义链(define-use/use-define or u-d/d-u chain),变量别名分析(alias analysis),指针分析(pointer analysis),数据依赖分析(data dependence analysis)等。

程序分析结果是编译器优化(compiler optimization)和程序变形(compiler transformation)的前提条件。常见的优化和变形有:函数内嵌(inlining),无用代码删除(Dead code elimination),标准化循环结构(loop normalization),循环体展开(loop unrolling),循环体合并,分裂(loop fusion,loop fission),数组填充(array padding),等等。 优化和变形的目的是减少代码的长度,提高内存(memory),缓存(cache)的使用率,减少读写磁盘,访问网络数据的频率。更高级的优化甚至可以把序列化的代码(serial code)变成并行运算,多线程的代码(parallelized,multi-threadedcode)。


LLVM的三阶段设计是这样的:
[LLVM's Implementation of the Three-Phase Design]
这样做的优点是如果需要支持一种新的编程语言,那么我们只需要实现一种新的前端。如果我们需要支持一种新的硬件设备,那我们只需要实现一个新的后端。而优化阶段因为是针对了统一的LLVM IR,所以它是一个通用的阶段,不论是支持新的编程语言,还是支持新的硬件设备,这里都不需要对优化阶段做修改。所以从这里可以看出LLVM IR的作用。
LLVM IR主要有三种格式:一种是在内存中的编译中间语言;一种是硬盘上存储的二进制中间语言(以.bc结尾),最后一种是可读的中间格式(以.ll结尾)。这三种中间格式是完全相等的。
IR是intermediate representation的缩写,顾名思义是中间表示的的缩写。中间表示已经被越来越多的编译器所采用,传统的编译器多采用汇编语言作为自己的中间语言,而现在大一些的编译器都有了自己专属的中间表示。LLVM IR的官方文档地址:http://llvm.org/docs/LangRef.html



Clang开发背景: http://www.51099.com/comp/prcj/20090927/343637.html

Apple 使用 LLVM 在不支持全部 OpenGL 特性的 GPU (Intel 低端显卡) 上生成代码 (JIT),令程序仍然能够正常运行。之后 LLVM 与 GCC 的集成过程引发了一些不快,GCC 系统庞大而笨重,而 Apple 大量使用的 Objective-C 在 GCC 中优先级很低。此外 GCC 作为一个纯粹的编译系统,与 IDE 配合很差。加之许可证方面的要求,Apple 无法使用修改版的 GCC 而闭源。于是 Apple 决定从零开始写 C family 的前端,也就是基于 LLVM 的 Clang 了。

Download:http://releases.llvm.org/download.html

编译Clang:http://clang.llvm.org/get_started.html                   http://blog.csdn.net/snsn1984/article/details/8232943     http://blog.csdn.net/snsn1984/article/details/8593380

Documents: http://clang.llvm.org/docs/

LLVM: http://llvm.org/docs/GettingStarted.html

http://blog.csdn.net/snsn1984/article/details/8165529

http://blog.csdn.net/snsn1984/article/details/8170575


GCC(GNU C Compiler, GNU Compiler Collection),GCC中提供了C Preprocessor这个C语言的预处理器,简称CPP。

https://gcc.gnu.org/onlinedocs/gcc/G_002b_002b-and-GCC.html

C++0x was the working name for the new standard for C++, adding many language features that I'll cover in this series on c++11. In September 2011, C++0x was officially published as the new C++11 standard.

http://blog.csdn.net/snsn1984/article/details/8062789


while valgrind emulates the machine at run-time, Asan works by instrumenting the code at compile-time.
http://www.tuicool.com/articles/AZJ3qe