美文网首页
【LLVM】LLVM编译流程

【LLVM】LLVM编译流程

作者: 爱笑的云里看梦 | 来源:发表于2018-05-09 15:21 被阅读118次

LLVM的编译流程

在介绍编译流程之前,首先回顾一下LLVM:
LLVM是一个模块化的、可重用的编译器和工具链技术的集合,Clang 是 LLVM 的子项目,是 C,C++ 和 Objective-C 编译器,它的编译速度比GCC快3倍,其中clang static analyzer主要进行语法分析、语义分析以及生成中间代码,在这个过程中会对代码进行检查,对于出错以及警告的代码会给与标记。此外,LLVM核心库还提供一个优化器,对流行的CPU做生成代码的支持(如x86等机器)。lld是Clang/LLVM的内置链接器,clang必须调用链接器来产生可执行文件。

LLVM相对于其它编译器的特殊性在于它提供一种代码编写良好的中间表示IR,这意味着它可以作为多种语言的后端,这样它就可以在提供语言无关的优化的同时还可以针对不同的硬件设备(CPU)生成对应的机器代码。

在介绍LLVM的编译流程之前,对于编译器的编译链接过程需要有一定的了解,可以参阅这些文章

快速开始——介绍LLVM编译流程

我们从一个例子开始,观察一次编译过程是如何完成的。首先我们编写如下的代码:

#import <Foundation/Foundation.h>
#define DEFINEEight 8
int main(){
    @autoreleasepool {
        int eight = DEFINEEight;
        int six = 6;
        NSString* site = [[NSString alloc] initWithString:@"starming"];
        int rank = eight + six;
        NSLog(@"%@ rank %d", site, rank);
    }
    return 0;
}

可以看到这段代码输出一个字符串和相加后的数字。将此代码保存为main.m文件。然后使用clang对其进行编译:

clang -ccc-print-phases main.m

可以看到编译过程输出如下:


编译流程
  • 0步骤获得源代码main.m,是OC语言。
  • 1步骤是预处理阶段,做相应处理(后面会提到)
  • 2步骤是编译阶段
  • 3步骤通过后端进行汇编前的处理
  • 4步骤汇编阶段
  • 5步骤链接阶段,做相应处理
  • 6步骤绑定相应变量(或常量等)到硬件机器上(如寄存器)
    通过如上步骤可以了解到整个过程以及过程中的一些信息。例如首先进行的预处理操作可以使用如下命令查看具体信息:
clang -E main.m

执行完后可以看到预处理后的样子:


预处理后

这个过程包括宏的替换,头文件的导入等等。在预处理完成后会进行词法分析,在此步骤会把代码切成一个个Token,比如大小括号,等于号还有字符串等。通过如下命令可以看到词法分析后的结果:

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

词法分析结果如下:


词法分析

接下来是语法分析,验证程序的语法是否正确,然后将所有的节点组成抽象语法树AST:

clang -fmodules -fsyntax-only -Xclang -ast-dump main.m
AST

这些步骤完成之后就要开始进行IR中间代码的生成了,代码生成器CodeGen会负责将语法树自顶向下遍历逐步翻译成LLVM IR,IR就是编译过程的前端的输出以及后端的输入:

clang -S -fobjc-arc -emit-llvm main.m -o main.ll

此步骤LLVM会去做些优化工作,在Xcode的编译设置里也可以设置优化的级别-01,-03,-0s等,还可以通过编写自己的pass自定制优化解决方案,编写自己的Pass请参阅[这篇文章]

clang -O3 -S -fobjc-arc -emit-llvm main.m -o main.ll

什么是pass呢,可以将pass理解为LLVM优化工作的一个节点,一个节点做一些事,把这些节点加起来就构成了LLVM完整的优化器了。而且当你在Xcode里开启了bitcode的话还会做进一步的优化工作:对于新的后端架构可以使用这份优化后的bitcode去生成。这也是LLVM灵活性的一个体现吧。
开启bitcode优化:

clang -emit-llvm -c main.m -o main.bc

生成汇编的命令:

clang -S -fobjc-arc main.m -o main.s

再生成目标文件:

clang -fmodules -c main.m -o main.o

最后生成可执行文件:

clang main.o -o main

这样通过执行./main就可以看到程序的执行结果啦!starming rank 14

那么以上就是LLVM的整个编译流程了。对于具体的Clang编译过程中的细节问题,将在后续的文章中进行介绍和讨论。欢迎关注!

相关文章

  • 二十五、LLVM

    什么是编译器 LLVM概述 LLVM案例体验 LLVM源码 & 编译流程 1 什么是编译器? 1.1 Python...

  • LLVM初探

    编译 想必都知道,那么LLVM是什么?LLVM是一种编译器!LLVM编译流程是怎么样的?本篇就LLVM进行初探 首...

  • iOS-底层原理 31:LLVM编译流程 & Clang插件开发

    iOS-底层原理 31:LLVM编译流程 & Clang插件开发 本文主要是理解LLVM的编译流程以及clang插...

  • 【LLVM】LLVM编译流程

    LLVM的编译流程 在介绍编译流程之前,首先回顾一下LLVM:LLVM是一个模块化的、可重用的编译器和工具链技术的...

  • LLVM编译流程 & Clang插件开发

    本文主要是理解LLVM的编译流程以及clang插件的开发 LLVM LLVM是架构编译器的框架系统,以C++编写而...

  • iOS-底层原理:LLVM编译流程 & Clang插件开发

    本文主要是理解LLVM的编译流程以及clang插件的开发 LLVM LLVM是架构编译器的框架系统,以C++编写而...

  • iOS llvm-2

    本文主要是理解LLVM的编译流程以及clang插件的开发 LLVM LLVM是架构编译器的框架系统,以C++编写而...

  • iOS llvm-1

    LLVM 传统编译器 LLVM区别于传统的编译器,它前端和后端分开了 LLVM流程1.所有的代码会经过[词法分析,...

  • LLVM编译流程

    前言 作为一个合格的iOS开发者,我们必须清楚,我们平时写的代码,是如何一步步转变生成App包的,这个过程就是我们...

  • LLVM编译流程

    转载:go博文[https://juejin.cn/post/6937226907389788168]

网友评论

      本文标题:【LLVM】LLVM编译流程

      本文链接:https://www.haomeiwen.com/subject/mmwnrftx.html