From 624e197c71b673f0b3ebc57f774536131b4f0f26 Mon Sep 17 00:00:00 2001 From: David Chase Date: Fri, 30 Nov 2018 08:36:00 -0500 Subject: [PATCH] cmd/compile: decrease inlining call cost from 60 to 57 A Go user made a well-documented request for a slightly lower threshold. I tested against a selection of other people's benchmarks, and saw a tiny benefit (possibly noise) at equally tiny cost, and no unpleasant surprises observed in benchmarking. I.e., might help, doesn't hurt, low risk, request was delivered on a silver platter. It did, however, change the behavior of one test because now bytes.Buffer.Grow is eligible for inlining. Updates #19348. Change-Id: I85e3088a4911290872b8c6bda9601b5354c48695 Reviewed-on: https://go-review.googlesource.com/c/151977 Run-TryBot: David Chase TryBot-Result: Gobot Gobot Reviewed-by: Keith Randall --- src/cmd/compile/internal/gc/inl.go | 2 +- test/fixedbugs/issue7921.go | 30 +++++++++++++++--------------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/cmd/compile/internal/gc/inl.go b/src/cmd/compile/internal/gc/inl.go index 3f649be7cb..4699bcfa1f 100644 --- a/src/cmd/compile/internal/gc/inl.go +++ b/src/cmd/compile/internal/gc/inl.go @@ -39,7 +39,7 @@ const ( inlineMaxBudget = 80 inlineExtraAppendCost = 0 // default is to inline if there's at most one call. -l=4 overrides this by using 1 instead. - inlineExtraCallCost = inlineMaxBudget * 3 / 4 + inlineExtraCallCost = 57 // 57 was benchmarked to provided most benefit with no bad surprises; see https://github.com/golang/go/issues/19348#issuecomment-439370742 inlineExtraPanicCost = 1 // do not penalize inlining panics. inlineExtraThrowCost = inlineMaxBudget // with current (2018-05/1.11) code, inlining runtime.throw does not help. diff --git a/test/fixedbugs/issue7921.go b/test/fixedbugs/issue7921.go index 08fef0f128..ce8d09a276 100644 --- a/test/fixedbugs/issue7921.go +++ b/test/fixedbugs/issue7921.go @@ -17,41 +17,41 @@ func bufferNotEscape() string { // copied during String() call, but object "handle" itself // can be stack-allocated. var b bytes.Buffer - b.WriteString("123") // ERROR "b does not escape" - b.Write([]byte{'4'}) // ERROR "b does not escape" "\[\]byte literal does not escape" - return b.String() // ERROR "b does not escape" "inlining call" "string\(bytes\.b\.buf\[bytes.b.off:\]\) escapes to heap" + b.WriteString("123") // ERROR "bufferNotEscape b does not escape$" + b.Write([]byte{'4'}) // ERROR "bufferNotEscape \[\]byte literal does not escape$" "bufferNotEscape b does not escape$" + return b.String() // ERROR "bufferNotEscape b does not escape$" "inlining call to bytes.\(\*Buffer\).String$" "string\(bytes.b.buf\[bytes.b.off:\]\) escapes to heap$" } -func bufferNoEscape2(xs []string) int { // ERROR "xs does not escape" - b := bytes.NewBuffer(make([]byte, 0, 64)) // ERROR "inlining call" "make\(\[\]byte, 0, 64\) does not escape" "&bytes.Buffer literal does not escape" +func bufferNoEscape2(xs []string) int { // ERROR "bufferNoEscape2 xs does not escape$" + b := bytes.NewBuffer(make([]byte, 0, 64)) // ERROR "bufferNoEscape2 &bytes.Buffer literal does not escape$" "bufferNoEscape2 make\(\[\]byte, 0, 64\) does not escape$" "inlining call to bytes.NewBuffer$" for _, x := range xs { b.WriteString(x) } - return b.Len() // ERROR "inlining call" + return b.Len() // ERROR "inlining call to bytes.\(\*Buffer\).Len$" } -func bufferNoEscape3(xs []string) string { // ERROR "xs does not escape" - b := bytes.NewBuffer(make([]byte, 0, 64)) // ERROR "inlining call" "make\(\[\]byte, 0, 64\) does not escape" "&bytes.Buffer literal does not escape" +func bufferNoEscape3(xs []string) string { // ERROR "bufferNoEscape3 xs does not escape$" + b := bytes.NewBuffer(make([]byte, 0, 64)) // ERROR "bufferNoEscape3 &bytes.Buffer literal does not escape$" "bufferNoEscape3 make\(\[\]byte, 0, 64\) does not escape$" "inlining call to bytes.NewBuffer$" for _, x := range xs { b.WriteString(x) b.WriteByte(',') } - return b.String() // ERROR "inlining call" "string\(bytes.b.buf\[bytes\.b\.off:\]\) escapes to heap" + return b.String() // ERROR "inlining call to bytes.\(\*Buffer\).String$" "string\(bytes.b.buf\[bytes.b.off:\]\) escapes to heap$" } func bufferNoEscape4() []byte { var b bytes.Buffer - b.Grow(64) // ERROR "b does not escape" - useBuffer(&b) // ERROR "&b does not escape" - return b.Bytes() // ERROR "inlining call" "b does not escape" + b.Grow(64) // ERROR "bufferNoEscape4 b does not escape$" "bufferNoEscape4 ignoring self-assignment in bytes.b.buf = bytes.b.buf\[:bytes.m·3\]$" "inlining call to bytes.\(\*Buffer\).Grow$" + useBuffer(&b) // ERROR "bufferNoEscape4 &b does not escape$" + return b.Bytes() // ERROR "bufferNoEscape4 b does not escape$" "inlining call to bytes.\(\*Buffer\).Bytes$" } -func bufferNoEscape5() { // ERROR "can inline bufferNoEscape5" - b := bytes.NewBuffer(make([]byte, 0, 128)) // ERROR "inlining call" "make\(\[\]byte, 0, 128\) does not escape" "&bytes.Buffer literal does not escape" +func bufferNoEscape5() { // ERROR "can inline bufferNoEscape5$" + b := bytes.NewBuffer(make([]byte, 0, 128)) // ERROR "bufferNoEscape5 &bytes.Buffer literal does not escape$" "bufferNoEscape5 make\(\[\]byte, 0, 128\) does not escape$" "inlining call to bytes.NewBuffer$" useBuffer(b) } //go:noinline -func useBuffer(b *bytes.Buffer) { // ERROR "b does not escape" +func useBuffer(b *bytes.Buffer) { // ERROR "useBuffer b does not escape$" b.WriteString("1234") } -- 2.50.0