AI Summary 3.20522.10 Compiler摘要 2026-10-09
编译程序(Compiler,compiling program)编译器,把用高级程序语言的源程序,翻译成等价的机器语言目标程序的翻译程序。采用生成性实现途实现的翻译程序。以高级程序设计语言书写的源程序作为输入,以汇编语言或机器语言表示的目标程序作为输出

编译器 gcc-llvm-clang

传统三段式模型

阶段

核心功能

关键技术

前端(frontEnd)

源码解析→语法树生成

词法分析(Lex)语法分析(Parse)语义分析

优化器(Optimizer)

中间代码优化

常量传播、死代码消除、循环优化等

后端(backEnd)

目标机器代码生成

指令选择、寄存器分配、指令调度

在编译过程中

  • 前端
    主要负责词法和语法分析,将源代码转化为抽象语法树

  • 优化器
    在前端的基础上,对得到的中间代码进行优化,使代码更加高效

  • 后端
    将已经优化的中间代码转化为针对各自平台的机器代码

主流编译器对比

1. GCC(GNU Compiler Collection)
  • 定位
    多语言静态编译器(C/C++/Fortran/Java等)

  • 架构特点

    • 前后端耦合度高 扩展困难

    • 采用GPL许可证 限制商业集成

  • 优势

    • 支持语言/平台最广(如嵌入式、超算)

    • 无需C++环境即可编译(纯C实现)

2. LLVM(Low Level Virtual Machine)
  • 革命性创新 模块化SDK架构

    • 将编译器拆分为可重用库(如libLLVMCore)

    • 定义通用中间表示 LLVM IR(解耦前后端)

  • 典型工具链:

    • opt
      IR优化器

    • llc
      IR→汇编代码生成器

    • llvm-mc
      汇编器/反汇编器

3. Clang(LLVM前端)
  • 定位
    替代GCC的C/C++/ObjC前端

  • 性能对比(以Carbon.h编译测试为例)

    指标

    Clang

    GCC

    编译速度

    1x

    2.5x

    内存占用

    源码130%

    源码1000%

  • 核心优势:

    • 错误提示友好(精确标记问题位置)

    • 静态分析能力(Clang Static Analyzer)

    • IDE友好(API驱动,支持代码补全/重构)

GCC

GCC(GNU Compiler Collection,GNU 编译器套装)
由 GNU 开发的编程语言编译器
GCC 原名为 GNU C 语言编译器,因为它原本只能处理 C语言

GCC 演进得可处理 C++、Fortran、Pascal、Objective-C、Java 以及 Ada 等他语言

clang+llvm构成一个完整的编译器
clang是前端
llvm是后端
统称为LLVM

LLVM

Low Level Virtual Machine,底层虚拟机
提供与编译器相关的支持
进行程序语言的编译期优化、链接优化、在线编译优化、代码生成
可作为多种编译器的后台来使用。

苹果公司用 GCC 作为官方的编译器

Apple 对编译工具会提出更高的要求原因

一 Apple 对 Objective-C 语言(包括后来对 C 语言)新增很多特性
GCC 开发者不买 Apple 的账
不给实现,因此索性后来两者分成两条分支分别开发,这也造成 Apple 的编译器版本远落后于 GCC 的官方版本

二 GCC 代码耦合度太高,很难独立
后期版本 代码质量越差, Apple 想做的很多功能(比如更好的 IDE 支持),需要模块化的方式来调用 GCC,但 GCC一直不给做

编译器大神 Chris Lattner

2000 年 本科毕业的 Chris Lattner 考 GRE,前往 UIUC(伊利诺伊大学厄巴纳香槟分校),读计算机硕士和博士 阶段,翻烂《Compilers: Principles, Techniques, and Tools》,成了 GPA 满分(4.0) 牛人研究探索关于编译器的未知领域,发表了一篇又一篇的论文
他在硕士毕业论文里提出了完整的在编译时、链接时、运行时甚至是在闲置时优化程序的编译思想,直接奠定了 LLVM 的基础

LLVM 用 GCC 作为前端来对用户程序进行语义分析产生 IF(Intermidiate Format)
LLVM 使用分析完成代码优化和生成
这项研究让他在 2005 年毕业时成为业界小有名气的编译器专家
因此早早地被 Apple 盯上,最终成为其编译器项目的骨干

刚进入 Apple,Chris Lattner 就大展身手
首先在 OpenGL 小组做代码优化,把 LLVM 运行时的编译架在 OpenGL 栈上,这样 OpenGL 栈能够产出更高效率的图形代码
如果显卡足够高级,这些代码会直接扔入 GPU 执行
不支持全部 OpenGL 特性的显卡(比如当时的 Intel GMA卡),LLVM 则能够把这些指令优化成高效的 CPU 指令,使程序依然能够正常运行
这个强大的 OpenGL 实现被用在了后来发布的 Mac OS X 10.5 上
LLVM 的链接优化被直接加入到 Apple 的代码链接器上
LLVM-GCC 也被同步到使用 GCC4.0 代码

LLVM2.0 - Clang

Apple 打算从零开始写 C、C++、Objective-C 语言的前端 Clang,完全替代掉 GCC

Clang 是 LLVM 生态中的编译前端
支持 C/C++/Objective-C 等语言
将源代码解析为 LLVM IR 中间表示
供 LLVM 后端进行优化和代码生成
得益于模块化设计,Clang 编译速度快、内存占用低,并可直接对接 IDE 提供实时语法检查和代码补全

