cmd/compile: shortcut intrinsic inlining AFTER getcallerXX check

A check in inl.go to prevent inlining of functions calling
either getcallerpc or getcallersp does not work when these
functions are intrinsics. Swap checks to fix.

Includes test.

No bug, this was discovered in the course of a ridiculous
experiment with inlining.

Change-Id: Ie1392523bb89882d586678f2674e1a4eadc5e431
Reviewed-on: https://go-review.googlesource.com/c/go/+/172217
Run-TryBot: David Chase <drchase@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
David Chase 2019-04-15 21:27:04 -04:00
parent dc193dee15
commit 376ce8c880
4 changed files with 42 additions and 5 deletions

View file

@ -289,10 +289,6 @@ func (v *hairyVisitor) visit(n *Node) bool {
switch n.Op { switch n.Op {
// Call is okay if inlinable and we have the budget for the body. // Call is okay if inlinable and we have the budget for the body.
case OCALLFUNC: case OCALLFUNC:
if isIntrinsicCall(n) {
v.budget--
break
}
// Functions that call runtime.getcaller{pc,sp} can not be inlined // Functions that call runtime.getcaller{pc,sp} can not be inlined
// because getcaller{pc,sp} expect a pointer to the caller's first argument. // because getcaller{pc,sp} expect a pointer to the caller's first argument.
// //
@ -309,6 +305,11 @@ func (v *hairyVisitor) visit(n *Node) bool {
} }
} }
if isIntrinsicCall(n) {
v.budget--
break
}
if fn := n.Left.Func; fn != nil && fn.Inl != nil { if fn := n.Left.Func; fn != nil && fn.Inl != nil {
v.budget -= fn.Inl.Cost v.budget -= fn.Inl.Cost
break break

View file

@ -49,7 +49,7 @@ var (
// dirs are the directories to look for *.go files in. // dirs are the directories to look for *.go files in.
// TODO(bradfitz): just use all directories? // TODO(bradfitz): just use all directories?
dirs = []string{".", "ken", "chan", "interface", "syntax", "dwarf", "fixedbugs", "codegen"} dirs = []string{".", "ken", "chan", "interface", "syntax", "dwarf", "fixedbugs", "codegen", "runtime"}
// ratec controls the max number of tests running at a time. // ratec controls the max number of tests running at a time.
ratec chan bool ratec chan bool

7
test/runtime/README Normal file
View file

@ -0,0 +1,7 @@
// Copyright 2019 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.
The runtime directory contains tests that specifically need
to be compiled as-if in the runtime package. For error-check
tests, these require the additional flags -+ and -p=runtime.

View file

@ -0,0 +1,29 @@
// errorcheck -0 -+ -p=runtime -m -newescape=true
// Copyright 2019 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 runtime
// A function that calls runtime.getcallerpc or runtime.getcallersp()
// cannot be inlined, no matter how small it is.
func getcallerpc() uintptr
func getcallersp() uintptr
func pc() uintptr {
return getcallerpc() + 1
}
func cpc() uintptr { // ERROR "can inline cpc"
return pc() + 2
}
func sp() uintptr {
return getcallersp() + 3
}
func csp() uintptr { // ERROR "can inline csp"
return sp() + 4
}