LLVM是可重用,可扩展的编译器和工具链后端的集合,可以方便的对新编程语言与新运行平台做最小化的兼容处理

llvm官网

https://llvm.org

为什么不再使用gcc

三段式编译工具链
  • gcc是GNU组织的开源的传统三段式的编译器套件

  • 传统的三段式编译工具链如图:

  • 分为前端,优化器,后端

  • 前端(Frontend):解析代码,检查静态语法,创建语法树(AST)

  • 优化器(Optimizer):根据选项,做部分代码优化

  • 后端(Backend):生成机器码(汇编)

[Retargetablity]

三段式的优点:

编译器的维护者只需要关注前端的逻辑,和后端分离,避免了为增加一种语言,需要再重复实现后端逻辑的冗余工作量

gcc的问题

  • gcc是一个完整的可执行文件,后端的优化器不能给其它语言提供重用的接口,即使是开源的,对于新增一种语言的代价也很大,需要重新实现相应的前端,优化等逻辑
  • 对于苹果而言,gcc对于自家的语言支持不给力,效率和插件,工具支持薄弱等问题
  • 性能问题gcc效率低,clang更快
  • 对整体工具链的掌控lldb 支持新语言等

llvm

  • llvm是指的是优化器和后端

  • llvm全称Low Level Virtual Machine(低级虚拟机),本身定位是虚拟机,类似jvm,属于编译器后端

  • IR:llvm最重要的一个部分就是IR全程为 Intermediate Representation (中间代码)

优势:

  • 优化器:共享优化器,每次新增语言都可以重用以前的优化器

  • llvm下的三段式编译结构

[LLVM's Implementation of the Three-Phase Design]

  • Clang是c语言系列的前端编译器,

  • swift是swift语言的前端编译器,相比Clang多了sil

    • Swift 中间语言(Swift Intermediate Language,SIL)是一门高级且专用于 Swift 的中间语言,适用于对 Swift 代码的进一步分析和优化

编译流程

  1. 预处理:

    1. 宏展开
  2. 词法分析

    1. 词法分析

    2. 预处理代码文本转为token

    3. 不校验语义

      1
      $clang -fmodules -fsyntax-only -Xclang -dump-tokens main.m

      展示为以token为单位的结构代码

  3. 语法分析(Semantic Analysis)

    1. Clang中由Parser和Sema两个模块实现

      1
      #clang -fmodules -fsyntax-only -Xclang -ast-dump main.m

      生成语法树

      静态分析(Static Analysis)

      1. 通过语法树进行静态分析,找出非语法性错误
      2. `模拟代码执行路径,
      3. Checker
  4. CodeGen-IR 代码生成

    1. 与oc runtime桥接
      1. Class/Meta Class/Protocol/Category内存结构生成,放在指定section中
      2. Method/Ivar/Property内存结构生成
      3. Class中method_list/ivar_list/property_list结构生成
    2. BitCode
      1. IR 生成二进制码
  5. 生成汇编(Assemble)

  6. 生成Target相关Object(Mach-O)

  7. 链接

参考资料