文章目录

  • 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拿到LGTeacherMetadata赋值给%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分析相关推荐

  1. 编译时如何看到每个文件的编译选项_导出 Clang 可视化编译耗时分析报告 —— ftimetrace 的使用...

    前言 笔者最近加入了新的团队,开始负责编译打包相关工作,因而开始学习优化编译时间相关技术.讲真,蛮开心的,每天都有挑战,同时每天都有收获,天天都在涨姿势,所以想记录下来并分享出来,也方便以后自己需要时 ...

  2. yocto 编译流程分析

    yocto 编译流程分析 2015年04月15日 10:55:13 日月星辰007 阅读数:4955 git clone 一份poky 的工程到本地. source poky/oe-init-buil ...

  3. TMS320C6678开发笔记---IBL编译与分析1

    第9节  IBL编译与分析 9.1节  MinGW安装 下载与安装参考文章:https://blog.csdn.net/kunkliu/article/details/106786512 安装建议:将 ...

  4. 高通Android智能平台环境搭建_编译流程分析

    高通Android智能平台环境搭建_编译流程分析 高通平台环境搭建,编译,系统引导流程分析 TOC \o \h \z \u 1. 高通平台android开发总结. 7 1.1 搭建高通平台环境开发环境 ...

  5. Linux——Linux驱动之Makefile编译总结(编译器路径设置、编译流程分析、编译试验测试)

    目录 0 引言 1 编译器路径设置 2 Makefile编译文件 3 Linux内核编译流程分析 4 编译试验测试

  6. qualcomm amss 文件结构以及编译流程分析

    qualcomm amss 文件结构以及编译流程分析 https://blog.csdn.net/npjocj/article/details/8206695 AMSS的source实际上是Qualc ...

  7. XR871SDK编译框架分析

    XR871SDK编译框架分析: -> 从/src/project/echocloud_demo/gcc 输入make编译, 解析当前文件夹下的Makefile文件: # # Rules for ...

  8. Android OTA在线升级二(升级包编译原理分析) 【转】

    本文转载自:http://blog.csdn.net/huryjiang/article/details/7590015 1 升级包的制作 基本命令: Ø  makeMtk [project[flav ...

  9. 【C 语言】编译过程 分析 ( 预处理 | 编译 | 汇编 | 链接 | 宏定义 | 条件编译 | 编译器指示字 )

    相关文章链接 : 1.[嵌入式开发]C语言 指针数组 多维数组 2.[嵌入式开发]C语言 命令行参数 函数指针 gdb调试 3.[嵌入式开发]C语言 结构体相关 的 函数 指针 数组 4.[嵌入式开发 ...

最新文章

  1. Magnetism and Earnshaw‘s Theorem
  2. WEB学习-CSS盒模型
  3. sizeof()与strlen()
  4. 一瓶可乐的自动售货机指令“旅程”
  5. Windows Mobile 开发系列文章收藏 - Windows Mobile 6.x
  6. mac mysql not found_mac版mysql安装后显示mysql: command not found咋整?
  7. c 运算符重载前置++_C ++运算符重载–综合指南
  8. 3. mysql的注解驱动的三种方式_上手spring boot项目(三)之spring boot整合mybatis进行增删改查的三种方式。...
  9. DOS 系统安装工具
  10. 安徽省计算机二级水平考试试卷,2010安徽省全国计算机等级考试二级笔试试卷VB试题及答案...
  11. 浙大PAT甲级 1080
  12. 微信小程序弹窗提示怎么写
  13. WPS演示常用快捷键大全
  14. 编写一个程序求解字谜游戏
  15. 《C++高级进阶》读书笔记 第一章 C++基础知识
  16. cesium.js官网教程之中文版本~~~~第一篇
  17. 幅频特性曲线protues_幅频特性曲线Matlab编程
  18. 使用latex撰写Elsevier双栏论文,表格标题caption左对齐问题
  19. Python 数据分析微专业课程--项目实战11 中国城市资本流动问题探索
  20. Refactor this method to reduce its Cognitive Complexity from 65 to the 15 allowed. [+22 locations]

热门文章

  1. Java工程师资格证书
  2. 小米10Pro手机相机特性分析
  3. Linux 网络唤醒
  4. 朗读者李晓云清华大学计算机,世界杰出女科学家奖得主张弥曼现身《朗读者》...
  5. 55岁李连杰近照疯传:人生下半场,拼的是健康
  6. 二项分布均值和方差的推导
  7. 人人都能看懂的Spring底层原理,看完绝对不会懵逼
  8. 将一根木棍分成三段,求这三段构成三角形的概率
  9. 机器人控制器编程课程-教案04-综合
  10. 浅谈互联网DD攻击和CC攻击