Swift编译 SIL分析
文章目录
- Swift编译 & SIL分析
- 1.Swift与OC编译区别
- 2.Swift编译流程
- 3. swiftc命令
- 4. SIL分析
- 1.创建项目,在`main.swift`写入以下代码:
- 2.查看`AST`语法树:`swiftc -dump-ast main.swift`
- 4.1 `LGTeacher`分析:
- 4.2 `main`函数分析:
- 4.4 `LGTeacher.__allocating_init`分析:
- 4.5 查看`LLVM IR`代码:`swiftc -emit-ir main.swift`
- 4.6 查看汇编代码:`swiftc -emit-assembly main.swift`
Swift编译 & SIL分析
1.Swift与OC编译区别
1.Swfit使用前端编译器swiftc,降级编译成IR,再通过后端编译器LLVM生成.o可执行文件。
2.OC使用前端编译器Clang编译出IR,再通过后端编译器LLVM生成.o可执行文件。
2.Swift编译流程
SwiftCode
->通过词法分析、语法分析(-dump-parse
)->生成AST
抽象语法树(-dump-ast
)->通过SILGen生成未优化代码量巨大的RawSIL文件(-emit-silgen
)->再拿到优化后更简洁的Canonical SIL
(-emit-sil
)->通过IRGen
生成IR(-emit-ir
)->最终生成二进制代码
3. swiftc命令
使用swiftc -h
,查看所有命令
-dump-ast 语法和类型检查,打印AST语法树
-dump-parse 语法检查,打印AST语法树
-dump-pcm 转储有关预编译Clang模块的调试信息
-dump-scope-maps <expanded-or-list-of-line:column> Parse and type-check input file(s) and dump the scope map(s)
-dump-type-info Output YAML dump of fixed-size types from all imported modules
-dump-type-refinement-contexts Type-check input file(s) and dump type refinement contexts(s)
-emit-assembly 输出汇编文件 (-S)
-emit-bc 输出一个LLVM的BC文件
-emit-executable 输出一个可执行文件
-emit-imported-modules 展示导入的模块列表
-emit-ir 展示IR中间代码
-emit-library 输出一个dylib动态库
-emit-object 输出一个.o机器文件
-emit-pcm 从模块映射中输出预编译Clang模块
-emit-sibgen 输出一个.sib的原始SIL文件
-emit-sib 输出一个.sib的标准SIL文件
-emit-silgen 展示原始SIL文件
-emit-sil 展示标准的SIL文件
-index-file 为源文件生成索引数据
-parse 解析文件
-print-ast 解析文件并打印(漂亮/简洁的)语法树
-resolve-imports 解析import导入的文件
-typecheck 检查文件类型
4. SIL分析
1.创建项目,在main.swift
写入以下代码:
import Foundationclass LGTeacher{var age: Int=18;var name: String="Zang";
}var t=LGTeacher();
2.查看AST
语法树:swiftc -dump-ast main.swift
语法树可以干很多事情,比如针对当前代码校验,这里会涉及到大量编译器知识。
查看优化后SIL代码:swiftc -emit-sil main.swift
4.1 LGTeacher
分析:
//LGTeacher
class LGTeacher {//age和name两个存储属性@_hasStorage @_hasInitialValue var age: Int { get set }@_hasStorage @_hasInitialValue var name: String { get set }//@objc标记的deinit方法@objc deinit//init方法init()
}@_hasStorage @_hasInitialValue var t: LGTeacher { get set }// t
//这个复杂的字符串就是当前的t,只是经过了swift混写之后的
//可以使用xcrun命令进行还原
sil_global hidden @$s4main1tAA9LGTeacherCvp : $LGTeacher
//通过
xcrun
命令还原混写后的字符串:
xcrun swift-demangle s4main1tAA9LGTeacherCvp
//输出结果:
$s4main1tAA9LGTeacherCvp ---> main.t : main.LGTeacher
4.2 main
函数分析:
// main
//@main就是应用程序的入口,
//@convention(c)表示c函数
//函数里有两个参数,一个Int32位整形参数,一个UnsafeMutablePointer指针参数
//函数有一个Int32位整形的返回值
sil @main : $@convention(c) (Int32, UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>) -> Int32 {bb0(%0 : $Int32, %1 : $UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>)://%0、%1...表示寄存器,与register read不是一个东西,这里的只是虚拟寄存器//一旦赋值就不会再改变,类似编程语言中的开发常量//alloc_global:分配全局变量,其实就是上面的t//看这里的@$s4main1tAA9LGTeacherCvp,和上面的t完全一致 alloc_global @$s4main1tAA9LGTeacherCvp // id: %2//global_addr:将全局变量地址赋值给%3%3 = global_addr @$s4main1tAA9LGTeacherCvp : $*LGTeacher // user: %7//将LGTeacher.Type,也就是元类型赋值给%4%4 = metatype $@thick LGTeacher.Type // user: %6// function_ref LGTeacher.__allocating_init()// 拿到__allocating_init的方法地址赋值给%5%5 = function_ref @$s4main9LGTeacherCACycfC : $@convention(method) (@thick LGTeacher.Type) -> @owned LGTeacher // user: %6// 通过apply调用%5也就是__allocating_init函数,并传入参数%4,将返回值赋值给%6%6 = apply %5(%4) : $@convention(method) (@thick LGTeacher.Type) -> @owned LGTeacher // user: %7//将返回的实例结果%6存储到%3store %6 to %3 : $*LGTeacher // id: %7//构建0,返回状态码%8 = integer_literal $Builtin.Int32, 0 // user: %9%9 = struct $Int32 (%8 : $Builtin.Int32) // user: %10return %9 : $Int32 // id: %10
} // end sil function 'main'
总结:
@main
这⾥标识我们当前main.swift
的⼊⼝函数,SIL
中的标识符名称以@
作为前缀
-%0,%1...
在 SIL也叫做寄存器,这⾥我们可以理解为我们⽇常开发中的常量,⼀旦赋值之后就不可 以再修改,如果SIL
中还要继续使⽤,那么就不断的累加数字。同时这⾥所说的寄存器是虚拟的,最 终运⾏到我们的机器上,会使⽤真的寄存器。alloc_gobal
创建⼀个全局变量global_addr
拿到全局变量的地址,赋值给%3
metatype
拿到LGTeacher
的Metadata
赋值给%4
- 将
__allocating_init
的函数地址赋值给%5
apply
调⽤__allocating_init
, 并把返回值给%6
- 将
%6
的值存储到%3
(也就是我们刚刚创建的全局变量的地址) - 构建
Int
,并return
4.4 LGTeacher.__allocating_init
分析:
// LGTeacher.__allocating_init()
sil hidden [exact_self_class] @$s4main9LGTeacherCACycfC : $@convention(method) (@thick LGTeacher.Type) -> @owned LGTeacher {// %0 "$metatype"bb0(%0 : $@thick LGTeacher.Type)://alloc_ref:在堆上分配内存空间%1 = alloc_ref $LGTeacher // user: %3// function_ref LGTeacher.init()//调用init方法,初始化当前变量%2 = function_ref @$s4main9LGTeacherCACycfc : $@convention(method) (@owned LGTeacher) -> @owned LGTeacher // user: %3//将实例变量返回%3 = apply %2(%1) : $@convention(method) (@owned LGTeacher) -> @owned LGTeacher // user: %4return %3 : $LGTeacher // id: %4
} // end sil function '$s4main9LGTeacherCACycfC'
总结:
alloc_ref
创建⼀个LGTeacher
的实例对象,当前实例对象的默认引⽤计数为1
调⽤init
⽅法
4.5 查看LLVM IR
代码:swiftc -emit-ir main.swift
4.6 查看汇编代码:swiftc -emit-assembly main.swift
Swift编译 SIL分析相关推荐
- 编译时如何看到每个文件的编译选项_导出 Clang 可视化编译耗时分析报告 —— ftimetrace 的使用...
前言 笔者最近加入了新的团队,开始负责编译打包相关工作,因而开始学习优化编译时间相关技术.讲真,蛮开心的,每天都有挑战,同时每天都有收获,天天都在涨姿势,所以想记录下来并分享出来,也方便以后自己需要时 ...
- yocto 编译流程分析
yocto 编译流程分析 2015年04月15日 10:55:13 日月星辰007 阅读数:4955 git clone 一份poky 的工程到本地. source poky/oe-init-buil ...
- TMS320C6678开发笔记---IBL编译与分析1
第9节 IBL编译与分析 9.1节 MinGW安装 下载与安装参考文章:https://blog.csdn.net/kunkliu/article/details/106786512 安装建议:将 ...
- 高通Android智能平台环境搭建_编译流程分析
高通Android智能平台环境搭建_编译流程分析 高通平台环境搭建,编译,系统引导流程分析 TOC \o \h \z \u 1. 高通平台android开发总结. 7 1.1 搭建高通平台环境开发环境 ...
- Linux——Linux驱动之Makefile编译总结(编译器路径设置、编译流程分析、编译试验测试)
目录 0 引言 1 编译器路径设置 2 Makefile编译文件 3 Linux内核编译流程分析 4 编译试验测试
- qualcomm amss 文件结构以及编译流程分析
qualcomm amss 文件结构以及编译流程分析 https://blog.csdn.net/npjocj/article/details/8206695 AMSS的source实际上是Qualc ...
- XR871SDK编译框架分析
XR871SDK编译框架分析: -> 从/src/project/echocloud_demo/gcc 输入make编译, 解析当前文件夹下的Makefile文件: # # Rules for ...
- Android OTA在线升级二(升级包编译原理分析) 【转】
本文转载自:http://blog.csdn.net/huryjiang/article/details/7590015 1 升级包的制作 基本命令: Ø makeMtk [project[flav ...
- 【C 语言】编译过程 分析 ( 预处理 | 编译 | 汇编 | 链接 | 宏定义 | 条件编译 | 编译器指示字 )
相关文章链接 : 1.[嵌入式开发]C语言 指针数组 多维数组 2.[嵌入式开发]C语言 命令行参数 函数指针 gdb调试 3.[嵌入式开发]C语言 结构体相关 的 函数 指针 数组 4.[嵌入式开发 ...
最新文章
- Magnetism and Earnshaw‘s Theorem
- WEB学习-CSS盒模型
- sizeof()与strlen()
- 一瓶可乐的自动售货机指令“旅程”
- Windows Mobile 开发系列文章收藏 - Windows Mobile 6.x
- mac mysql not found_mac版mysql安装后显示mysql: command not found咋整?
- c 运算符重载前置++_C ++运算符重载–综合指南
- 3. mysql的注解驱动的三种方式_上手spring boot项目(三)之spring boot整合mybatis进行增删改查的三种方式。...
- DOS 系统安装工具
- 安徽省计算机二级水平考试试卷,2010安徽省全国计算机等级考试二级笔试试卷VB试题及答案...
- 浙大PAT甲级 1080
- 微信小程序弹窗提示怎么写
- WPS演示常用快捷键大全
- 编写一个程序求解字谜游戏
- 《C++高级进阶》读书笔记 第一章 C++基础知识
- cesium.js官网教程之中文版本~~~~第一篇
- 幅频特性曲线protues_幅频特性曲线Matlab编程
- 使用latex撰写Elsevier双栏论文,表格标题caption左对齐问题
- Python 数据分析微专业课程--项目实战11 中国城市资本流动问题探索
- Refactor this method to reduce its Cognitive Complexity from 65 to the 15 allowed. [+22 locations]