一、LLVM的简单介绍
- 1.1、什么是LLVM官网:https://llvm.org/
- LLVM官网解释:The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
- 翻译为中文:LLVM 项目是模块化、可重用的编译器以及工具链技术的集合
- 美国计算机协会 (ACM) 将其2012 年软件系统奖项颁给了LLVM,之前曾经获得此奖项的软件和技术包括:
Java
、Apache
、Mosaic
、the World Wide Web
、Smalltalk
、UNIX
、Eclipse
等等
- 1.2、LLVM 的创始人
Chris Lattner
,亦是Swift之父
- 1.3、LLVM命名的由来,有些文章把LLVM当做Low Level Virtual Machine(低级虚拟机)的缩写简称,官方描述如下
- The name
LLVM
itself is not an acronym; it is the full name of the project. LLVM
这个名称本身不是首字母缩略词; 它是项目的全名
二、编译器架构
- 2.1、传统的编译器架构
- Frontend:前端
词法分析、语法分析、语义分析、生成中间代码 - Optimizer:优化器
中间代码优化 - Backend:后端
生成机器码
- 2.2、LLVM架构
- 不同的前端后端使用统一的中间代码LLVM Intermediate Representation (
LLVM IR
) - 如果需要支持一种新的编程语言,那么只需要实现一个新的前端
- 如果需要支持一种新的硬件设备,那么只需要实现一个新的后端
- 优化阶段是一个通用的阶段,它针对的是统一的LLVM IR,不论是支持新的编程语言,还是支持新的硬件设备,都不需要对优化阶段做修改
- 相比之下,GCC的前端和后端没分得太开,前端后端耦合在了一起。所以GCC为了支持一门新的语言,或者为了支持一个新的目标平台,就
变得特别困难 LLVM
现在被作为实现各种静态和运行时编译语言的通用基础结构(GCC家族、Java、.NET、Python、Ruby、Scheme、Haskell、D等)
- 2.3、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),有利于调试和错误报告
- 设计清晰简单,容易理解,易于扩展增强
- 2.4、Clang 与 LLVM
- 广义的LLVM:整个LLVM架构
- 狭义的LLVM:LLVM后端(代码优化、目标代码生成等)
三、OC源文件的编译过程
创建一个命令行项目
- 3.1、命令行查看编译的过程:
clang -ccc-print-phases main.m
3.2、查看 preprocessor(预处理)的结果:clang -E main.m
3.3、词法分析
词法分析,生成Token: clang -fmodules -E -Xclang -dump-tokens main.m
3.4、语法树-AST
语法分析,生成语法树
(AST,Abstract Syntax Tree): clang -fmodules -fsyntax-only -Xclang -ast-dump main.m
3.5、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,读取数据