文章目录
- 基本构成
- 传统编译器
- 编译器的发展历史(History of Compiler)
- GCC 编译过程与原理(GCC Process and Principle)
- LLVM/Clang 编译过程与原理(LLVM/Clang Process and Principle)
- GCC与与 LLVM/Clang 的对比
- 总结
- 参考
基本构成
目前主流如 LLVM 和 GCC 等经典的开源编译器,通常分为三个部分,前端(Frontend),优化器(Optimizer)和后端(Backend)。
-
Frontend:主要负责词法和语法分析,将源代码转化为抽象语法树,即将程序划分为基本的组成部分,检查代码的语法、语义和语法,然后生成中间代码
-
Optimizer:优化器则是在前端的基础上,对得到的中间代码进行优化(如去掉冗余代码、子表达式消除等工作),使代码更加高效
-
Backend:后端则是将已经优化的中间代码,针对具体的硬件生成目标代码,转换成为包括代码优化器和代码生成器
传统编译器
编译器的发展历史(History of Compiler)
- 早期编译器将高级语言翻译成机器代码
- 随着程序复杂度增加,出现多阶段、可优化的编译器设计
GCC 编译过程与原理(GCC Process and Principle)
- 预处理(Preprocessing)
- 编译(Compilation)
- 汇编(Assembly)
- 链接(Linking)
- 支持多平台和多种优化选项
LLVM/Clang 编译过程与原理(LLVM/Clang Process and Principle)
- 模块化设计,前端(Clang)、中端(LLVM IR)、后端(目标代码生成)分离
- 易于扩展和优化
- 广泛用于研究与工业界
LLVM (Low Level Virtual Machine,底层虚拟机) 提供了与编译器相关的支持,能够进行程序语言的编译期优化、链接优化、在线编译优化、代码生成。简而言之,可以作为多种编译器的后台来使用。
LLVM 作为一个编译器的基础建设,它是为了任意一种编程语言写成的程序,利用虚拟技术,创造出编译时期,链结时期,运行时期以及“闲置时期”的优化。
GCC与与 LLVM/Clang 的对比
比较项 | GCC | LLVM + Clang |
---|---|---|
前端 | 多个语言的独立前端(如 cc1) | Clang 为 C/C++/Objective-C 等 |
中间表示 | GIMPLE → RTL | LLVM IR(统一的三地址码) |
后端 | RTL 到汇编器 | LLVM 后端生成目标汇编或机器码 |
架构设计 | 前后端耦合性较高 | 更模块化、可插拔性强 |
类型 | GCC | Clang/LLVM |
---|---|---|
许可证 | GNU GPL | Apache 2.0 |
代码模块化 | 一体化架构 | 模块化 |
支持平台 | Unix、Windows、MAC | Unix、Windows、MAC |
代码生成 | 高效,有很多编译器选项可以使用 | 高效,LLVM 后端使用了 SSA 表单 |
语言独立类型系统 | 没有 | 有 |
构建工具 | Make Base | CMake |
解析器 | 最早采用 Bison LR,现在改为递归下降解析器 | 手写的递归下降解析器 |
链接器 | LD | lld |
调试器 | GDB | LLDB |
总结
编译技术是计算机科学皇冠上的一颗明珠,作为基础软件中的核心技术
编译器能够识别高级语言程序代码中的词汇、句子以及各种特定的格式和数据结构
编译过程,是将源代码程序转换成机器能够识别的二进制码
传统编译器通常分为三个部分,前端(frontEnd),优化器(Optimizer)和后端(backEnd)
参考
- GCC和LLVM发家历史?两大开源编译器的爱恨情仇【AI编译器】系列第二篇
- 02History.md