入职公司以来,有时间会看Golang编译相关的源码,一方面是为了学习使用Golang,另一方面也为了了解Golang编译相关的原理。
Golang编译源码在src/cmd/compile目录。按src/cmd/compile/README.md中指出的,编译分为四步:解析,AST转换与类型检查,生成SSA与优化,生成机器码。目前主要看了解析,AST,类型检查等,粗略阅读了SSA,机器码代码。越往后读花的时间越多,不了解的知识越来越多。
编译器的main文件是compile/main,然后执行compile/gc/main:Main函数,主要分为以下几个步骤:
0: 解析源码
调用gc/noder.go:parseFiles函数解析源码,所有源码解析后放到xtop中。xtop是一个slice,保存所有AST。
1: 常量,类型,函数签名的类型检查
此步骤调用gc/typecheck.go:typecheck函数。
2: 变量定义及赋值的类型检查
同样调用gc/typecheck.go:typecheck函数
3: 函数体的类型检查
调用gc/typecheck.go:typecheckslice函数检查函数(包括闭包)体
4: 捕获变量
调用gc/closure.go:capturevars
5: 内联
这一步没有细看
6: 逃逸分析
调用gc/esc.go:escapes分析。这里涉及到了强连通分量
7:转换闭包
没细看
8:编译顶层函数
调用gc/pgen.go:funccompile
9:检查外部声明
10:写磁盘