Clang 只支持C,C++ 和 Objective-C 三种语言

GCC 和 Clang 对比

  • Clang 特性

  • 速度快
    通过编译 OS X 上几乎包含了所有 C 头文件的 carbon.h 的测试,包括预处理 (Preprocess),语法 (lex),解析 (parse),语义分析 (Semantic Analysis),抽象语法树生成 (Abstract Syntax Tree) 的时间,Clang 比 GCC 快2倍多

  • 内存占用小
    Clang 内存占用是源码的 130%,Apple GCC 则超过 10 倍

  • 诊断信息可读性强
    错误的语法有源码提示,在错误的调用和相关上下文的下方有~~~~~和^的提示,相比之下 GCC 的提示很天书

  • 兼容性好
    Clang 开始被设计为 API,允许被源代码分析工具和 IDE 集成
    GCC 被构建成一个单一的静态编译器,非常难以被作为 API 并集成到其他工具中

  • Clang 有静态分析,GCC 没有

  • Clang 使用 BSD 许可证,GCC 使用 GPL 许可证

许可证
  • GCC 优势

支持 JAVA/ADA/FORTRAN

GCC 支持更多平台

GCC 更流行,广泛使用,支持完备

GCC 基于 C,不需要 C++ 编译器即可编译

GCC、LLVM 和 Clang 如何选择?

不推荐老 GCC 4.2,苹果不会维持了
LLVM-GCC 更好 在项目中途改编译选项可是一个大变动,需要慎重

新项目 LLVM-GCC 是个安全的选择
苹果公司认为它够稳定够成熟,所以才把它当做 Xcode 4 的预设选项
既然选项使用的是 GCC parser,向后兼容性应该没问题

LLVM-GCC 是个安全的选项,但并不是指 Clang/LLVM 比较不安全,只是成熟度还沒那么高效了

LLVM 的颠覆性设计
  • 核心价值:

    • 前后端解耦
      新增语言只需实现新前端(如Rust前端rustc)

    • 优化器复用
      通用IR使优化算法跨平台共享

    • 生态扩展
      允许开发者插入自定义Pass(如安全检查Pass)

GCC 的局限性
  • 代码高度耦合,难以抽取优化模块

  • 苹果对Objective-C扩展受阻(如ARC内存管理)

  • 插件机制弱,难以集成到IDE

工具链选型建议

场景

推荐方案

原因

跨平台C/C++开发

GCC

成熟稳定,平台支持最广

macOS/iOS生态开发

Clang+LLVM

深度集成Xcode,对Apple技术栈优化最佳

需要高级静态分析

Clang

内置Clang Static Analyzer

定制编译器优化

LLVM SDK

可编程插入自定义优化Pass

兼容历史GCC项目

LLVM-GCC

平衡兼容性与LLVM后端优化

调试器兼容性

  • GDB(GNU Debugger) 作为通用调试标准

    • 只要编译器生成 DWARF调试信息(Clang/GCC均支持)

    • 示例:Clang编译时添加-g选项即可用GDB调试

总结 - LLVM

传统编译器工作的时候

前端 负责解析源代码,检查语法错误,将其翻译为抽象的语法树(Abstract Syntax Tree)
后端 负责将优化器优化后的中间代码转换为目标机器的代码
这一过程后端会最大化的利用目标机器的特殊指令,以提高代码的性能
这一模型的好处是 支持多种语言时,只需要添加多个前端就可以了
当需要支持多种目标机器时,只需要添加多个后端就可以了
对于中间的优化器,可以使用通用的中间代码

三段式的结构
开发前端的人只需要知道如何将源代码转换为优化器能够理解的中间代码就可以了
不需要知道优化器的工作原理,也不需要了解目标机器的知识
大大降低了编译器的开发难度,使更多的开发人员可以参与进来
虽然这种三段式的编译器有很多优点,并且被写到了教科书上,但是在实际中这一结构却从来没有被完美实现过
做的比较好的应该属 Java 和 .NET 虚拟机
虚拟机可以将目标语言翻译为 bytecode,理论上将任何语言翻译为 bytecode,然后输入虚拟机中运行
但是 动态语言的模型 不适合 C 语言,所以硬将 C 语言翻译为 bytecode 并实现垃圾回收机制的效率是非常低的

GCC 也将三段式做的比较好,并且实现了很多前端,支持了很多语言。
但是上述这些编译器的致命缺陷是,他们是一个完整的可执行文件,没有给其它语言的开发者提供代码重用的接口
GCC 是开源的,但是源代码重用的难度较大

LLVM 定位是底层的虚拟机
是为了解决编译器代码重用的问题,LLVM 一上来就站在比较高的角度,制定了 LLVM IR 这一中间代码表示语言

LLVM IR 充分考虑了各种应用场景
如在 IDE 中调用 LLVM 进行实时的代码语法检查,对静态语言、动态语言的编译、优化等。

LLVM 不仅仅是 Compiler Collection,也是Libraries Collection

LLVM 不仅仅是编译器,也是一个 SDK
Apple LLVM compiler 4.2 是一个真正的 LLVM 编译器,前端使用的是 Clang,基于最新的 LLVM 3.2 编译的
LLVM GCC 4.2 编译器的核心仍然是 LLVM,但是前端使用的是 GCC 4.2 编译器