Getting Started with LLVM Core Libraries-工具和设计

Introducing LLVM's basic design principles and its history

  追溯llvm的历史要追溯到10年前(2014),起初它着眼于编译器的后端算法和中间表述(今天依然是llvm的重点),当时其他部分还要依赖gcc。其中最重要的是它的IR,llvm在整个编译的过程中有很多种中间表示,如AST(C/C++转换成IR的过程)、DAG(IR转换成特定机器的汇编语言的过程)、某种特定的中间表示(汇编器和链接器使用)等其他中间表示依然起到很重要的作用,但是,真正让llvm与众不同的还是它的IR,甚至llvm这个名字的由来还和IR有很大的关系。

  首先看IR(intermediate representation)的特点:

  • SSA
  • 无限多个寄存器

  其存在方式有两种,一种在内存中,一种是在磁盘上,SSA能够更方便的优化,再加上保存在磁盘上的这种编码方式能够达到几近全时优化的效果,这也是llvm的作者在最早介绍llvm的论文中提出的目标,但是IR的描述能力毕竟有限,要想实现全时优化,就要求对诸如程序分布这种行为做出描述,这也意味着实现了此功能的llvm要像jvm那样能够成为一个运行平台,类似jvm的名字,llvm这个名字就是这么来的。

  随着llvm项目的发展,其设计目标已经重点放在了通过磁盘上的IR操作实现链接时优化等功能,而不是全时优化,最终只保留了llvm这个名字,但是llvm已经成了一个强大的编译器框架,而不是一个类似jvm的那样的平台。

  说到这,说一下个人理解吧,感觉是llvm起初提出了一个比较精妙的编码表示方案,有利于一些编译优化,进而发现可以憧憬的的目标——全时优化,但是又发现实现全时优化比较困难,在llvm的mail list上有人专门就此发起了一个很详细的讨论,详细阐述了llvm不能像java那样成为一个platform或者vm的原因,重点还是要做编译器。

Understanding LLVM tody

  不管怎样,llvm这么名字还是保留下来了,现在如果有人跟你提起“LLVM”,可能是指以下内容:

  • 整个LLVM Project/框架
  • 由LLVM框架构造的编译器
  • LLVM框架的可重用代码:库
  • LLVM IR

  LLVM框架主要包括三个方面的核心内容:

  • 前端(frontend):将源码转换成中间代码(IR),包括词法分析、语法分析、语义分析、中间代码生成
  • IR:两种方式,readable和binary-encoded
  • 后端(backend):将IR转换成汇编代码,包括寄存器分配

LLVM的编译流程如图:

  每个步骤中间交互有两种介质:1) in-memory; 2) by-file,前者变现出来通过一些高层的工具如clang,自动进行指定的动作;后者可以每一步每一步分离开来,通过一个个独立的工具完成。

Interacting with the compiler driver

如前文所述,可以使用driver来自动完成一系列动作,对于代码hello.c:

#include <stdio.h>
int main()
{
    printf("Hello, World!\n");
    return 0;
}

直接编译:

clang hello.c -o hello

即可通过clang来执行一系列编译器的功能,直接生成可执行文件。

-###参数可以查看clang调用了哪些工具:

clang -### hello.c -o hello

Using standalone tools

posted @ 2014-10-12 21:37  pocean  阅读(1012)  评论(0编辑  收藏  举报