iOS之LLVM架构

2020-01-03  本文已影响0人  好_好先生

编译器架构

传统编译器架构(Three-Phase)

Three-Phase.png

上图是最简单的三段式编译器架构。

Apple支持的语言

C
C++
Objective-C
Swift
...

iPhone CPU架构

指令集对应的机型:
2019 A13芯片arm64e : iphone11、iphone11 Pro
2018 A12芯片arm64e : iphone XS、iphone XS Max、iphoneXR
2017 A11芯片arm64: iPhone 8、iPhone 8 Plus、and iPhone X
2016 A10芯片arm64:iPhone 7、7 Plus、iPad (2018)
2015 A9芯片arm64: iPhone 6S、6S Plus 
2014 A8芯片arm64: iPhone 6、iPhone 6 Plus
2013 A7芯片arm64: iPhone 5S
armv7s:iPhone5、iPhone5C、iPad4(iPad with Retina Display)
armv7:iPhone4、iPhone4S、iPad、iPad2、iPad3(The New iPad)、iPad mini、iPod Touch 3G、iPod Touch4

模拟器32位处理器测试需要i386架构
模拟器64位处理器测试需要x86_64架构
真机32位处理器需要armv7,或者armv7s架构
真机64位处理器需要arm64架构

LLVM:

The name "LLVM" itself is not an acronym; it is the full name of the project
"LLVM"这个名称本身不是首字母缩略词;它是项目的全名

LLVM.png
LLVM百度百科

LLVM架构:

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

GCC:

GCC架构.jpeg
GCC百度百科.png
GCC百度百科

GCC的消亡与Clang的崛起

Apple一直使用GCC作为官方的编译器。GCC作为开源世界的编译器标准一直做得不错,但Apple对编译工具会提出更高的要求。
一方面,是Apple对Objective-C语言新增很多特性,但GCC开发者并不买Apple的账--不给实现,因此索性后来两者分成两条分支分别开发,这也造成Apple的编译器版本远落后于GCC的官方版本。另一方面,GCC的代码耦合度太高,不好独立,而且越是后期的版本,代码质量越差,但Apple想做的很多功能(比如更好的IDE支持)需要模块化的方式来调用GCC,但GCC一直不给做。所以,这种不和让Apple一直在寻找一个高效的、模块化的、协议更放松的开源替代品。GCC系统庞大而笨重,而Apple大量使用的Objective-C在GCC中优先级很低。此外GCC作为一个纯粹的编译系统,与IDE配合得很差。加之许可证方面的要求,Apple无法使用LLVM 继续改进GCC的代码质量。于是,Apple决定从零开始写 C、C++、Objective-C语言的前端 Clang,完全替代掉GCC。

Clang

相比GCC,Clang具有如下优点:

OC源代码的前端编译过程

源代码:

#include <stdio.h>

#define AGE 40

int main(int argc, const char * argv[]) {
    int a = 10;
    int b = 20;
    int c = a + b + AGE;
    
    return 0;
}
0: input, "main.m", objective-c //找到源代码:main.m 文件
1: preprocessor, {0}, objective-c-cpp-output //预处理器,include,import 宏定义换掉
2: compiler, {1}, ir // 编译成ir 中间代码
3: backend, {2}, assembler // 后端 交给后端
4: assembler, {3}, object // 目标代码 
5: linker, {4}, image // 链接 其他一些静态库动态库
6: bind-arch, "x86_64", {5}, image // 适合某个架构的代码

预处理(preprocessor)

词法分析

annot_module_include '#include <stdio.h>

#define AGE 40

int main(int argc, const char * argv[]) {
    int a = 10;
    int b = 20;
    int c = a + b '     Loc=<main.m:9:1>
int 'int'    [StartOfLine]  Loc=<main.m:13:1>
identifier 'main'    [LeadingSpace] Loc=<main.m:13:5>
l_paren '('     Loc=<main.m:13:9>
int 'int'       Loc=<main.m:13:10>
identifier 'argc'    [LeadingSpace] Loc=<main.m:13:14>
comma ','       Loc=<main.m:13:18>
const 'const'    [LeadingSpace] Loc=<main.m:13:20>
char 'char'  [LeadingSpace] Loc=<main.m:13:26>
star '*'     [LeadingSpace] Loc=<main.m:13:31>
identifier 'argv'    [LeadingSpace] Loc=<main.m:13:33>
l_square '['        Loc=<main.m:13:37>
r_square ']'        Loc=<main.m:13:38>
r_paren ')'     Loc=<main.m:13:39>
l_brace '{'  [LeadingSpace] Loc=<main.m:13:41>
int 'int'    [StartOfLine] [LeadingSpace]   Loc=<main.m:14:5>
identifier 'a'   [LeadingSpace] Loc=<main.m:14:9>
equal '='    [LeadingSpace] Loc=<main.m:14:11>
numeric_constant '10'    [LeadingSpace] Loc=<main.m:14:13>
semi ';'        Loc=<main.m:14:15>
int 'int'    [StartOfLine] [LeadingSpace]   Loc=<main.m:15:5>
identifier 'b'   [LeadingSpace] Loc=<main.m:15:9>
equal '='    [LeadingSpace] Loc=<main.m:15:11>
numeric_constant '20'    [LeadingSpace] Loc=<main.m:15:13>
semi ';'        Loc=<main.m:15:15>
int 'int'    [StartOfLine] [LeadingSpace]   Loc=<main.m:16:5>
identifier 'c'   [LeadingSpace] Loc=<main.m:16:9>
equal '='    [LeadingSpace] Loc=<main.m:16:11>
identifier 'a'   [LeadingSpace] Loc=<main.m:16:13>
plus '+'     [LeadingSpace] Loc=<main.m:16:15>
identifier 'b'   [LeadingSpace] Loc=<main.m:16:17>
plus '+'     [LeadingSpace] Loc=<main.m:16:19>
numeric_constant '40'    [LeadingSpace] Loc=<main.m:16:21 <Spelling=main.m:11:13>>
semi ';'        Loc=<main.m:16:24>
return 'return'  [StartOfLine] [LeadingSpace]   Loc=<main.m:18:5>
numeric_constant '0'     [LeadingSpace] Loc=<main.m:18:12>
semi ';'        Loc=<main.m:18:13>
r_brace '}'  [StartOfLine]  Loc=<main.m:19:1>
eof ''      Loc=<main.m:19:2>

语法分析

void test(int a, int b) {
    int c = a + b -3;
}
语法分析.png
语法分析2.png

swift生成语法树:swiftc -dump-ast main.swift
swfit生成SIL代码:swiftc -emit-sil main.swift

生成中间代码(LLVM IR)

官方语法参考:
https://llvm.org/docs/LangRef.html

LLVM-IR.jpeg

文章参考:
https://www.jianshu.com/p/9dbb5930f0ea
https://blog.csdn.net/xhhjin/article/details/81164076
https://ke.qq.com/course/322016

上一篇 下一篇

猜你喜欢

热点阅读