LLVM
是以 C++
编写的架构编译器(compiler
)的框架系统compile time
link time
run time
idle time
Frontend
编译器前端的任务是 解析源代码前端
LLVM
的前端还会生成 中间代码(intermediate representation
,IR)Optimizer
优化器端的任务是改善代码的运行时间,例如消除冗余运算等。c++
Backend
/ 代码生成器CodeGenerator
OC
、c
、c++
使用的编译器前端是clang
;Swift
使用的是Swift
;后端都是LLVM
。 后端
传统的编译器设计把前端、优化器、后端集成在一块儿,须要支持新语言或新硬件结构时就必须从新开发一套编译器。LLVM
的设计模式很好的解决了这种不便。设计模式
LLVM
的编译器前端会生成通用的中间代码(intermediate respresentation
IR)LLVM
中的一个子项目LLVM
的轻量级编译器GCC
,提供更快的编译速度OC
、C
、C++
LLVM
架构的编译器前端clang -ccc-print-phases main.m
复制代码
clang -E main.m
复制代码
执行后能够看到头文件导入以及宏被替换。xcode
预处理后会进行词法分析,词法分析会把代码切片成一个个token
。bash
clang -fmodules -fsyntax-only -Xclang -dump-tokens main.m
复制代码
执行后能够看到每一个词(token
)所在的位置架构
语法分析会验证语法是否正确,在词法分析的基础上把单词组合成各类语法短语,而后把节点组成抽象的语法树(Abstract Syntax Tree,AST)框架
clang -fmodules -fsyntax-only -Xclang -ast-dump main.m
复制代码
若是找不到头文件,能够手动导入SDK函数
clang -isysroot SDK路径 -fmodules -fsyntax-only -Xclang -ast-dump main.m
复制代码
处理完上述步骤,代码生成器(Core Generator
)会根据语法树自顶向下生成LLVM IR
。OC会在这里进行runtime
的桥接:property
的合成、ARC
处理等。优化
clang -S -fobjc-arc -emit-llvm main.m
复制代码
LLVM
的优化级别有 -O0
-O1
-O2
-O3
-Os
clang -Os -S -fobjc-arc -emit-llvm main.m
复制代码
执行指令能够获得.ll
文件
@ 全局标示
% 局部标示
alloca 开辟空间
align 字节对齐
i32 32位,4字节
store 写入内存
load 读取数据
call 调用函数
ret return
复制代码
查看未优化的main.ll
优化后的main.ll
xcode7
之后开启了bitCode
,苹果对代码作了进一步优化并生成.bc
文件。经过.ll
文件生成.bc
文件。
clang -emit-llvm -c main.ll -o main.bc
复制代码
能够经过.bc
或.ll
文件生成汇编代码
clang -S -fobjc-arc main.bc -o main.s
clang -S -fobjc-arc main.ll -o main.s
复制代码
生成汇编代码的时候也能够进行优化
clang -Os -S -fobjc-arc main.bc -o main.s
复制代码
输入汇编代码,转化成机器代码,最后输出目标文件。
clang -fmodules -c main.s -o main.o
复制代码
查看main.o中的符号
xcrun nm -nm main.o
复制代码
能够看到print
函数、test
函数、main
函数
_printf
能够看到 undefined extranal
标示undefined
表明它在当前文件找不到extranal
表明它能够外部访问把编译的.o
文件和dylib.a
文件链接,生成mach-o
文件
clang main.o -o main
复制代码
执行可执行文件,能够看见输出了正确结果