Open qiulaidongfeng opened 1 month ago
Related Issues and Documentation
(Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.)
Are these benchmarks of the compiler itself? (I'm not sure, but the names look suggestive.) If so, it is expected that pgo compiles will take a little bit longer.
Are these benchmarks of the compiler itself? (I'm not sure, but the names look suggestive.) If so, it is expected that pgo compiles will take a little bit longer.
These benckmark come from open source code that I wrote while researching compilation principles, it doesn't call go build.
I started using pgo in this open source code more than a year ago, default.pgo comes from running all benchmarks ,because it conforms to the https://go.dev/doc/pgo it is important that profiles are representative of actual behavior in the application’s production environment
.
pgo usually brings some performance improvement. But yesterday, I tried to update default.pgo to test how much optimization pgo produces for new code, and I noticed that some of the benchmarks showed a stable decline in performance after using pgo, with the benchmark showing a stable increase in execution time of more than 10%. I see https://go.dev/doc/pgo If you encounter a program where PGO results in worse performance than disabling PGO, please file an issue at https://go.dev/issue/new.
I tried go1.21.7, and pgo gave me a performance boost of less than 5%. I tried go1.22.2, and pgo caused some benchmarks to increase execution time by more than 10%.
git bisect to b56645a87b28840a180d64077877cb46570b4176
@prattmic
Does https://github.com/golang/go/commit/b56645a87b28840a180d64077877cb46570b4176 on its own cause regressions for these benchmarks (without PGO)?
We could set up bisection of the specific optimizations, but we'd need to modify the compiler (I did this once before). Before that, it may help to look at the logs of go build -gcflags=all=-d=pgodebug=1
. Messages with "hot-budget" indicate which functions are PGO-inlined. You may find some important ones newly missing after https://github.com/golang/go/commit/b56645a87b28840a180d64077877cb46570b4176.
Before that, it may help to look at the logs of go build -gcflags=all=-d=pgodebug=1. Messages with "hot-budget" indicate which functions are PGO-inlined. You may find some important ones newly missing after https://github.com/golang/go/commit/b56645a87b28840a180d64077877cb46570b4176.
I tried , but the two outputs differ by tens of kilobytes,it is difficult to see directly what has changed. b56645a87b28840a180d64077877cb46570b4176.txt
Thanks. If you sort the files first, then diff works pretty well, though there are quite a few changes.
Almost all of the changes are reductions in inline cost, which results in more inlines. This is expected behavior of https://github.com/golang/go/commit/b56645a87b28840a180d64077877cb46570b4176, so it doesn't look like something is fundamentally broken.
Bisecting the optimization decisions is a good next step. I'll put together a CL for that when I get a chance.
In the meantime, I'm curious how "diverse" the regressed benchmarks are. For example, if you look at a CPU profile of just ComplierToCBuildMode2/使用选择器取地址与解引用
is most CPU time spent spent in a single function, or is it spread across lots of functions in the program? (We can get a sense of this by taking a high-level look at a profile's flame graph).
Does https://github.com/golang/go/commit/b56645a87b28840a180d64077877cb46570b4176 on its own cause regressions for these benchmarks (without PGO)?
I tried, result discover no performance degradation without pgo.
│ old.txt │ new.txt │ │ sec/op │ sec/op vs base │ ComplierToCBuildMode2/输出456-16 4.788µ ± 1% 4.755µ ± 1% ~ (p=0.078 n=10) ComplierToCBuildMode2/for加1,1万次,输出10000-16 4.225µ ± 2% 4.196µ ± 1% ~ (p=0.138 n=10) ComplierToCBuildMode2/for代码块和main代码块都有变量i,输出10000-16 4.830µ ± 1% 4.838µ ± 1% ~ (p=0.754 n=10) ComplierToCBuildMode2/输出1-10000中偶数的数量,比较"s"=="a"输出false-16 6.735µ ± 2% 6.719µ ± 2% ~ (p=0.315 n=10) ComplierToCBuildMode2/使用指针循环加一个int变量自增10000次-16 4.294µ ± 2% 4.283µ ± 2% ~ (p=0.956 n=10) ComplierToCBuildMode2/输出结构体字段,结果字符串11-16 4.774µ ± 2% 4.749µ ± 1% ~ (p=0.093 n=10) ComplierToCBuildMode2/整数和浮点数互相转换-16 2.947µ ± 1% 2.940µ ± 1% ~ (p=0.699 n=10) ComplierToCBuildMode2/调用malloc和free-16 22.83µ ± 0% 22.85µ ± 1% ~ (p=0.631 n=10) ComplierToCBuildMode2/使用自操作语句-16 6.516µ ± 2% 6.599µ ± 2% ~ (p=0.218 n=10) ComplierToCBuildMode2/使用nil-16 5.873µ ± 4% 5.826µ ± 1% ~ (p=0.159 n=10) ComplierToCBuildMode2/使用选择器取地址与解引用-16 24.82µ ± 1% 24.58µ ± 1% -0.96% (p=0.009 n=10) ComplierToCBuildMode2/使用init函数-16 25.19µ ± 1% 25.15µ ± 0% ~ (p=0.315 n=10) ComplierToCBuildMode2/switch-16 7.834µ ± 2% 7.820µ ± 1% ~ (p=0.481 n=10) ComplierToCBuildMode2/位与,位或,异或,逻辑运算,括号表达式-16 7.167µ ± 1% 7.212µ ± 1% ~ (p=0.393 n=10) ComplierToCBuildMode2/数组类型与索引表达式-16 6.737µ ± 2% 6.683µ ± 1% ~ (p=0.247 n=10) ComplierToCBuildMode2/goto语句-16 2.135µ ± 2% 2.122µ ± 1% ~ (p=0.382 n=10) geomean 6.725µ 6.709µ -0.25%
I wrote an open source tool(https://github.com/qiulaidongfeng/diffbench) to analyze pgo debug information, I got:
// old inline , but new not inline hot-budget check allows inlining for call gitee.com/u-language/u-language/ucom/ast2.(*VarNode).C (cost 1217) at gitee.com/u-language/u-language/ucom/cast2/utoc.go:82:13 in function gitee.com/u-language/u-language/ucom/cast2.generateCFile hot-budget check allows inlining for call gitee.com/u-language/u-language/ucom/ast.ParserVAR (cost 727) at gitee.com/u-language/u-language/ucom/ast/Parser.go:66:20 in function gitee.com/u-language/u-language/ucom/ast.ParserNode hot-budget check allows inlining for call gitee.com/u-language/u-language/ucom/ast.parserSece (cost 1652) at gitee.com/u-language/u-language/ucom/ast/Parser.go:78:29 in function gitee.com/u-language/u-language/ucom/ast.ParserNode hot-budget check allows inlining for call reflect.convertOp (cost 1568) at reflect/value.go:3322:17 in function reflect.Value.Convert hot-budget check allows inlining for call gitee.com/u-language/u-language/ucom/ast.(*Sbt).addFunc (cost 872) at gitee.com/u-language/u-language/ucom/ast/sbt.go:199:18 in function gitee.com/u-language/u-language/ucom/ast.(*Sbt).AddFunc hot-budget check allows inlining for call runtime.(*mcache).refill (cost 1746) at runtime/malloc.go:923:11 in function runtime.(*mcache).nextFree ---------------- // new inline , but old not inline hot-budget check allows inlining for call gitee.com/u-language/u-language/ucom/ast2.(*Tree).parserType2 (cost 540) at gitee.com/u-language/u-language/ucom/ast2/parser.go:220:22 in function gitee.com/u-language/u-language/ucom/ast2.(*Tree).parserType hot-budget check allows inlining for call runtime.(*mcentral).cacheSpan (cost 1698) at runtime/mcache.go:182:44 in function runtime.(*mcache).refill hot-budget check allows inlining for call gitee.com/u-language/u-language/ucom/check.check_selector (cost 1871) at gitee.com/u-language/u-language/ucom/check/ret.go:88:57 in function gitee.com/u-language/u-language/ucom/check.ret_info hot-budget check allows inlining for call github.com/huandu/go-clone.(*cloneState).clonePtr (cost 1426) at github.com/huandu/go-clone@v1.7.2/clone.go:106:24 in function github.com/huandu/go-clone.(*cloneState).clone hot-budget check allows inlining for call runtime.gcDrainMarkWorkerIdle (cost 962) at runtime/mgc.go:1395:26 in function runtime.gcBgMarkWorker.func2 hot-budget check allows inlining for call gitee.com/u-language/u-language/ucom/cast.generateInit (cost 1710) at gitee.com/u-language/u-language/ucom/cast/ast.go:144:22 in function gitee.com/u-language/u-language/ucom/cast.(*UtoC).C hot-budget check allows inlining for call gitee.com/u-language/u-language/ucom/ast2.(*Tree).parserGoto (cost 216) at gitee.com/u-language/u-language/ucom/ast2/parser.go:124:15 in function gitee.com/u-language/u-language/ucom/ast2.(*Tree).parser hot-budget check allows inlining for call gitee.com/u-language/u-language/ucom/check3.checkCall (cost 1113) at gitee.com/u-language/u-language/ucom/check3/check3.go:45:39 in function gitee.com/u-language/u-language/ucom/check3.checkNode hot-budget check allows inlining for call reflect.implements (cost 1846) at reflect/value.go:3552:15 in function reflect.convertOp hot-budget check allows inlining for call runtime.markrootSpans (cost 652) at runtime/mgcmark.go:193:16 in function runtime.markroot hot-budget check allows inlining for call runtime.scanframeworker (cost 1587) at runtime/mgcmark.go:803:18 in function runtime.scanstack hot-budget check allows inlining for call github.com/huandu/go-clone.(*cloneState).cloneSlice (cost 1419) at github.com/huandu/go-clone@v1.7.2/clone.go:108:26 in function github.com/huandu/go-clone.(*cloneState).clone hot-budget check allows inlining for call gitee.com/u-language/u-language/ucom/ast.(*Sbt).AddMethod (cost 468) at gitee.com/u-language/u-language/ucom/ast/Parser.go:1237:25 in function gitee.com/u-language/u-language/ucom/ast.parserMethod hot-budget check allows inlining for call gitee.com/u-language/u-language/ucom/ast2.(*Tree).parserObject3 (cost 324) at gitee.com/u-language/u-language/ucom/ast2/parser.go:501:25 in function gitee.com/u-language/u-language/ucom/ast2.(*Tree).parserSelect2 hot-budget check allows inlining for call reflect.haveIdenticalUnderlyingType (cost 1974) at reflect/value.go:3541:32 in function reflect.convertOp hot-budget check allows inlining for call github.com/huandu/go-clone.(*cloneState).cloneInterface (cost 1607) at github.com/huandu/go-clone@v1.7.2/clone.go:102:30 in function github.com/huandu/go-clone.(*cloneState).clone hot-budget check allows inlining for call runtime.procresize (cost 1620) at runtime/proc.go:1452:18 in function runtime.startTheWorldWithSema hot-budget check allows inlining for call runtime.(*pageAlloc).allocRange (cost 1012) at runtime/mpagealloc.go:914:21 in function runtime.(*pageAlloc).alloc hot-budget check allows inlining for call gitee.com/u-language/u-language/ucom/ast.parserASSIGN (cost 1865) at gitee.com/u-language/u-language/ucom/ast/Parser.go:250:25 in function gitee.com/u-language/u-language/ucom/ast.ParserVAR hot-budget check allows inlining for call runtime.finishsweep_m (cost 1312) at runtime/mgc.go:684:16 in function runtime.gcStart.func2 hot-budget check allows inlining for call gitee.com/u-language/u-language/ucom/ast2.(*Tree).findElse (cost 533) at gitee.com/u-language/u-language/ucom/ast2/parser.go:557:19 in function gitee.com/u-language/u-language/ucom/ast2.(*Tree).parserIf hot-budget check allows inlining for call runtime.gcDrain (cost 958) at runtime/mgcmark.go:1017:9 in function runtime.gcDrainMarkWorkerIdle hot-budget check allows inlining for call gitee.com/u-language/u-language/ucom/check3.predefined_func (cost 568) at gitee.com/u-language/u-language/ucom/check3/check3.go:214:31 in function gitee.com/u-language/u-language/ucom/check3.checkCall hot-budget check allows inlining for call gitee.com/u-language/u-language/ucom/ast.parserASSIGN (cost 1865) at gitee.com/u-language/u-language/ucom/ast/Parser.go:478:22 in function gitee.com/u-language/u-language/ucom/ast.parserSece hot-budget check allows inlining for call github.com/huandu/go-clone.(*cloneState).copyStruct (cost 1558) at github.com/huandu/go-clone@v1.7.2/clone.go:230:19 in function github.com/huandu/go-clone.(*cloneState).clonePtr hot-budget check allows inlining for call runtime.gcDrain (cost 958) at runtime/mgcmark.go:1027:9 in function runtime.gcDrainMarkWorkerDedicated hot-budget check allows inlining for call gitee.com/u-language/u-language/ucom/cast2.generateInit (cost 1817) at gitee.com/u-language/u-language/ucom/cast2/utoc.go:35:22 in function gitee.com/u-language/u-language/ucom/cast2.(*UtoC).C hot-budget check allows inlining for call runtime.suspendG (cost 1157) at runtime/mgcmark.go:232:23 in function runtime.markroot.func1 hot-budget check allows inlining for call gitee.com/u-language/u-language/ucom/ast2.(*Tree).parserIndexExprOrGenericInstantiation (cost 890) at gitee.com/u-language/u-language/ucom/ast2/expr3.go:303:55 in function gitee.com/u-language/u-language/ucom/ast2.(*stack).AutoPush hot-budget check allows inlining for call runtime.gcDrainN (cost 1293) at runtime/mgcmark.go:568:22 in function runtime.gcAssistAlloc1 hot-budget check allows inlining for call runtime.newproc1 (cost 1681) at runtime/proc.go:4492:19 in function runtime.newproc.func1 hot-budget check allows inlining for call gitee.com/u-language/u-language/ucom/cast.(*Package).GenerateheaderFile (cost 947) at gitee.com/u-language/u-language/ucom/cast/package.go:188:36 in function gitee.com/u-language/u-language/ucom/cast.(*Package).C hot-budget check allows inlining for call runtime.(*pageAlloc).free (cost 1767) at runtime/mheap.go:1640:14 in function runtime.(*mheap).freeSpanLocked
I studied the code paths that were affected,in hot path https://gitee.com/u-language/u-language/blob/pgo2024-8-9/ucom/check3/check3.go#L231, there executed through multiple function calls, execute to errcode.NewMsgUnknownSymbol in https://gitee.com/u-language/u-language/blob/pgo2024-8-9/ucom/check3/check3.go#L127, remove https://gitee.com/u-language/u-language/blob/pgo2024-8-9/ucom/errcode/msg.go#L149-L151 of errcode.NewMsgUnknownSymbol ,no significant performance degradation with pgo.
I don't know why having these three lines of code would cause performance to drop when using pgo.
if Debug {
msg.stack = debug.Stack()
}
Interesting. My best guess is that the additional PGO inlines made a caller of NewMsgUnknownSymbol too expensive to inline into. The "hot-budget" logs only inlines explicitly allowed by PGO. There could be some downstream effects on non-PGO inlines [1].
-m
will show standard inlines as well. Use as go build "-gcflags=all=-d=pgodebug=1 -m"
. Perhaps you could update that nice diff tool to compare the "inlining call to ..." lines.
As for why inling NewMsgUnknownSymbol would matter, my best guess would be that some hot callsite manages to keep the name string on the stack if the call is inlined.
Also, for what it's worth, I don't see any obvious code changing errcode.Debug
. If you can make it a const, this problem will likely go away as that conditional code will disappear.
[1] For example, we won't inline into a function that is very large. And inlines into a function may make it large.
-m will show standard inlines as well. Use as go build "-gcflags=all=-d=pgodebug=1 -m". Perhaps you could update that nice diff tool to compare the "inlining call to ..." lines.
I updated diff tool support inline and escape analysis information. I got:
// old inline , but new not inline:1: inlining call to srcFunc.name gitee.com/u-language/u-language/ucom/ast/Parser.go:66:20: ... argument does not escape gitee.com/u-language/u-language/ucom/ast/Parser.go:66:20: inlining call to (*Tree).Panic gitee.com/u-language/u-language/ucom/ast/Parser.go:66:20: inlining call to ParserVAR gitee.com/u-language/u-language/ucom/ast/Parser.go:66:20: inlining call to check_is_type_token gitee.com/u-language/u-language/ucom/ast/Parser.go:66:20: inlining call to lex.NewLine gitee.com/u-language/u-language/ucom/ast/Parser.go:78:29: &SelfOpStmt{...} escapes to heap gitee.com/u-language/u-language/ucom/ast/Parser.go:78:29: ... argument does not escape gitee.com/u-language/u-language/ucom/ast/Parser.go:78:29: inlining call to (*Tree).Panic gitee.com/u-language/u-language/ucom/ast/Parser.go:78:29: inlining call to NewSelfOpStmt gitee.com/u-language/u-language/ucom/ast/Parser.go:78:29: inlining call to parserSece golang.org/x/sys@v0.15.0/windows/setupapi_windows.go:1145:25: UTF16ToString(ret[:n]) escapes to heap hot-budget check allows inlining for call gitee.com/u-language/u-language/ucom/ast.(*Sbt).addFunc (cost 872) at gitee.com/u-language/u-language/ucom/ast/sbt.go:199:18 in function gitee.com/u-language/u-language/ucom/ast.(*Sbt).AddFunc hot-budget check allows inlining for call gitee.com/u-language/u-language/ucom/ast.ParserVAR (cost 727) at gitee.com/u-language/u-language/ucom/ast/Parser.go:66:20 in function gitee.com/u-language/u-language/ucom/ast.ParserNode hot-budget check allows inlining for call gitee.com/u-language/u-language/ucom/ast.parserSece (cost 1652) at gitee.com/u-language/u-language/ucom/ast/Parser.go:78:29 in function gitee.com/u-language/u-language/ucom/ast.ParserNode hot-budget check allows inlining for call reflect.convertOp (cost 1568) at reflect/value.go:3322:17 in function reflect.Value.Convert hot-budget check allows inlining for call runtime.(*mcache).refill (cost 1746) at runtime/malloc.go:923:11 in function runtime.(*mcache).nextFree reflect/value.go:3322:17: inlining call to abi.(*Type).Elem reflect/value.go:3322:17: inlining call to abi.(*Type).Kind reflect/value.go:3322:17: inlining call to convertOp reflect/value.go:3322:17: inlining call to nameFor reflect/value.go:3322:17: inlining call to pkgPathFor reflect/value.go:3322:17: inlining call to toRType runtime/debugcall.go:55:19: inlining call to funcInfo.valid runtime/debugcall.go:55:19: inlining call to funcname runtime/debuglog.go:826:19: inlining call to funcInfo.valid runtime/debuglog.go:826:19: inlining call to funcname runtime/error.go:307:35: inlining call to funcInfo.valid runtime/error.go:307:35: inlining call to funcname runtime/heapdump.go:288:18: inlining call to funcInfo.valid runtime/heapdump.go:288:18: inlining call to funcname runtime/heapdump.go:634:20: inlining call to funcInfo.valid runtime/heapdump.go:634:20: inlining call to funcname runtime/malloc.go:923:11: inlining call to (*mcache).refill runtime/malloc.go:923:11: inlining call to atomic.(*Uint64).Add runtime/malloc.go:923:11: inlining call to spanClass.sizeclass runtime/mgc.go:1376:31: inlining call to gcDrainMarkWorkerDedicated runtime/mgc.go:1391:31: inlining call to gcDrainMarkWorkerDedicated runtime/mgcmark.go:802:38: inlining call to funcname runtime/os_windows.go:1329:35: inlining call to srcFunc.name runtime/panic.go:56:45: inlining call to funcInfo.valid runtime/panic.go:56:45: inlining call to funcname runtime/plugin.go:105:19: inlining call to funcInfo.valid runtime/plugin.go:105:19: inlining call to funcname runtime/plugin.go:114:20: inlining call to funcInfo.valid runtime/plugin.go:114:20: inlining call to funcname runtime/preempt.go:418:28: inlining call to srcFunc.name runtime/print.go:295:23: inlining call to funcInfo.valid runtime/print.go:295:23: inlining call to funcname runtime/proc.go:3824:60: inlining call to funcInfo.valid runtime/proc.go:3824:60: inlining call to funcname runtime/stack.go:625:53: inlining call to funcInfo.valid runtime/stack.go:625:53: inlining call to funcname runtime/stack.go:930:38: inlining call to funcname runtime/stack.go:985:21: inlining call to funcInfo.valid runtime/stack.go:985:21: inlining call to funcname runtime/stkframe.go:101:17: inlining call to funcInfo.valid runtime/stkframe.go:101:17: inlining call to funcname runtime/stkframe.go:127:44: inlining call to funcInfo.valid runtime/stkframe.go:127:44: inlining call to funcname runtime/stkframe.go:139:43: inlining call to funcInfo.valid runtime/stkframe.go:139:43: inlining call to funcname runtime/stkframe.go:194:37: inlining call to funcInfo.valid runtime/stkframe.go:194:37: inlining call to funcname runtime/stkframe.go:201:104: inlining call to funcInfo.valid runtime/stkframe.go:201:104: inlining call to funcname runtime/stkframe.go:221:37: inlining call to funcInfo.valid runtime/stkframe.go:221:37: inlining call to funcname runtime/stkframe.go:226:102: inlining call to funcInfo.valid runtime/stkframe.go:226:102: inlining call to funcname runtime/symtab.go:1017:22: inlining call to funcname runtime/symtab.go:1018:19: inlining call to funcname runtime/symtab.go:1032:17: inlining call to funcname runtime/symtab.go:1067:17: inlining call to funcname runtime/symtab.go:1075:17: inlining call to funcname runtime/symtab.go:132:39: inlining call to srcFunc.name runtime/symtab.go:185:16: inlining call to srcFunc.name runtime/symtab.go:544:22: inlining call to funcInfo.valid runtime/symtab.go:544:22: inlining call to funcname runtime/symtab.go:546:99: inlining call to funcInfo.valid runtime/symtab.go:546:99: inlining call to funcname runtime/symtab.go:548:56: inlining call to funcInfo.valid runtime/symtab.go:548:56: inlining call to funcname runtime/symtab.go:669:21: inlining call to srcFunc.name runtime/symtab.go:687:34: inlining call to funcInfo.valid runtime/symtab.go:687:34: inlining call to funcname runtime/symtab.go:958:56: inlining call to funcInfo.valid runtime/symtab.go:958:56: inlining call to funcname runtime/symtab.go:984:35: inlining call to funcInfo.valid runtime/symtab.go:984:35: inlining call to funcname runtime/traceback.go:1001:19: inlining call to srcFunc.name runtime/traceback.go:1090:34: inlining call to srcFunc.name runtime/traceback.go:1141:17: inlining call to srcFunc.name runtime/traceback.go:1330:27: inlining call to funcInfo.valid runtime/traceback.go:1330:27: inlining call to funcname runtime/traceback.go:223:19: inlining call to funcInfo.valid runtime/traceback.go:223:19: inlining call to funcname runtime/traceback.go:364:62: inlining call to funcInfo.valid runtime/traceback.go:364:62: inlining call to funcname runtime/traceback.go:468:73: inlining call to funcInfo.valid runtime/traceback.go:468:73: inlining call to funcname runtime/traceback.go:515:19: inlining call to funcInfo.valid runtime/traceback.go:515:19: inlining call to funcname runtime/traceback.go:625:43: inlining call to funcname runtime/traceback.go:802:24: inlining call to funcInfo.valid runtime/traceback.go:802:24: inlining call to funcname ---------------- // new inline , but old not inline :1: inlining call to (*moduledata).funcName :1: inlining call to (*mspan).newPinnerBits :1: inlining call to Float64Slice.Sort :1: inlining call to IntSlice.Sort :1: inlining call to StringSlice.Sort :1: x escapes to heap encoding/binary/binary.go:455:23: inlining call to reflect.Indirect encoding/binary/binary.go:455:23: inlining call to reflect.Value.Kind encoding/binary/binary.go:455:23: inlining call to reflect.flag.kind encoding/binary/binary.go:471:34: inlining call to reflect.Indirect encoding/binary/binary.go:471:34: inlining call to reflect.Value.Kind encoding/binary/binary.go:471:34: inlining call to reflect.flag.kind gitee.com/u-language/u-language/ucom/ast/Parser.go:1237:25: Type + "method" escapes to heap gitee.com/u-language/u-language/ucom/ast/Parser.go:1237:25: inlining call to (*Sbt).AddMethod gitee.com/u-language/u-language/ucom/ast/Parser.go:1237:25: inlining call to NewMethodTableInfo gitee.com/u-language/u-language/ucom/ast/Parser.go:1237:25: inlining call to NewSbt gitee.com/u-language/u-language/ucom/ast/Parser.go:1237:25: make(map[string]SymbolInfo) escapes to heap gitee.com/u-language/u-language/ucom/ast/Parser.go:1237:25: new(Sbt) escapes to heap gitee.com/u-language/u-language/ucom/ast/Parser.go:1237:25: new(sync.Map) escapes to heap gitee.com/u-language/u-language/ucom/ast/Parser.go:1331:21: inlining call to (*Sbt).AddEnum gitee.com/u-language/u-language/ucom/ast/Parser.go:192:21: inlining call to (*Sbt).AddEnum gitee.com/u-language/u-language/ucom/ast/Parser.go:250:25: &AssignmentNode{...} escapes to heap gitee.com/u-language/u-language/ucom/ast/Parser.go:250:25: inlining call to NewASSIGNNode gitee.com/u-language/u-language/ucom/ast/Parser.go:250:25: inlining call to parserASSIGN gitee.com/u-language/u-language/ucom/ast/Parser.go:324:21: inlining call to (*Sbt).AddConst gitee.com/u-language/u-language/ucom/ast/Parser.go:454:23: inlining call to (*Sbt).addFunc gitee.com/u-language/u-language/ucom/ast/Parser.go:478:22: &AssignmentNode{...} escapes to heap gitee.com/u-language/u-language/ucom/ast/Parser.go:478:22: inlining call to NewASSIGNNode gitee.com/u-language/u-language/ucom/ast/Parser.go:478:22: inlining call to parserASSIGN gitee.com/u-language/u-language/ucom/ast/check.go:223:17: inlining call to utils.PutMapSet gitee.com/u-language/u-language/ucom/ast2/expr3.go:303:55: "exit" escapes to heap gitee.com/u-language/u-language/ucom/ast2/expr3.go:303:55: &IndexExpr{...} escapes to heap gitee.com/u-language/u-language/ucom/ast2/expr3.go:303:55: ... argument does not escape gitee.com/u-language/u-language/ucom/ast2/expr3.go:303:55: inlining call to (*Tree).panic gitee.com/u-language/u-language/ucom/ast2/expr3.go:303:55: inlining call to (*Tree).parserIndexExprOrGenericInstantiation gitee.com/u-language/u-language/ucom/ast2/expr3.go:303:55: inlining call to NewIndexExpr gitee.com/u-language/u-language/ucom/ast2/parser.go:124:15: "exit" escapes to heap gitee.com/u-language/u-language/ucom/ast2/parser.go:124:15: &GotoStmt{} escapes to heap gitee.com/u-language/u-language/ucom/ast2/parser.go:124:15: ... argument does not escape gitee.com/u-language/u-language/ucom/ast2/parser.go:124:15: inlining call to (*Tree).lex2TokenToStr gitee.com/u-language/u-language/ucom/ast2/parser.go:124:15: inlining call to (*Tree).panic gitee.com/u-language/u-language/ucom/ast2/parser.go:124:15: inlining call to (*Tree).parserGoto gitee.com/u-language/u-language/ucom/ast2/parser.go:124:15: inlining call to (*Tree).subline gitee.com/u-language/u-language/ucom/ast2/parser.go:124:15: inlining call to NewGotoStmt gitee.com/u-language/u-language/ucom/ast2/parser.go:124:15: inlining call to errcode.NewMsgUnexpected gitee.com/u-language/u-language/ucom/ast2/parser.go:124:15: ~r0 escapes to heap gitee.com/u-language/u-language/ucom/ast2/parser.go:220:22: ... argument does not escape gitee.com/u-language/u-language/ucom/ast2/parser.go:220:22: inlining call to (*Tree).parserType2 gitee.com/u-language/u-language/ucom/ast2/parser.go:501:25: ... argument does not escape gitee.com/u-language/u-language/ucom/ast2/parser.go:501:25: inlining call to (*Tree).parserObject3 gitee.com/u-language/u-language/ucom/ast2/parser.go:557:19: inlining call to (*Tree).findElse gitee.com/u-language/u-language/ucom/ast2/parser.go:557:19: inlining call to NewRbraceNode gitee.com/u-language/u-language/ucom/ast2/parser.go:557:19: ~r0 escapes to heap gitee.com/u-language/u-language/ucom/cast/ast.go:144:22: "strings: illegal use of non-zero Builder copied by value" escapes to heap gitee.com/u-language/u-language/ucom/cast/ast.go:144:22: &ast.FuncInfo{} does not escape gitee.com/u-language/u-language/ucom/cast/ast.go:144:22: inlining call to generateInit gitee.com/u-language/u-language/ucom/cast/ast.go:144:22: inlining call to strings.(*Builder).String gitee.com/u-language/u-language/ucom/cast/ast.go:144:22: inlining call to strings.(*Builder).WriteString gitee.com/u-language/u-language/ucom/cast/ast.go:144:22: inlining call to strings.(*Builder).copyCheck gitee.com/u-language/u-language/ucom/cast/ast.go:144:22: inlining call to strings.noescape gitee.com/u-language/u-language/ucom/cast/ast.go:144:22: inlining call to strings.noescape gitee.com/u-language/u-language/ucom/cast/ir2.go:155:7: inlining call to ast.(*MethodNode).C gitee.com/u-language/u-language/ucom/cast/package.go:188:36: "strings: illegal use of non-zero Builder copied by value" escapes to heap gitee.com/u-language/u-language/ucom/cast/package.go:188:36: func literal does not escape gitee.com/u-language/u-language/ucom/cast/package.go:188:36: inlining call to (*Package).GenerateheaderFile gitee.com/u-language/u-language/ucom/cast/package.go:188:36: inlining call to (*Package).WithAutoFree gitee.com/u-language/u-language/ucom/cast/package.go:188:36: inlining call to strings.(*Builder).String gitee.com/u-language/u-language/ucom/cast/package.go:188:36: inlining call to strings.(*Builder).WriteString gitee.com/u-language/u-language/ucom/cast/package.go:188:36: inlining call to strings.(*Builder).copyCheck gitee.com/u-language/u-language/ucom/cast/package.go:188:36: inlining call to strings.noescape gitee.com/u-language/u-language/ucom/cast/package.go:188:36: inlining call to strings.noescape gitee.com/u-language/u-language/ucom/cast/package.go:188:36: p.headerFile.Data escapes to heap gitee.com/u-language/u-language/ucom/cast2/utoc.go:35:22: "strings: illegal use of non-zero Builder copied by value" escapes to heap gitee.com/u-language/u-language/ucom/cast2/utoc.go:35:22: &ast2.FuncInfo{} does not escape gitee.com/u-language/u-language/ucom/cast2/utoc.go:35:22: inlining call to generateInit gitee.com/u-language/u-language/ucom/cast2/utoc.go:35:22: inlining call to strings.(*Builder).String gitee.com/u-language/u-language/ucom/cast2/utoc.go:35:22: inlining call to strings.(*Builder).WriteString gitee.com/u-language/u-language/ucom/cast2/utoc.go:35:22: inlining call to strings.(*Builder).copyCheck gitee.com/u-language/u-language/ucom/cast2/utoc.go:35:22: inlining call to strings.noescape gitee.com/u-language/u-language/ucom/cast2/utoc.go:35:22: inlining call to strings.noescape gitee.com/u-language/u-language/ucom/cast2/utoc.go:82:13: "strings: illegal use of non-zero Builder copied by value" escapes to heap gitee.com/u-language/u-language/ucom/cast2/utoc.go:82:13: inlining call to ast2.(*VarNode).C gitee.com/u-language/u-language/ucom/cast2/utoc.go:82:13: inlining call to strings.(*Builder).WriteString gitee.com/u-language/u-language/ucom/cast2/utoc.go:82:13: inlining call to strings.(*Builder).copyCheck gitee.com/u-language/u-language/ucom/cast2/utoc.go:82:13: inlining call to strings.noescape gitee.com/u-language/u-language/ucom/cast2/utoc.go:82:13: inlining call to strings.noescape gitee.com/u-language/u-language/ucom/check/check.go:134:23: inlining call to utils.PutMapSet gitee.com/u-language/u-language/ucom/check/check.go:175:24: inlining call to utils.PutMapSet gitee.com/u-language/u-language/ucom/check/check.go:27:23: inlining call to utils.PutMapSet gitee.com/u-language/u-language/ucom/check/ret.go:88:57: "&" + typ escapes to heap gitee.com/u-language/u-language/ucom/check/ret.go:88:57: &ast.Object{...} escapes to heap gitee.com/u-language/u-language/ucom/check/ret.go:88:57: ast.info escapes to heap gitee.com/u-language/u-language/ucom/check/ret.go:88:57: inlining call to IsExportSymbol gitee.com/u-language/u-language/ucom/check/ret.go:88:57: inlining call to ast.(*Sbt).Have gitee.com/u-language/u-language/ucom/check/ret.go:88:57: inlining call to ast.(*SymbolInfo).PtrStructDecl gitee.com/u-language/u-language/ucom/check/ret.go:88:57: inlining call to ast.(*SymbolInfo).PtrVarInfoSbt gitee.com/u-language/u-language/ucom/check/ret.go:88:57: inlining call to ast.NewObject gitee.com/u-language/u-language/ucom/check/ret.go:88:57: inlining call to ast.NewSymbolInfo_Var gitee.com/u-language/u-language/ucom/check/ret.go:88:57: inlining call to ast.NewVarInfoSbt gitee.com/u-language/u-language/ucom/check/ret.go:88:57: inlining call to check_selector gitee.com/u-language/u-language/ucom/check/ret.go:88:57: inlining call to errcode.NewMsgSymbol gitee.com/u-language/u-language/ucom/check/ret.go:88:57: inlining call to errcode.remove_package_name gitee.com/u-language/u-language/ucom/check/ret.go:88:57: ~r0 escapes to heap gitee.com/u-language/u-language/ucom/check3/check3.go:214:31: "&" + typ escapes to heap gitee.com/u-language/u-language/ucom/check3/check3.go:214:31: ... argument does not escape gitee.com/u-language/u-language/ucom/check3/check3.go:214:31: inlining call to ast2.(*Tree).Panic gitee.com/u-language/u-language/ucom/check3/check3.go:214:31: inlining call to check_parame_num gitee.com/u-language/u-language/ucom/check3/check3.go:214:31: inlining call to errcode.NewMsgNumberOfParameNoMatch gitee.com/u-language/u-language/ucom/check3/check3.go:214:31: inlining call to predefined_func gitee.com/u-language/u-language/ucom/check3/check3.go:214:31: ~r0 escapes to heap gitee.com/u-language/u-language/ucom/check3/check3.go:45:39: ... argument does not escape gitee.com/u-language/u-language/ucom/check3/check3.go:45:39: errcode.NewMsgCallTypeIsNotEqual(decltyp, typ, i + 1) escapes to heap gitee.com/u-language/u-language/ucom/check3/check3.go:45:39: inlining call to ast2.(*Sbt).Have gitee.com/u-language/u-language/ucom/check3/check3.go:45:39: inlining call to ast2.(*Tree).Panic gitee.com/u-language/u-language/ucom/check3/check3.go:45:39: inlining call to checkCall gitee.com/u-language/u-language/ucom/check3/check3.go:45:39: inlining call to check_parame_num gitee.com/u-language/u-language/ucom/check3/check3.go:45:39: inlining call to errcode.NewMsgNumberOfParameNoMatch gitee.com/u-language/u-language/ucom/check3/check3.go:45:39: inlining call to errcode.NewMsgUnknownSymbol gitee.com/u-language/u-language/ucom/check3/check3.go:45:39: inlining call to errcode.remove_package_name gitee.com/u-language/u-language/ucom/check3/check3.go:45:39: inlining call to utils.IsPtr gitee.com/u-language/u-language/ucom/check3/check3.go:45:39: inlining call to utils.Typ_is_equal gitee.com/u-language/u-language/ucom/check3/check3.go:45:39: inlining call to utils.is_ptr_and_nil gitee.com/u-language/u-language/ucom/check3/check3.go:45:39: ~r0 escapes to heap gitee.com/u-language/u-language/ucom/check3/check3.go:62:12: inlining call to checkElse gitee.com/u-language/u-language/ucom/parser/package.go:38:29: inlining call to utils.NewWaitGroup gitee.com/u-language/u-language/ucom/parser/package.go:83:10: ast.p.FindTree does not escape gitee.com/u-language/u-language/ucom/parser/package.go:83:10: inlining call to ast.(*Package).Parser github.com/huandu/go-clone@v1.7.2/clone.go:102:30: &reflect.ValueError{...} escapes to heap github.com/huandu/go-clone@v1.7.2/clone.go:102:30: inlining call to (*cloneState).cloneInterface github.com/huandu/go-clone@v1.7.2/clone.go:102:30: inlining call to reflect.Value.IsNil github.com/huandu/go-clone@v1.7.2/clone.go:102:30: inlining call to reflect.Value.Type github.com/huandu/go-clone@v1.7.2/clone.go:102:30: inlining call to reflect.flag.kind github.com/huandu/go-clone@v1.7.2/clone.go:102:30: inlining call to reflect.noescape github.com/huandu/go-clone@v1.7.2/clone.go:102:30: inlining call to reflect.noescape github.com/huandu/go-clone@v1.7.2/clone.go:106:24: &reflect.ValueError{...} escapes to heap github.com/huandu/go-clone@v1.7.2/clone.go:106:24: inlining call to (*Allocator).New github.com/huandu/go-clone@v1.7.2/clone.go:106:24: inlining call to (*cloneState).clonePtr github.com/huandu/go-clone@v1.7.2/clone.go:106:24: inlining call to reflect.Value.CanInterface github.com/huandu/go-clone@v1.7.2/clone.go:106:24: inlining call to reflect.Value.IsNil github.com/huandu/go-clone@v1.7.2/clone.go:106:24: inlining call to reflect.Value.Kind github.com/huandu/go-clone@v1.7.2/clone.go:106:24: inlining call to reflect.Value.Type github.com/huandu/go-clone@v1.7.2/clone.go:106:24: inlining call to reflect.flag.kind github.com/huandu/go-clone@v1.7.2/clone.go:106:24: inlining call to reflect.noescape github.com/huandu/go-clone@v1.7.2/clone.go:106:24: inlining call to reflect.noescape github.com/huandu/go-clone@v1.7.2/clone.go:108:26: &reflect.ValueError{...} escapes to heap github.com/huandu/go-clone@v1.7.2/clone.go:108:26: inlining call to (*Allocator).MakeSlice github.com/huandu/go-clone@v1.7.2/clone.go:108:26: inlining call to (*cloneState).cloneSlice github.com/huandu/go-clone@v1.7.2/clone.go:108:26: inlining call to reflect.Value.Cap github.com/huandu/go-clone@v1.7.2/clone.go:108:26: inlining call to reflect.Value.IsNil github.com/huandu/go-clone@v1.7.2/clone.go:108:26: inlining call to reflect.Value.Len github.com/huandu/go-clone@v1.7.2/clone.go:108:26: inlining call to reflect.Value.Type github.com/huandu/go-clone@v1.7.2/clone.go:108:26: inlining call to reflect.flag.kind github.com/huandu/go-clone@v1.7.2/clone.go:108:26: inlining call to reflect.noescape github.com/huandu/go-clone@v1.7.2/clone.go:108:26: inlining call to reflect.noescape github.com/huandu/go-clone@v1.7.2/clone.go:230:19: inlining call to (*cloneState).copyStruct github.com/huandu/go-clone@v1.7.2/clone.go:230:19: inlining call to reflect.PointerTo github.com/huandu/go-clone@v1.7.2/clone.go:230:19: inlining call to reflect.PtrTo github.com/huandu/go-clone@v1.7.2/clone.go:230:19: inlining call to reflect.Value.CanAddr github.com/huandu/go-clone@v1.7.2/clone.go:230:19: inlining call to reflect.Value.Type github.com/huandu/go-clone@v1.7.2/clone.go:230:19: inlining call to reflect.noescape github.com/huandu/go-clone@v1.7.2/clone.go:230:19: inlining call to reflect.noescape github.com/huandu/go-clone@v1.7.2/clone.go:230:19: inlining call to reflect.toRType github.com/spf13/cobra@v1.8.0/bash_completions.go:449:32: commandSorterByName(c.commands) escapes to heap github.com/spf13/cobra@v1.8.0/bash_completions.go:449:32: inlining call to (*Command).Commands github.com/spf13/cobra@v1.8.0/bash_completions.go:656:32: commandSorterByName(c.commands) escapes to heap github.com/spf13/cobra@v1.8.0/bash_completions.go:656:32: inlining call to (*Command).Commands github.com/spf13/cobra@v1.8.0/command.go:1250:40: commandSorterByName(c.commands) escapes to heap github.com/spf13/cobra@v1.8.0/command.go:1250:40: inlining call to (*Command).Commands github.com/spf13/cobra@v1.8.0/completions.go:286:26: commandSorterByName(c.commands) escapes to heap github.com/spf13/cobra@v1.8.0/completions.go:286:26: inlining call to (*Command).Commands github.com/spf13/cobra@v1.8.0/completions.go:455:45: commandSorterByName(c.commands) escapes to heap github.com/spf13/cobra@v1.8.0/completions.go:455:45: inlining call to (*Command).Commands github.com/spf13/pflag@v1.0.5/flag.go:213:11: inlining call to sort.StringSlice.Sort github.com/spf13/pflag@v1.0.5/flag.go:213:11: sort.x escapes to heap golang.org/x/sys@v0.15.0/windows/exec_windows.go:203:24: inlining call to UTF16ToString golang.org/x/sys@v0.15.0/windows/security_windows.go:219:29: inlining call to UTF16ToString golang.org/x/sys@v0.15.0/windows/security_windows.go:238:22: inlining call to UTF16ToString golang.org/x/sys@v0.15.0/windows/security_windows.go:309:24: inlining call to UTF16ToString golang.org/x/sys@v0.15.0/windows/security_windows.go:309:42: inlining call to UTF16ToString golang.org/x/sys@v0.15.0/windows/security_windows.go:42:24: inlining call to UTF16ToString golang.org/x/sys@v0.15.0/windows/security_windows.go:744:24: inlining call to UTF16ToString golang.org/x/sys@v0.15.0/windows/security_windows.go:788:24: inlining call to UTF16ToString golang.org/x/sys@v0.15.0/windows/security_windows.go:807:24: inlining call to UTF16ToString golang.org/x/sys@v0.15.0/windows/security_windows.go:824:24: inlining call to UTF16ToString golang.org/x/sys@v0.15.0/windows/setupapi_windows.go:1096:24: inlining call to UTF16ToString golang.org/x/sys@v0.15.0/windows/setupapi_windows.go:1126:23: inlining call to UTF16ToString golang.org/x/sys@v0.15.0/windows/setupapi_windows.go:1130:25: inlining call to UTF16ToString golang.org/x/sys@v0.15.0/windows/setupapi_windows.go:1145:25: inlining call to UTF16ToString golang.org/x/sys@v0.15.0/windows/setupapi_windows.go:1145:25: ~r0 escapes to heap golang.org/x/sys@v0.15.0/windows/setupapi_windows.go:1161:32: inlining call to UTF16ToString golang.org/x/sys@v0.15.0/windows/setupapi_windows.go:1260:23: inlining call to UTF16ToString golang.org/x/sys@v0.15.0/windows/setupapi_windows.go:1311:27: inlining call to UTF16ToString golang.org/x/sys@v0.15.0/windows/setupapi_windows.go:1407:49: inlining call to UTF16ToString golang.org/x/sys@v0.15.0/windows/setupapi_windows.go:178:22: inlining call to UTF16ToString golang.org/x/sys@v0.15.0/windows/setupapi_windows.go:250:22: inlining call to UTF16ToString golang.org/x/sys@v0.15.0/windows/setupapi_windows.go:435:22: inlining call to UTF16ToString golang.org/x/sys@v0.15.0/windows/setupapi_windows.go:448:22: inlining call to UTF16ToString golang.org/x/sys@v0.15.0/windows/setupapi_windows.go:461:22: inlining call to UTF16ToString golang.org/x/sys@v0.15.0/windows/setupapi_windows.go:521:22: inlining call to UTF16ToString golang.org/x/sys@v0.15.0/windows/setupapi_windows.go:525:22: inlining call to UTF16ToString golang.org/x/sys@v0.15.0/windows/setupapi_windows.go:529:22: inlining call to UTF16ToString golang.org/x/sys@v0.15.0/windows/setupapi_windows.go:535:23: inlining call to UTF16ToString golang.org/x/sys@v0.15.0/windows/setupapi_windows.go:550:32: inlining call to UTF16ToString golang.org/x/sys@v0.15.0/windows/syscall_windows.go:1491:20: inlining call to UTF16ToString golang.org/x/sys@v0.15.0/windows/syscall_windows.go:1495:20: inlining call to UTF16ToString golang.org/x/sys@v0.15.0/windows/syscall_windows.go:1680:22: inlining call to UTF16ToString hot-budget check allows inlining for call gitee.com/u-language/u-language/ucom/ast.(*Sbt).AddMethod (cost 468) at gitee.com/u-language/u-language/ucom/ast/Parser.go:1237:25 in function gitee.com/u-language/u-language/ucom/ast.parserMethod hot-budget check allows inlining for call gitee.com/u-language/u-language/ucom/ast.parserASSIGN (cost 1865) at gitee.com/u-language/u-language/ucom/ast/Parser.go:250:25 in function gitee.com/u-language/u-language/ucom/ast.ParserVAR hot-budget check allows inlining for call gitee.com/u-language/u-language/ucom/ast.parserASSIGN (cost 1865) at gitee.com/u-language/u-language/ucom/ast/Parser.go:478:22 in function gitee.com/u-language/u-language/ucom/ast.parserSece hot-budget check allows inlining for call gitee.com/u-language/u-language/ucom/ast2.(*Tree).findElse (cost 533) at gitee.com/u-language/u-language/ucom/ast2/parser.go:557:19 in function gitee.com/u-language/u-language/ucom/ast2.(*Tree).parserIf hot-budget check allows inlining for call gitee.com/u-language/u-language/ucom/ast2.(*Tree).parserGoto (cost 216) at gitee.com/u-language/u-language/ucom/ast2/parser.go:124:15 in function gitee.com/u-language/u-language/ucom/ast2.(*Tree).parser hot-budget check allows inlining for call gitee.com/u-language/u-language/ucom/ast2.(*Tree).parserIndexExprOrGenericInstantiation (cost 890) at gitee.com/u-language/u-language/ucom/ast2/expr3.go:303:55 in function gitee.com/u-language/u-language/ucom/ast2.(*stack).AutoPush hot-budget check allows inlining for call gitee.com/u-language/u-language/ucom/ast2.(*Tree).parserObject3 (cost 324) at gitee.com/u-language/u-language/ucom/ast2/parser.go:501:25 in function gitee.com/u-language/u-language/ucom/ast2.(*Tree).parserSelect2 hot-budget check allows inlining for call gitee.com/u-language/u-language/ucom/ast2.(*Tree).parserType2 (cost 540) at gitee.com/u-language/u-language/ucom/ast2/parser.go:220:22 in function gitee.com/u-language/u-language/ucom/ast2.(*Tree).parserType hot-budget check allows inlining for call gitee.com/u-language/u-language/ucom/ast2.(*VarNode).C (cost 1217) at gitee.com/u-language/u-language/ucom/cast2/utoc.go:82:13 in function gitee.com/u-language/u-language/ucom/cast2.generateCFile hot-budget check allows inlining for call gitee.com/u-language/u-language/ucom/cast.(*Package).GenerateheaderFile (cost 947) at gitee.com/u-language/u-language/ucom/cast/package.go:188:36 in function gitee.com/u-language/u-language/ucom/cast.(*Package).C hot-budget check allows inlining for call gitee.com/u-language/u-language/ucom/cast.generateInit (cost 1710) at gitee.com/u-language/u-language/ucom/cast/ast.go:144:22 in function gitee.com/u-language/u-language/ucom/cast.(*UtoC).C hot-budget check allows inlining for call gitee.com/u-language/u-language/ucom/cast2.generateInit (cost 1817) at gitee.com/u-language/u-language/ucom/cast2/utoc.go:35:22 in function gitee.com/u-language/u-language/ucom/cast2.(*UtoC).C hot-budget check allows inlining for call gitee.com/u-language/u-language/ucom/check.check_selector (cost 1871) at gitee.com/u-language/u-language/ucom/check/ret.go:88:57 in function gitee.com/u-language/u-language/ucom/check.ret_info hot-budget check allows inlining for call gitee.com/u-language/u-language/ucom/check3.checkCall (cost 1132) at gitee.com/u-language/u-language/ucom/check3/check3.go:45:39 in function gitee.com/u-language/u-language/ucom/check3.checkNode hot-budget check allows inlining for call gitee.com/u-language/u-language/ucom/check3.predefined_func (cost 568) at gitee.com/u-language/u-language/ucom/check3/check3.go:214:31 in function gitee.com/u-language/u-language/ucom/check3.checkCall hot-budget check allows inlining for call github.com/huandu/go-clone.(*cloneState).cloneInterface (cost 1607) at github.com/huandu/go-clone@v1.7.2/clone.go:102:30 in function github.com/huandu/go-clone.(*cloneState).clone hot-budget check allows inlining for call github.com/huandu/go-clone.(*cloneState).clonePtr (cost 1426) at github.com/huandu/go-clone@v1.7.2/clone.go:106:24 in function github.com/huandu/go-clone.(*cloneState).clone hot-budget check allows inlining for call github.com/huandu/go-clone.(*cloneState).cloneSlice (cost 1419) at github.com/huandu/go-clone@v1.7.2/clone.go:108:26 in function github.com/huandu/go-clone.(*cloneState).clone hot-budget check allows inlining for call github.com/huandu/go-clone.(*cloneState).copyStruct (cost 1558) at github.com/huandu/go-clone@v1.7.2/clone.go:230:19 in function github.com/huandu/go-clone.(*cloneState).clonePtr hot-budget check allows inlining for call reflect.haveIdenticalUnderlyingType (cost 1974) at reflect/value.go:3541:32 in function reflect.convertOp hot-budget check allows inlining for call reflect.implements (cost 1846) at reflect/value.go:3552:15 in function reflect.convertOp hot-budget check allows inlining for call runtime.(*mcentral).cacheSpan (cost 1698) at runtime/mcache.go:182:44 in function runtime.(*mcache).refill hot-budget check allows inlining for call runtime.(*pageAlloc).allocRange (cost 1012) at runtime/mpagealloc.go:914:21 in function runtime.(*pageAlloc).alloc hot-budget check allows inlining for call runtime.(*pageAlloc).free (cost 1767) at runtime/mheap.go:1640:14 in function runtime.(*mheap).freeSpanLocked hot-budget check allows inlining for call runtime.finishsweep_m (cost 1312) at runtime/mgc.go:684:16 in function runtime.gcStart.func2 hot-budget check allows inlining for call runtime.gcDrain (cost 958) at runtime/mgcmark.go:1017:9 in function runtime.gcDrainMarkWorkerIdle hot-budget check allows inlining for call runtime.gcDrain (cost 958) at runtime/mgcmark.go:1027:9 in function runtime.gcDrainMarkWorkerDedicated hot-budget check allows inlining for call runtime.gcDrainMarkWorkerIdle (cost 962) at runtime/mgc.go:1395:26 in function runtime.gcBgMarkWorker.func2 hot-budget check allows inlining for call runtime.gcDrainN (cost 1293) at runtime/mgcmark.go:568:22 in function runtime.gcAssistAlloc1 hot-budget check allows inlining for call runtime.markrootSpans (cost 652) at runtime/mgcmark.go:193:16 in function runtime.markroot hot-budget check allows inlining for call runtime.newproc1 (cost 1681) at runtime/proc.go:4492:19 in function runtime.newproc.func1 hot-budget check allows inlining for call runtime.procresize (cost 1620) at runtime/proc.go:1452:18 in function runtime.startTheWorldWithSema hot-budget check allows inlining for call runtime.scanframeworker (cost 1587) at runtime/mgcmark.go:803:18 in function runtime.scanstack hot-budget check allows inlining for call runtime.suspendG (cost 1157) at runtime/mgcmark.go:232:23 in function runtime.markroot.func1 internal/intern/intern.go:66:19: inlining call to safeMap internal/intern/intern.go:66:19: map[key]*Value{} escapes to heap math/big/nat.go:1195:8: inlining call to putNat math/big/nat.go:1197:9: inlining call to putNat math/big/nat.go:486:9: inlining call to putNat math/big/nat.go:511:8: inlining call to putNat math/big/nat.go:607:9: inlining call to putNat math/big/natdiv.go:512:8: inlining call to putNat math/big/natdiv.go:620:8: inlining call to putNat math/big/natdiv.go:710:8: inlining call to putNat math/big/natdiv.go:743:10: inlining call to putNat math/big/natdiv.go:746:8: inlining call to putNat os/file_windows.go:130:21: inlining call to (*dirInfo).close os/file_windows.go:154:18: inlining call to (*dirInfo).close reflect/value.go:3541:32: inlining call to abi.(*FuncType).In reflect/value.go:3541:32: inlining call to abi.(*FuncType).InSlice reflect/value.go:3541:32: inlining call to abi.(*FuncType).NumIn reflect/value.go:3541:32: inlining call to abi.(*FuncType).NumOut reflect/value.go:3541:32: inlining call to abi.(*FuncType).Out reflect/value.go:3541:32: inlining call to abi.(*FuncType).OutSlice reflect/value.go:3541:32: inlining call to abi.(*StructField).Embedded reflect/value.go:3541:32: inlining call to abi.(*Type).ChanDir reflect/value.go:3541:32: inlining call to abi.(*Type).Elem reflect/value.go:3541:32: inlining call to abi.(*Type).Key reflect/value.go:3541:32: inlining call to abi.(*Type).Kind reflect/value.go:3541:32: inlining call to abi.(*Type).Len reflect/value.go:3541:32: inlining call to abi.Name.IsEmbedded reflect/value.go:3541:32: inlining call to abi.addChecked reflect/value.go:3541:32: inlining call to haveIdenticalUnderlyingType reflect/value.go:3552:15: inlining call to (*interfaceType).nameOff reflect/value.go:3552:15: inlining call to (*interfaceType).typeOff reflect/value.go:3552:15: inlining call to (*rtype).nameOff reflect/value.go:3552:15: inlining call to (*rtype).typeOff reflect/value.go:3552:15: inlining call to abi.(*Type).Kind reflect/value.go:3552:15: inlining call to abi.(*Type).Uncommon reflect/value.go:3552:15: inlining call to abi.(*UncommonType).Methods reflect/value.go:3552:15: inlining call to abi.Name.IsExported reflect/value.go:3552:15: inlining call to abi.addChecked reflect/value.go:3552:15: inlining call to implements reflect/value.go:3552:15: inlining call to nameOffFor reflect/value.go:3552:15: inlining call to toRType reflect/value.go:3552:15: inlining call to typeOffFor regexp/backtrack.go:315:18: inlining call to newBitState regexp/backtrack.go:315:18: new(bitState) escapes to heap regexp/exec.go:403:24: inlining call to newOnePassMachine regexp/exec.go:403:24: new(onePassMachine) escapes to heap runtime/arena.go:948:8: inlining call to sysMap runtime/arena.go:948:8: inlining call to sysMapOS runtime/debugcall.go:172:16: inlining call to casGToWaiting runtime/heapdump.go:698:15: inlining call to casGToWaiting runtime/iface.go:627:24: &TypeAssertionError{...} escapes to heap runtime/iface.go:627:24: inlining call to assertE2I runtime/iface.go:632:24: &TypeAssertionError{...} escapes to heap runtime/iface.go:632:24: inlining call to assertE2I runtime/malloc.go:1587:10: inlining call to sysMap runtime/malloc.go:1587:10: inlining call to sysMapOS runtime/mbarrier.go:211:22: inlining call to reflect_typedmemmove runtime/mbitmap.go:583:17: inlining call to (*wbBuf).get1 runtime/mbitmap.go:626:16: inlining call to (*wbBuf).get1 runtime/mbitmap.go:658:18: inlining call to (*wbBuf).get1 runtime/mcache.go:182:44: inlining call to (*activeSweep).begin runtime/mcache.go:182:44: inlining call to (*mcentral).cacheSpan runtime/mcache.go:182:44: inlining call to (*mcentral).fullSwept runtime/mcache.go:182:44: inlining call to (*mcentral).fullUnswept runtime/mcache.go:182:44: inlining call to (*mcentral).partialSwept runtime/mcache.go:182:44: inlining call to (*mcentral).partialUnswept runtime/mcache.go:182:44: inlining call to atomic.(*Uint32).CompareAndSwap runtime/mcache.go:182:44: inlining call to atomic.(*Uint32).Load runtime/mcache.go:182:44: inlining call to spanClass.sizeclass runtime/mcache.go:182:44: inlining call to traceEnabled runtime/mfinal.go:249:34: &TypeAssertionError{...} escapes to heap runtime/mfinal.go:249:34: inlining call to assertE2I runtime/mfinal.go:467:24: inlining call to assertE2I2 runtime/mgc.go:1371:17: inlining call to casGToWaiting runtime/mgc.go:684:16: inlining call to (*activeSweep).sweepers runtime/mgc.go:684:16: inlining call to (*mcentral).fullUnswept runtime/mgc.go:684:16: inlining call to (*mcentral).partialUnswept runtime/mgc.go:684:16: inlining call to assertWorldStopped runtime/mgc.go:684:16: inlining call to atomic.(*Uint32).Load runtime/mgc.go:684:16: inlining call to finishsweep_m runtime/mgc.go:833:16: inlining call to casGToWaiting runtime/mgc.go:951:15: inlining call to casGToWaiting runtime/mgcmark.go:1017:9: inlining call to (*gcWork).tryGetFast runtime/mgcmark.go:1017:9: inlining call to atomic.(*Bool).Load runtime/mgcmark.go:1017:9: inlining call to atomic.(*Int64).Add runtime/mgcmark.go:1017:9: inlining call to atomic.(*Uint8).Load runtime/mgcmark.go:1017:9: inlining call to gcDrain runtime/mgcmark.go:1027:9: inlining call to (*gcWork).tryGetFast runtime/mgcmark.go:1027:9: inlining call to atomic.(*Bool).Load runtime/mgcmark.go:1027:9: inlining call to atomic.(*Int64).Add runtime/mgcmark.go:1027:9: inlining call to atomic.(*Uint8).Load runtime/mgcmark.go:1027:9: inlining call to gcDrain runtime/mgcmark.go:193:16: inlining call to (*mSpanStateBox).get runtime/mgcmark.go:193:16: inlining call to (*mspan).base runtime/mgcmark.go:193:16: inlining call to arenaIdx.l1 runtime/mgcmark.go:193:16: inlining call to arenaIdx.l2 runtime/mgcmark.go:193:16: inlining call to atomic.(*Uint8).Load runtime/mgcmark.go:193:16: inlining call to getLockRank runtime/mgcmark.go:193:16: inlining call to lock runtime/mgcmark.go:193:16: inlining call to lockWithRank runtime/mgcmark.go:193:16: inlining call to markrootSpans runtime/mgcmark.go:193:16: inlining call to spanClass.noscan runtime/mgcmark.go:193:16: inlining call to unlock runtime/mgcmark.go:193:16: inlining call to unlockWithRank runtime/mgcmark.go:222:18: inlining call to casGToWaiting runtime/mgcmark.go:232:23: func literal does not escape runtime/mgcmark.go:232:23: inlining call to atomic.(*Uint32).Load runtime/mgcmark.go:232:23: inlining call to dumpgstatus runtime/mgcmark.go:232:23: inlining call to nanotime runtime/mgcmark.go:232:23: inlining call to osyield runtime/mgcmark.go:232:23: inlining call to readgstatus runtime/mgcmark.go:232:23: inlining call to suspendG runtime/mgcmark.go:563:15: inlining call to casGToWaiting runtime/mgcmark.go:568:22: inlining call to (*gcCPULimiterState).limiting runtime/mgcmark.go:568:22: inlining call to (*gcWork).tryGetFast runtime/mgcmark.go:568:22: inlining call to atomic.(*Bool).Load runtime/mgcmark.go:568:22: inlining call to atomic.(*Int64).Add runtime/mgcmark.go:568:22: inlining call to atomic.(*Uint8).Load runtime/mgcmark.go:568:22: inlining call to gcDrainN runtime/mgcmark.go:802:12: inlining call to (*unwinder).init runtime/mgcmark.go:803:18: inlining call to funcInfo.valid runtime/mgcmark.go:803:18: inlining call to scanframeworker runtime/mgcsweep.go:103:29: inlining call to (*spanSetBlockAlloc).free runtime/mgcsweep.go:103:29: inlining call to atomic.(*Uint32).Store runtime/mgcsweep.go:105:32: inlining call to (*spanSetBlockAlloc).free runtime/mgcsweep.go:105:32: inlining call to atomic.(*Uint32).Store runtime/mgcsweep.go:255:29: inlining call to (*spanSetBlockAlloc).free runtime/mgcsweep.go:255:29: inlining call to atomic.(*Uint32).Store runtime/mgcsweep.go:256:26: inlining call to (*spanSetBlockAlloc).free runtime/mgcsweep.go:256:26: inlining call to atomic.(*Uint32).Store runtime/mheap.go:1503:11: inlining call to sysMap runtime/mheap.go:1503:11: inlining call to sysMapOS runtime/mheap.go:1534:8: inlining call to sysMap runtime/mheap.go:1534:8: inlining call to sysMapOS runtime/mheap.go:1640:14: inlining call to (*pageAlloc).chunkOf runtime/mheap.go:1640:14: inlining call to (*pageAlloc).free runtime/mheap.go:1640:14: inlining call to (*pageBits).clear runtime/mheap.go:1640:14: inlining call to (*pageBits).clearAll runtime/mheap.go:1640:14: inlining call to (*pallocBits).free runtime/mheap.go:1640:14: inlining call to (*pallocBits).free1 runtime/mheap.go:1640:14: inlining call to (*pallocBits).freeAll runtime/mheap.go:1640:14: inlining call to assertLockHeld runtime/mheap.go:1640:14: inlining call to chunkIdx.l1 runtime/mheap.go:1640:14: inlining call to chunkIdx.l2 runtime/mheap.go:1640:14: inlining call to chunkIndex runtime/mheap.go:1640:14: inlining call to chunkPageIndex runtime/mheap.go:1640:14: inlining call to offAddr.lessThan runtime/mpagealloc.go:914:21: inlining call to (*pageAlloc).allocRange runtime/mpagealloc.go:914:21: inlining call to (*pageAlloc).chunkOf runtime/mpagealloc.go:914:21: inlining call to (*pageBits).clearAll runtime/mpagealloc.go:914:21: inlining call to (*pageBits).setAll runtime/mpagealloc.go:914:21: inlining call to (*pallocBits).allocAll runtime/mpagealloc.go:914:21: inlining call to (*pallocData).allocAll runtime/mpagealloc.go:914:21: inlining call to assertLockHeld runtime/mpagealloc.go:914:21: inlining call to chunkIdx.l1 runtime/mpagealloc.go:914:21: inlining call to chunkIdx.l2 runtime/mpagealloc.go:914:21: inlining call to chunkIndex runtime/mpagealloc.go:914:21: inlining call to chunkPageIndex runtime/mpagealloc_64bit.go:179:9: inlining call to sysMap runtime/mpagealloc_64bit.go:179:9: inlining call to sysMapOS runtime/mpagealloc_64bit.go:235:9: inlining call to sysMap runtime/mpagealloc_64bit.go:235:9: inlining call to sysMapOS runtime/mspanset.go:218:24: inlining call to (*spanSetBlockAlloc).free runtime/mspanset.go:218:24: inlining call to atomic.(*Uint32).Store runtime/mspanset.go:264:25: inlining call to (*spanSetBlockAlloc).free runtime/mspanset.go:264:25: inlining call to atomic.(*Uint32).Store runtime/pinner.go:171:34: inlining call to (*mspan).newPinnerBits runtime/pinner.go:315:35: inlining call to (*mspan).newPinnerBits runtime/print.go:252:14: inlining call to printpointer runtime/proc.go:1276:16: inlining call to casGToWaiting runtime/proc.go:1452:18: ... argument does not escape runtime/proc.go:1452:18: inlining call to (*muintptr).set runtime/proc.go:1452:18: inlining call to (*puintptr).set runtime/proc.go:1452:18: inlining call to (*randomOrder).reset runtime/proc.go:1452:18: inlining call to assertLockHeld runtime/proc.go:1452:18: inlining call to assertWorldStopped runtime/proc.go:1452:18: inlining call to atomicstorep runtime/proc.go:1452:18: inlining call to gcd runtime/proc.go:1452:18: inlining call to getLockRank runtime/proc.go:1452:18: inlining call to lock runtime/proc.go:1452:18: inlining call to lockWithRank runtime/proc.go:1452:18: inlining call to mget runtime/proc.go:1452:18: inlining call to muintptr.ptr runtime/proc.go:1452:18: inlining call to nanotime runtime/proc.go:1452:18: inlining call to noescape runtime/proc.go:1452:18: inlining call to noescape runtime/proc.go:1452:18: inlining call to procresize runtime/proc.go:1452:18: inlining call to puintptr.ptr runtime/proc.go:1452:18: inlining call to runqempty runtime/proc.go:1452:18: inlining call to traceEnabled runtime/proc.go:1452:18: inlining call to traceGoSched runtime/proc.go:1452:18: inlining call to traceGomaxprocs runtime/proc.go:1452:18: inlining call to unlock runtime/proc.go:1452:18: inlining call to unlockWithRank runtime/proc.go:1452:18: make([]*p, nprocs) escapes to heap runtime/proc.go:1452:18: make([]uint32, maskWords) escapes to heap runtime/proc.go:1452:18: new(p) escapes to heap runtime/proc.go:4492:19: inlining call to (*gcControllerState).addScannableStack runtime/proc.go:4492:19: inlining call to (*goroutineProfileStateHolder).Store runtime/proc.go:4492:19: inlining call to acquirem runtime/proc.go:4492:19: inlining call to alignUp runtime/proc.go:4492:19: inlining call to atomic.(*Int32).Add runtime/proc.go:4492:19: inlining call to atomic.(*Uint32).Load runtime/proc.go:4492:19: inlining call to atomic.(*Uint32).Store runtime/proc.go:4492:19: inlining call to atomic.(*Uint64).Add runtime/proc.go:4492:19: inlining call to fastrand runtime/proc.go:4492:19: inlining call to newproc1 runtime/proc.go:4492:19: inlining call to puintptr.ptr runtime/proc.go:4492:19: inlining call to readgstatus runtime/proc.go:4492:19: inlining call to releasem runtime/proc.go:4492:19: inlining call to traceEnabled runtime/stack.go:930:12: inlining call to (*unwinder).init runtime/symtab.go:820:25: inlining call to (*moduledata).funcName runtime/symtab.go:980:25: inlining call to (*moduledata).funcName runtime/traceback.go:1114:8: inlining call to (*unwinder).init
Interesting. My best guess is that the additional PGO inlines made a caller of NewMsgUnknownSymbol too expensive to inline into. The "hot-budget" logs only inlines explicitly allowed by PGO. There could be some downstream effects on non-PGO inlines [1].
The difference results don't seem to support your guess, it shows what happened after b56645a87b28840a180d64077877cb46570b4176, gitee.com/u-language/u-language/ucom/check3/check3.go:45:39: inlining call to errcode.NewMsgUnknownSymbol but I don`t confirm this come from the performance regression line, because https://gitee.com/u-language/u-language/blob/pgo2024-8-9/ucom/check3/check3.go#L201 call same funcname in caller(checkCall).
Go version
go version devel go1.24-f428c7b7 Sat Aug 3 05:06:40 2024 +0000 windows/amd64
Output of
go env
in your module/workspace:What did you do?
Repeat step:
git clone https://gitee.com/u-language/u-language.git -b pgo2024-8-9 cd u-language Set environment variable URoot to the current path cd ucom
go test -run=ssss -bench=Mode2 -count=10 -pgo off > new.txt && sleep 20 && go test -run=ssss -bench=Mode2 -count=10 > pgo.txt && benchstat new.txt pgo.txt
What did you see happen?
pgo does not cause performance degradation
What did you expect to see?