LLVM简介
LLVM(wiki chs)是开源跨平台的编译器基础设施,包含一系列模块化的编译器组件和工具链,用来开发编译器前端和后端。源代码见:github 也可从官网下载代码 注:LLVM本身并不是编译器
LLVM架构提供了完整编译系统的中间层,与绝大多数编译器一样,LLVM架构也使用经典三段式的结构设计。
① 前端(Frontend)负责分析源代码【词法分析】,可以检查语法级错误【语法分析】,构建针对该语言的抽象语法树(Abstract Syntax Tree,AST)【语义分析】 ,并将代码编译成LLVM IR【IR生成】
② 抽象语法树可以进一步转换为优化,最终转为新的表示方式, 然后再交给优化器
③ 最终由后端生成可执行的机器码 注:如果需要增加一种处理器架构(如:arm64、x86等),只需要增加一种后端
Clang及许多新的GCC工具链都支持LLVM架构,能输出LLVM IR代码。LLVM已经成为多个编译器和代码生成相关子项目的母项目。 注:Clang是类C语言的编译器前端,是LLVM的一个子项目。
LLVM前端已支持的编程语言:C、C++、ActionScript、Ada、D语言、Fortran、GLSL、Haskell、Java字节码、Objective-C、Swift、Python、Ruby、Crystal、Rust、Scala以及C#等
LLVM后端已支持指令集架构:x86、x86-64、ARM、MIPS、PowerPC以及RISC-V等
相比之下,传统GCC的前端和后端没分得太开,耦合在一起。这使得GCC支持一门新的语言或新的目标平台,变得特别麻烦
LLVM的核心是IR语言(Intermediate Representation),一种类似汇编的底层语言。
IR是一种强类型的精简指令集(Reduced Instruction Set Computing,RISC),并对目标指令集进行了抽象。
LLVM IR有3种表示形式:
text:便于阅读的文本格式。扩展名为.ll
bitcode:二进制格式。扩展名为.bc
memory:内存格式
LLVM其他子项目
lld链接器
lld链接器子项目旨在为LLVM开发一个内置的,平台独立的链接器,去除对所有第三方链接器的依赖。
2017.5,lld已经支持ELF、PE/COFF和Mach-O可执行文件格式。
ndk中的lld链接器(ld.lld)的可执行文件见:
在lld支持不完全的情况下,用户可以使用其他项目,如GNU ld链接器、bfd链接器(ld.bfd)、gold链接器。 注:ld.gold是google在GNU ld上改进的链接器
ndk中GNU ld链接器、bfd链接器(ld.bfd)、gold链接器(ld.gold)的可执行文件在:
C++标准库
LLVM项目包含一个叫做libc++的C++标准库的实现 注:GNU的为Libstdc++
lldb调试器
lldb(wiki)是LLVM的调试子项目,目前已支持C、C++及Objective-C。XCode5+、Android Studio缺省使用LLDB进行调试,LLDB也被VS Code、Eclipse等IDE使用。
参考
The Architecture of Open Source Applications: LLVM
深入剖析 iOS 编译 Clang / LLVM (github链接)