LLVM
一、什么是LLVM?
- 官网:https://llvm.org/
- The
LLVM
Project is a collection of modular and reusablecompiler
andtoolchain
technologies.
(LLVM
项目是模块化、可重用的编译器
以及工具链技术
的集合。) - 美国计算机协会 (ACM) 将其
2012
年软件系统奖项颁给了LLVM
,之前曾经获得此奖项的软件和技术包括:Java
、Apache
、Mosaic
、the World Wide Web
、Smalltalk
、UNIX
、Eclipse
等等 - 创始人
Chris Lattner
,亦是Swift
之父; - 有些文章把
LLVM
当做Low Level Virtual Machine
(低级虚拟机)的缩写简称,官方描述如下:The name "LLVM" itself is not an acronym; it is the full name of the project.
(LLVM
这个名称本身不是首字母缩略词; 它是项目的全名)
二、传统的编译器架构和LLVM架构
- 不同的前端后端使用统一的中间代码
LLVM Intermediate Representation
(LLVM IR
) - 如果需要支持一种新的编程语言,那么只需要实现一个新的前端
- 如果需要支持一种新的硬件设备,那么只需要实现一个新的后端
- 优化阶段是一个通用的阶段,它针对的是统一的
LLVM IR
,不论是支持新的编程语言,还是支持新的硬件设备,都不需要对优化阶段做修改 - 相比之下,
GCC
的前端和后端没分得太开,前端后端耦合在了一起。所以GCC
为了支持一门新的语言,或者为了支持一个新的目标平台,就变得特别困难 LLVM
现在被作为实现各种静态和运行时编译语言的通用基础结构(GCC
家族、Java
、.NET
、Python
、Ruby
、Scheme
、Haskell
、D
等)
三、Clang
什么是
Clang
?LLVM
项目的一个子项目- 基于
LLVM
架构的C/C++/Objective-C
编译器前端 - 官网:http://clang.llvm.org/
相比于
GCC
,Clang
具有如下优点编译速度快:在某些平台上,
Clang
的编译速度显著的快过GCC
(Debug
模式下编译OC
速度比GGC
快3倍
)占用内存小:
Clang
生成的AST
所占用的内存是GCC
的五分之一左右模块化设计:
Clang
采用基于库的模块化设计,易于IDE
集成及其他用途的重用诊断信息可读性强:在编译过程中,
Clang
创建并保留了大量详细的元数据 (metadata
),有利于调试和错误报告设计清晰简单,容易理解,易于扩展增强
四、Clang与LLVM
五、OC源文件的编译过程
- 命令行查看编译的过程:
$ clang -ccc-print-phases main.m
- 查看
preprocessor
(预处理)的结果:$ clang -E main.m
六、词法分析
- 词法分析,生成
Token
:$ clang -fmodules -E -Xclang -dump-tokens main.m
七、语法树-AST
- 语法分析,生成语法树(
AST
,Abstract Syntax Tree
):$ clang -fmodules -fsyntax-only -Xclang -ast-dump main.m
八、LLVM IR
LLVM IR
有3种表示形式(但本质是等价的,就好比水可以有气体、液体、固体3种形态)text
:便于阅读的文本格式,类似于汇编语言,拓展名.ll
,$ clang -S -emit-llvm main.m
memory
:内存格式bitcode
:二进制格式,拓展名.bc
,$ clang -c -emit-llvm main.m
- IR基本语法
- 注释以分号
;
开头 - 全局标识符以
@
开头,局部标识符以%
开头 alloca
,在当前函数栈帧中分配内存i32
,32bit
,4个字节的意思align
,内存对齐store
,写入数据load
,读取数据
- 注释以分号
- 官方语法参考
九、源码下载
下载LLVM
$ git clone https://git.llvm.org/git/llvm.git/
- 大小
746.2 MB
,仅供参考
下载clang
$ cd llvm/tools
$ git clone https://git.llvm.org/git/clang.git/
- 大小
297.7 MB
,仅供参考
十、源码编译
安装
cmake
和ninja
(先安装brew
,https://brew.sh/)$ brew install cmake
$ brew install ninja
ninja
如果安装失败,可以直接从github
获取release
版放入【/usr/local/bin】
中在LLVM源码同级目录下新建一个
【llvm_build】
目录(最终会在【llvm_build】
目录下生成【build.ninja】
)$ cd llvm_build
$ cmake -G Ninja ../llvm -DCMAKE_INSTALL_PREFIX=LLVM的安装路径
- 更多
cmake
相关选项,可以参考:https://llvm.org/docs/CMake.html
依次执行编译、安装指令
$ ninja
- 编译完毕后,
【llvm_build】
目录大概21.05 G
(仅供参考) $ ninja install
- 安装完毕后,安装目录大概
11.92 G
(仅供参考)
也可以生成
Xcode
项目再进行编译,但是速度很慢(可能需要1个多小时)在
llvm
同级目录下新建一个【llvm_xcode】
目录cd llvm_xcode
$ cmake -G Xcode ../llvm
十一、应用与实践
libclang
、libTooling
- 官方参考:https://clang.llvm.org/docs/Tooling.html
- 应用:语法树分析、语言转换等
Clang
插件开发Pass
开发 p- 官方参考:https://llvm.org/docs/WritingAnLLVMPass.html
- 应用:代码优化、代码混淆等
开发新的编程语言
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 DeveloperLY's Blog!