iOS底层原理-LLVM

LLVM概述:

LLVM是架构编译器框架系统,以C++编写而成,用以优化任意程序语言编写的程序的编译时间、链接时间、运行时间、空闲时间,对开发者保持开放,并兼容已有的脚本。

传统编译器:

编译器前端:

编译器前端的任务是解析源代码。他会进行:词法分析,语法分析,语义分析,检查源代码是否存在错误,然后构建抽象语法树(AST),LLVM的前端还会生成中间代码(IR)。

优化器:

优化器负责进行各种优化。改变代码的运行时间,例如消除冗余计算等。

后端:

将代码映射到目标指令集。生成机器语言,并且进行机器语言相关的代码优化。

iOS的编译器架构:

Objective C/C/C++使用的编译器前端是Clang,Swift是Swift,后端都是LLVM。 

LLVM的设计

当编译器决定支持多种源语言或者多种硬件架构时,LLVM最重要的地方就来了。其他的编译器如GCC,他的方法非常成功,但由于它是作为整体应用程序设计的,因此它们的用途受到很大的限制。

LLVM设计最重要的方面是,使用通用的代码表示形式(IR),它是用来在编译器种表示代码的形式,所以LLVM可以为任何编程语言独立编写前端,并且可以为任意的硬件架构独立编写后端。

Clang

Clang是LLVM项目中的子项目,它是基于LLVM架构的轻型编译器,诞生之初是为了替代GCC,提供更快的编译速度。它是负责编译ObjectiveC/C/C++的编译器,它属于LLVM编译框架中的前端编译器。

编译流程

通过命令可以打印源码的编译阶段:

clang -ccc-print-phases main.m

 +- 0: input, "main.m", objective-c
            +- 1: preprocessor, {0}, objective-c-cpp-output
         +- 2: compiler, {1}, ir
      +- 3: backend, {2}, assembler
   +- 4: assembler, {3}, object
+- 5: linker, {4}, image
6: bind-arch, "x86_64", {5}, image
0:输入文件:找到源文件;
1:预处理阶段:这个过程处理包括宏的替换,头文件的导入;
2:编译阶段:进行词法分析、语法分析、语义分析,检查语法错误,生成IR代码;
3:后端:这里LLVM会通过一个一个Pass去优化,每个Pass做一些事,最终生成汇编语言;
4:生成目标文件;
5: 链接:链接需要的动态库和静态库,生成可执行文件;
6:通过不同的架构,生成可执行文件。

 例:main.m

#import <UIKit/UIKit.h>
#import "AppDelegate.h"

#define  a  10
#define  b  5

typedef int WD_INT;

int main(int argc, char * argv[]) {
    
    int c = 6;
    WD_INT d = 10;
    NSLog(@"%d",a);
    NSLog(@"%d",b);
    NSLog(@"%d",c);
    NSLog(@"%d",d);
    
    return  0;
}

预处理阶段

 执行如下命令:

clang -E main.m

执行完成可看到头文件的导入与宏的替换。

编译阶段

词法分析:

词法分析的时候,将代码拆分一个个token,比如大小括号,等于号,还有字符串等。

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

语法分析:

词法分析完成后进行语法分析,它的任务是验证语法是否正确。在词法分析的基础上将单词序列组合成各类语法短语,如程序,语句,表达式等,然后将所有的节点组合成抽象语法树(AST)。

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

生成中间代码(IR):

通过下面的命令可以生成.ll的文本文件,查看IR代码。

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

IR的优化:

 LLVM的优化级别分别是 -O0 -O1 -O2 -O3 -Os 

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

bitCode

Xcode7开启bitCode,苹果会进一步优化。生成.bc的中间代码。

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

生成汇编代码:

通过最终的.bc或者.ll代码生成汇编代码。

clang -S -fobjc-arc main.bc -o main.s
clang -S -fobjc-arc main.ll -o main.s

生成的汇编代码也可以进行优化:

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

生成目标文件:

 clang -fmodules -c main.s -o main.o

通过nm命令去查看main.o中的符号:

clang -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator15.0.sdk -fmodules -c main.s  -o main.o 

undefined 表示当前文件暂时找不到符号。

external 表示这个符号是外部可以访问的。

生成可执行文件(链接)

连接器把编译产生的.o文件和(.dylib.a)文件,生成mach.o文件。

clang main.o -o main

clang -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator15.0.sdk main.o -o main

通过nm命令去查看链接后的符号 

$xcrun nm -nm main 

 

Clang 插件

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值