一、什么是LLVM?

  • 官网:https://llvm.org/
  • The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
    LLVM项目是模块化、可重用的编译器以及工具链技术的集合。)
  • 美国计算机协会 (ACM) 将其2012年软件系统奖项颁给了LLVM,之前曾经获得此奖项的软件和技术包括:JavaApacheMosaicthe World Wide WebSmalltalkUNIXEclipse等等
  • 创始人Chris Lattner,亦是Swift之父;
  • 有些文章把LLVM当做Low Level Virtual Machine(低级虚拟机)的缩写简称,官方描述如下:The name "LLVM" itself is not an acronym; it is the full name of the project.(LLVM这个名称本身不是首字母缩略词; 它是项目的全名)

二、传统的编译器架构和LLVM架构


  • 不同的前端后端使用统一的中间代码LLVM Intermediate Representation (LLVM IR)
  • 如果需要支持一种新的编程语言,那么只需要实现一个新的前端
  • 如果需要支持一种新的硬件设备,那么只需要实现一个新的后端
  • 优化阶段是一个通用的阶段,它针对的是统一的LLVM IR,不论是支持新的编程语言,还是支持新的硬件设备,都不需要对优化阶段做修改
  • 相比之下,GCC的前端和后端没分得太开,前端后端耦合在了一起。所以GCC为了支持一门新的语言,或者为了支持一个新的目标平台,就变得特别困难
  • LLVM现在被作为实现各种静态和运行时编译语言的通用基础结构(GCC家族、Java.NETPythonRubySchemeHaskellD等)

三、Clang

  • 什么是Clang

    • LLVM项目的一个子项目
    • 基于LLVM架构的C/C++/Objective-C编译器前端
    • 官网:http://clang.llvm.org/
  • 相比于GCCClang具有如下优点

  • 编译速度快:在某些平台上,Clang的编译速度显著的快过GCCDebug模式下编译OC速度比GGC3倍

  • 占用内存小:Clang生成的AST所占用的内存是GCC的五分之一左右

  • 模块化设计:Clang采用基于库的模块化设计,易于IDE集成及其他用途的重用

  • 诊断信息可读性强:在编译过程中,Clang创建并保留了大量详细的元数据 (metadata),有利于调试和错误报告

  • 设计清晰简单,容易理解,易于扩展增强

四、Clang与LLVM

五、OC源文件的编译过程

  • 命令行查看编译的过程:$ clang -ccc-print-phases main.m
  • 查看preprocessor(预处理)的结果:$ clang -E main.m

六、词法分析

  • 词法分析,生成Token$ clang -fmodules -E -Xclang -dump-tokens main.m


七、语法树-AST

  • 语法分析,生成语法树(ASTAbstract Syntax Tree): $ clang -fmodules -fsyntax-only -Xclang -ast-dump main.m


八、LLVM IR

  • LLVM IR有3种表示形式(但本质是等价的,就好比水可以有气体、液体、固体3种形态)
    • text:便于阅读的文本格式,类似于汇编语言,拓展名.ll$ clang -S -emit-llvm main.m
    • memory:内存格式
    • bitcode:二进制格式,拓展名.bc$ clang -c -emit-llvm main.m

  • IR基本语法
    • 注释以分号 ; 开头
    • 全局标识符以@开头,局部标识符以%开头
    • alloca,在当前函数栈帧中分配内存
    • i3232bit,4个字节的意思
    • align,内存对齐
    • store,写入数据
    • load,读取数据
  • 官方语法参考

九、源码下载

  • 下载LLVM

    • $ git clone https://git.llvm.org/git/llvm.git/
    • 大小746.2 MB,仅供参考
  • 下载clang

    • $ cd llvm/tools
    • $ git clone https://git.llvm.org/git/clang.git/
    • 大小297.7 MB,仅供参考

十、源码编译

  • 安装cmakeninja(先安装brewhttps://brew.sh/

    • $ brew install cmake
    • $ brew install ninja
  • ninja如果安装失败,可以直接从github获取release版放入【/usr/local/bin】

  • 在LLVM源码同级目录下新建一个【llvm_build】目录(最终会在【llvm_build】目录下生成【build.ninja】

  • 依次执行编译、安装指令

    • $ ninja
    • 编译完毕后,【llvm_build】目录大概21.05 G(仅供参考)
    • $ ninja install
    • 安装完毕后,安装目录大概11.92 G(仅供参考)
  • 也可以生成Xcode项目再进行编译,但是速度很慢(可能需要1个多小时)

  • llvm同级目录下新建一个【llvm_xcode】目录

    • cd llvm_xcode
    • $ cmake -G Xcode ../llvm



十一、应用与实践