SSA:终于知道 Go 编译器偷摸做了哪些事

共 2047字,需浏览 5分钟

 ·

2022-01-01 17:46


在go的源码和汇编码之间,其实编译器在你眼皮底下偷偷又做了不少事情,而ssa就是查看查看编译器优化行为的利器。

在golang中,我们可以使用go tool compile -S main.go 工具将一个go程序直接转换为汇编代码。但是你会发现,最终编译出来的汇编代码其实是已经被优化过了的,编译器其实很聪明,甚至将一些函数合并,取消等。至于这个过程,并不是一蹴而就的,在golang代码和最终的汇编代码中,还有一种中间的代码结构,这个结构就叫做SSA (Static Single Assignment) 静态单赋值。

这个中间的代码结构是有必要存在的,go源码解析后是一个AST树,是一个树形结构,而最终的汇编是一条一条的线性命令。将树形结构转化拆分优化为汇编命令是比较复杂的。所以这里将这么一个大的步骤分成两步走,能大大降低编译器优化的难度。

怎么生成ssa

我们可以使用命令 GOSSAFUNC=Foo go build index.go  来看我们将一个go源码,怎么转化为SSA的全过程的。

go代码

package array


func Foo () int {
 a := [3]int{1,3,5}
 i := 2
 elem := a[i]
 return elem
}

image-20211218225223395

生成ssa.html

怎么看ssa

image-20211218225244800

这个html中的ssa中间语言的语法是由 cmd/compile/internal/ssa/gen/genericOps.go 生成的。

image-20211218230201931

每一行和对应的SSA代码都标记出来了,有一些即使没有SSA的经验,也是能立马看懂的。比如像v10 是常量1,而v13是代表指针指向a[0], v14 代表将常量1存储进入a[0]。不过有一些则不是那么容易看出了。

通过中间可以看出过了很多优化步骤才最终生成了汇编码。

image-20211218230740078

有哪些步骤可以参考这里:https://github.com/golang/go/blob/release-branch.go1.15/src/cmd/compile/internal/ssa/compile.go#L418

至于每个步骤做了什么事情,这个就很复杂了。

关于ssa

关于ssa,我自己的理解就是,将源码的AST树,先演变成像

v1= xxx
v2= xxx
v3= xxx

这种线性执行语句。这种语句的特点就是每一行都定义了一个变量。所以叫“静态单赋值语句”。然后使用各种之间的赋值规则,可以很容易看出哪些赋值变量其实是没有用到的。对于没有用到的直接可以删除。当然还有其他各种规则,最终将v1...vn的赋值变量进行预计算,优化,最后优化为最简的几个赋值变量。这点可以从ssa.html的start到最后的trim就看出了。

最开始的源码

image-20211218231704579

切换为AST树

image-20211218231717903

再变成SSA语言

image-20211218231608947

经过不断优化,变成三个执行语言。(其实这个foo函数直接可以在编译阶段将5返回)

image-20211218231647243

最后再变化为汇编码:


这个编译器优化的过程,我感觉对于语言使用者还是主要适用于纯研究。

比如想研究下数组是在栈上分配内存还是在静态数据区分配内存,可以生成ssa看看。

或者想研究下哪行代码对应哪个内部函数等。

参考:

https://gocompiler.shizhz.me/10.-golang-bian-yi-qi-han-shu-bian-yi-ji-dao-chu/10.2.1-ssa

https://oftime.net/2021/02/14/ssa/

https://draveness.me/golang/docs/part1-prerequisite/ch02-compile/golang-ir-ssa/

https://github.com/golang/go/blob/master/src/cmd/compile/internal/ssa/README.md

https://en.wikipedia.org/wiki/Static_single_assignment_form



推荐阅读


福利

我为大家整理了一份从入门到进阶的Go学习资料礼包,包含学习建议:入门看什么,进阶看什么。关注公众号 「polarisxu」,回复 ebook 获取;还可以回复「进群」,和数万 Gopher 交流学习。

浏览 137
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报