> For the complete documentation index, see [llms.txt](https://gocompiler.shizhz.me/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://gocompiler.shizhz.me/9.-golang-bian-yi-qi-tao-yi-fen-xi/9.6-bian-yi-ri-zhi.md).

# 9.6 编译日志

与内联一样，我们可以通过编译参数 `-m` 来反馈编译器的逃逸分析结果。将下列代码保存到文件 `main.go` 中：

```go
package main

type T struct {
    Name string
}

func escapeAnalysis(arg T) (*T, bool) {
    l1 := arg
    l1.Name = "Golang"

    l2 := &l1
    l3 := *l2
    return &l3, arg.Name == "Java"
}
```

通过命令 `go tool compile -G=3 -m -json "0,file:///tmp/main.json" main.go` 进行编译，可以看到如下输出：

> ```
> main.go:7:21: leaking param: arg
> main.go:12:2: moved to heap: l3
> ```

可见只有变量 l3 逃逸到了堆上，与上文中我们分析的一致。

文件 `/tmp/main.json` 也会包含相关信息。其中 `-m` 对应的数字越大，日志就越详细，例如我们通过命令 `go tool compile -G=3 -m=2 -json "0,file:///tmp/main.json" main.go` 编译时，得到的结果如下：

> ```
> main.go:12:2: l3 escapes to heap:
> main.go:12:2:   flow: ~r1 = &l3:
> main.go:12:2:     from &l3 (address-of) at main.go:13:9
> main.go:12:2:     from return &l3, arg.Name == string(“Java”) (return) at main.go:13:2
> main.go:7:21: parameter arg leaks to l3 with derefs=0:
> main.go:7:21:   flow: l1 = arg:
> main.go:7:21:     from l1 := arg (assign) at main.go:8:5
> main.go:7:21:   flow: l2 = &l1:
> main.go:7:21:     from &l1 (address-of) at main.go:11:8
> main.go:7:21:     from l2 := &l1 (assign) at main.go:11:5
> main.go:7:21:   flow: l3 = *l2:
> main.go:7:21:     from *l2 (indirection) at main.go:12:8
> main.go:7:21:     from l3 := *l2 (assign) at main.go:12:5
> main.go:7:21: leaking param: arg
> main.go:12:2: moved to heap: l3
> ```

其中 `-m -m` 与 `-m=2` 效果一样，当 `-m=4` 时，日志还会打印出内联前后的 IR Tree 结构，读者可以自己尝试。
