1
0
mirror of https://github.com/golang/go synced 2024-11-27 01:11:20 -07:00
go/test/fixedbugs/issue7921.go
Keith Randall 13baf4b2cd cmd/compile: encourage inlining of functions with single-call bodies
This is a simple tweak to allow a bit more mid-stack inlining.
In cases like this:

func f() {
    g()
}

We'd really like to inline f into its callers. It can't hurt.

We implement this optimization by making calls a bit cheaper, enough
to afford a single call in the function body, but not 2.
The remaining budget allows for some argument modification, or perhaps
a wrapping conditional:

func f(x int) {
    g(x, 0)
}
func f(x int) {
    if x > 0 {
        g()
    }
}

Update #19348

Change-Id: Ifb1ea0dd1db216c3fd5c453c31c3355561fe406f
Reviewed-on: https://go-review.googlesource.com/c/147361
Reviewed-by: Austin Clements <austin@google.com>
Reviewed-by: David Chase <drchase@google.com>
2018-11-08 17:29:23 +00:00

58 lines
2.0 KiB
Go

// +build !gcflags_noopt
// errorcheck -0 -m
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package foo
import "bytes"
// In order to get desired results, we need a combination of
// both escape analysis and inlining.
func bufferNotEscape() string {
// b itself does not escape, only its buf field will be
// 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"
}
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"
for _, x := range xs {
b.WriteString(x)
}
return b.Len() // ERROR "inlining call"
}
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"
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"
}
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"
}
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"
useBuffer(b)
}
//go:noinline
func useBuffer(b *bytes.Buffer) { // ERROR "b does not escape"
b.WriteString("1234")
}