mirror of https://github.com/golang/go.git
cmd/compile: record InlCost in export data
Previously, we were treating cross-package function calls as free for inlining budgeting. In theory, we should be able to recompute InlCost from the exported/reimported function bodies. However, that process mutates the structure of the Node AST enough that it doesn't preserve InlCost. To avoid unexpected issues, just record and restore InlCost in the export data. Fixes #19261. Change-Id: Iac2bc0d32d4f948b64524aca657051f9fc96d92d Reviewed-on: https://go-review.googlesource.com/70151 Run-TryBot: Matthew Dempsky <mdempsky@google.com> Reviewed-by: Robert Griesemer <gri@golang.org>
This commit is contained in:
parent
1fbeccb15a
commit
a509cae90d
|
|
@ -377,6 +377,7 @@ func export(out *bufio.Writer, trace bool) int {
|
|||
p.tracef("\n----\nfunc { %#v }\n", f.Inl)
|
||||
}
|
||||
p.int(i)
|
||||
p.int(int(f.InlCost))
|
||||
p.stmtList(f.Inl)
|
||||
if p.trace {
|
||||
p.tracef("\n")
|
||||
|
|
|
|||
|
|
@ -187,6 +187,7 @@ func Import(imp *types.Pkg, in *bufio.Reader) {
|
|||
// them only for functions with inlineable bodies. funchdr does
|
||||
// parameter renaming which doesn't matter if we don't have a body.
|
||||
|
||||
inlCost := p.int()
|
||||
if f := p.funcList[i]; f != nil {
|
||||
// function not yet imported - read body and set it
|
||||
funchdr(f)
|
||||
|
|
@ -200,6 +201,7 @@ func Import(imp *types.Pkg, in *bufio.Reader) {
|
|||
body = []*Node{nod(OEMPTY, nil, nil)}
|
||||
}
|
||||
f.Func.Inl.Set(body)
|
||||
f.Func.InlCost = int32(inlCost)
|
||||
funcbody()
|
||||
} else {
|
||||
// function already imported - read body but discard declarations
|
||||
|
|
|
|||
|
|
@ -0,0 +1,24 @@
|
|||
// Copyright 2017 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 p
|
||||
|
||||
func F() { // ERROR "can inline F"
|
||||
print(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
|
||||
print(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
|
||||
print(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
|
||||
print(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
|
||||
print(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
|
||||
print(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
|
||||
}
|
||||
|
||||
func G() {
|
||||
F() // ERROR "inlining call to F"
|
||||
print(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
|
||||
print(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
|
||||
print(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
|
||||
print(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
|
||||
print(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
|
||||
print(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
// Copyright 2017 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 q
|
||||
|
||||
import "./p"
|
||||
|
||||
func H() {
|
||||
p.F() // ERROR "inlining call to p.F"
|
||||
print(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
|
||||
print(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
|
||||
print(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
|
||||
print(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
|
||||
print(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
|
||||
print(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
// errorcheckdir -0 -m
|
||||
|
||||
// Copyright 2017 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 ignored
|
||||
Loading…
Reference in New Issue