入职公司以来,有时间会看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:写磁盘