# 5.5 编译日志

如果查看 `irgen.generate()` 的完整代码，可以发现如下代码片段：

```go
if base.Flag.W > 1 {
    for _, n := range g.target.Decls {
        s := fmt.Sprintf("\nafter noder2 %v", n)
        ir.Dump(s, n)
    }
}
```

可见 IR Tree 并没有完全隐藏在编译器内部，而是可以通过编译参数 `-W` 来查看，并且编译器不仅会 dump 出 IR Tree 的结构，还会 dump 出泛型函数实例化时所做的改变。我们通过一个例子来查看一下。

将下列代码保存为 main.go:

```go
package main

import "fmt"

func genericFun[T any](i, j T)  {
    fmt.Printf("i: %v, j: %v\n",i, j)
}

func main() {
    genericFun(5,6)
    genericFun[float32](10.5, 11.8)
}
```

通过命令 `go tool compile -G=2 -W=2 main.go` 进行编译即可看到如下结果：

> ```
> after noder2 genericFun [0xc0001642c0]
> .   DCLFUNC tc(1) Iota:-1 ABI:ABIInternal FUNC-func[T₁](T₁, T₁) # main.go:5
> .   DCLFUNC-Dcl
> .   .   NAME-main.i tc(1) Class:PPARAM Offset:0 OnStack main.T₁ # main.go:5
> .   .   NAME-main.j tc(1) Class:PPARAM Offset:0 OnStack main.T₁ # main.go:5
> .   DCLFUNC-body
> .   .   CALLFUNC tc(1) Use:3 STRUCT-(int, error) # main.go:6 STRUCT-(int, error)
> .   .   .   NAME-fmt.Printf tc(1) Class:PFUNC Offset:0 FUNC-func(string, …interface {}) (int, error) # print.go:212
> .   .   CALLFUNC-Args
> .   .   .   LITERAL-“i: %v, j: %v\n” tc(1) string # main.go:6
> .   .   .   CONVIFACE tc(1) Implicit INTER-interface {} # main.go:6 INTER-interface {}
> .   .   .   .   NAME-main.i tc(1) Class:PPARAM Offset:0 OnStack main.T₁ # main.go:5
> .   .   .   CONVIFACE tc(1) Implicit INTER-interface {} # main.go:6 INTER-interface {}
> .   .   .   .   NAME-main.j tc(1) Class:PPARAM Offset:0 OnStack main.T₁ # main.go:5
>
> after noder2 main [0xc000164580]
> .   DCLFUNC tc(1) Iota:-1 ABI:ABIInternal FUNC-func() # main.go:9
> .   DCLFUNC-body
> .   .   CALL tc(1) Use:3 # main.go:10
> .   .   .   FUNCINST tc(1) FUNC-func[T₁](T₁, T₁) # main.go:10 FUNC-func[T₁](T₁, T₁)
> .   .   .   .   NAME-main.genericFun tc(1) Class:PFUNC Offset:0 FUNC-func[T₁](T₁, T₁) # main.go:5
> .   .   .   FUNCINST-Targs
> .   .   .   .   TYPE .int Offset:0 type int
> .   .   CALL-Args
> .   .   .   LITERAL-5 tc(1) int # main.go:10
> .   .   .   LITERAL-6 tc(1) int # main.go:10
> .   .   CALL tc(1) Use:3 # main.go:11
> .   .   .   FUNCINST tc(1) FUNC-func[T₁](T₁, T₁) # main.go:11 FUNC-func[T₁](T₁, T₁)
> .   .   .   .   NAME-main.genericFun tc(1) Class:PFUNC Offset:0 FUNC-func[T₁](T₁, T₁) # main.go:5
> .   .   .   FUNCINST-Targs
> .   .   .   .   TYPE .float32 Offset:0 type float32
> .   .   CALL-Args
> .   .   .   LITERAL-10.5 tc(1) float32 # main.go:11
> .   .   .   LITERAL-11.8 tc(1) float32 # main.go:11
>
> stenciled genericFun[int] [0xc0001646e0]
> .   DCLFUNC tc(1) Iota:-1 ABI:ABIInternal FUNC-func(int, int) # main.go:5
> .   DCLFUNC-Dcl
> .   .   NAME-main.i tc(1) Class:PPARAM Offset:0 OnStack int # main.go:5
> .   .   NAME-main.j tc(1) Class:PPARAM Offset:0 OnStack int # main.go:5
> .   DCLFUNC-body
> .   .   CALLFUNC tc(1) Use:3 STRUCT-(int, error) # main.go:6 STRUCT-(int, error)
> .   .   .   NAME-fmt.Printf tc(1) Class:PFUNC Offset:0 FUNC-func(string, …interface {}) (int, error) # print.go:212
> .   .   CALLFUNC-Args
> .   .   .   LITERAL-“i: %v, j: %v\n” tc(1) string # main.go:6
> .   .   .   CONVIFACE tc(1) Implicit INTER-interface {} # main.go:6 INTER-interface {}
> .   .   .   .   NAME-main.i tc(1) Class:PPARAM Offset:0 OnStack int # main.go:5
> .   .   .   CONVIFACE tc(1) Implicit INTER-interface {} # main.go:6 INTER-interface {}
> .   .   .   .   NAME-main.j tc(1) Class:PPARAM Offset:0 OnStack int # main.go:5
>
> stenciled genericFun[float32] [0xc000164840]
> .   DCLFUNC tc(1) Iota:-1 ABI:ABIInternal FUNC-func(float32, float32) # main.go:5
> .   DCLFUNC-Dcl
> .   .   NAME-main.i tc(1) Class:PPARAM Offset:0 OnStack float32 # main.go:5
> .   .   NAME-main.j tc(1) Class:PPARAM Offset:0 OnStack float32 # main.go:5
> .   DCLFUNC-body
> .   .   CALLFUNC tc(1) Use:3 STRUCT-(int, error) # main.go:6 STRUCT-(int, error)
> .   .   .   NAME-fmt.Printf tc(1) Class:PFUNC Offset:0 FUNC-func(string, …interface {}) (int, error) # print.go:212
> .   .   CALLFUNC-Args
> .   .   .   LITERAL-“i: %v, j: %v\n” tc(1) string # main.go:6
> .   .   .   CONVIFACE tc(1) Implicit INTER-interface {} # main.go:6 INTER-interface {}
> .   .   .   .   NAME-main.i tc(1) Class:PPARAM Offset:0 OnStack float32 # main.go:5
> .   .   .   CONVIFACE tc(1) Implicit INTER-interface {} # main.go:6 INTER-interface {}
> .   .   .   .   NAME-main.j tc(1) Class:PPARAM Offset:0 OnStack float32 # main.go:5
>
> modified main [0xc000164580]
> .   DCLFUNC tc(1) Iota:-1 ABI:ABIInternal FUNC-func() # main.go:9
> .   DCLFUNC-body
> .   .   CALLFUNC tc(1) Use:3 # main.go:10
> .   .   .   NAME-main.genericFun[int] tc(1) Class:PFUNC Offset:0 FUNC-func(int, int) # main.go:5
> .   .   CALLFUNC-Args
> .   .   .   LITERAL-5 tc(1) int # main.go:10
> .   .   .   LITERAL-6 tc(1) int # main.go:10
> .   .   CALLFUNC tc(1) Use:3 # main.go:11
> .   .   .   NAME-main.genericFun[float32] tc(1) Class:PFUNC Offset:0 FUNC-func(float32, float32) # main.go:5
> .   .   CALLFUNC-Args
> .   .   .   LITERAL-10.5 tc(1) float32 # main.go:11
> .   .   .   LITERAL-11.8 tc(1) float32 # main.go:11
> ```

前两个以 `after noder2` 开头的结构分别对应两个函数申明，这是 Step 3 完成之后 IR Tree 的总体结构，可以看到其中还包括泛型信息；而随后的信息是泛型函数实例化的 dump 信息，以 `stenciled` 开头的两个函数 `genericFun[int]` 与 `genericFun[float32]` 便是生成的实例化函数，最后 `modified main` 是修改之后的 main 函数，可以发现此时 main 函数内部直接调用的是实例化函数，已经抹掉了有关泛型的所有信息。

编译参数加上 `-G=2` 是为了启用泛型支持以便调用新的类型检查逻辑，并且在创建 IR Tree 完成之后退出编译，否则会 dump 出非常多的信息。可以在 `irgen.go` 的函数 `check2()` 中查看该 flag 的使用方式。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://gocompiler.shizhz.me/golang-bian-yi-qi-ir-tree/5.5-bian-yi-ri-zhi.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
