llvm与gcc
-
llvm 是一个编译器,也是一个编译器架构,是一系列编译工具,也是一个编译器工具链,开源 C++11 实现。
-
gcc 相对于 clang 的优势:
- gcc 支持更过语言前端,如 Java, Ada, FORTRAN, Go等
- gcc 支持更多地 CPU 目标架构
- gcc 支持更多语言扩展,比如 gcc 可以完美地支持 Linux Kernel 的编译,而 clang 会遇到一些扩展的问题
-
clang 相对于 gcc 的优势:
- clang 的 AST 和整个设计是人类可以阅读的
- clang 的模块化和复用性更好,clang 从初衷上就是以 API 的形式设计,可以被源码分析工具,重构,IDE等复用。而 gcc 在设计时就没有这个考量,gcc 被设计为“一大团”静态编译器,总之就是可以实现功能,并且功能很强大(上面优点),但其中内容基本不可知,gcc 的设计就没有考虑复用性
- clang 可以序列化其生成的 AST 到硬盘上并且被其他程序读入,这对整个程序的分析很有用,gcc 不支持这项功能
- llvm 的优化在全程都会进行,包括编译时优化,链接时优化,装载时优化,运行时优化,以及闲时优化。可参考:LLVM全时优化。
- clang 更快且用更少内存
- clang 在设计时就考虑提供更加清晰准确地诊断信息(error 和 warning 信息)
- gcc 的许可证是 GPL,clang 是 BSD
gcc 就像橡皮泥,能够塑造出任何优秀的作品,但基本没有复用性可言;llvm 就像乐高积木,虽然更加粗犷,但是模块化和复用性极佳。
那么,llvm 框架模块化的优势究竟是怎样在其他领域为其他应用带来巨大的便利的呢?以下整理自 知乎@蓝色 大佬的一个回答(LLVM相比于GCC,有哪些技术上的优势?):
-
统一的IR与模块化。你可以很轻易的抽取LLVM的组件(以库的形式)出来用于其它领域,如抽取LLVM JIT用于 MapD 这样的 GPU 数据库,或者抽取LLVM的整个后端(优化与CodeGen)用于 TVM 这样的深度学习推理框架。这样带来的好处就是 LLVM 不再仅仅是用于给 Clang 等编译器前端提供服务的编译器后端,而是可以为需要JIT / CodeGen 功能的所有领域服务,比如提到的GPU数据库、深度学习推理框架,还包括安全、区块链等应用领域。而这一切LLVM所需要的仅仅是一个统一的中间表示格式:LLVM IR。所以,现在比较常见的开发模式变为:
各种各样的应用(DSL、GPU数据库、TVM、安全、区块链等)----> 生成 LLVM IR ----> LLVM的优化 ----> LLVM Code Gen ----> 目标代码(ARM、x86、Hexagon、NVPTX、AMDGPU、WebAssembly…)。 这在LLVM出现之前,基本上是做不到的事情,不仅GCC,包括其它编译器都可以理解为“一坨”,根本抽不出来。
-
快速的可定制化。这一点架设在第一点的基础上,由于在LLVM中编写优化Pass非常方便,所以针对各种各样的应用,可以变为:
-
各种各样的应用(DSL、GPU数据库、TVM、安全、区块链等)----> 生成 LLVM IR ----> 编写针对自己特定应用的优化Pass ----> LLVM的优化 ----> LLVM Code Gen ----> 目标代码(ARM、x86、Hexagon、NVPTX、AMDGPU、WebAssembly…)
-
也包括:各种各样的应用(DSL、GPU数据库、TVM、安全、区块链等)----> 生成 LLVM IR ----> 编写针对自己特定应用的优化Pass ----> LLVM的优化 ----> LLVM Code Gen ----> 目标代码(ARM、x86、Hexagon、NVPTX、AMDGPU、WebAssembly,自己的后端(如AI芯片)…)
-
-
使用现代C++代码编写并有良好的代码组织。LLVM使用C++11编写,代码十分清晰与规范,对于阅读并且改写非常的方便。同时,其代码组织非常的好,每一个地方放什么东西,一目了然。而我也与一些同僚聊过,大家也都觉得LLVM是更好读、更好改的代码。
-
License优势。这一点是优势,但是是否是技术优势,看如何理解,但是这一点确实帮助了LLVM很多,让其快速被各大公司采用并不断回馈它。
Ref:
https://www.youtube.com/watch?v=RzrHuP2aVEg
https://www.zhihu.com/question/23807363