]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: shortcut intrinsic inlining AFTER getcallerXX check
authorDavid Chase <drchase@google.com>
Tue, 16 Apr 2019 01:27:04 +0000 (21:27 -0400)
committerDavid Chase <drchase@google.com>
Fri, 19 Apr 2019 20:18:29 +0000 (20:18 +0000)
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>
src/cmd/compile/internal/gc/inl.go
test/run.go
test/runtime/README [new file with mode: 0644]
test/runtime/inlinegcpc.go [new file with mode: 0644]

index 38be394bfb791cb93b6d26090c5a43f314bee3c2..35cbadafd73ccff34235078c4b9b929a7fa7535d 100644 (file)
@@ -289,10 +289,6 @@ func (v *hairyVisitor) visit(n *Node) bool {
        switch n.Op {
        // Call is okay if inlinable and we have the budget for the body.
        case OCALLFUNC:
-               if isIntrinsicCall(n) {
-                       v.budget--
-                       break
-               }
                // Functions that call runtime.getcaller{pc,sp} can not be inlined
                // 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 {
                        v.budget -= fn.Inl.Cost
                        break
index 460d4f2d8c3c98b5f5df774e95435dd6a1b32e83..f66db630c56d7c5e03e4d7e43cee24c3d968a415 100644 (file)
@@ -49,7 +49,7 @@ var (
 
        // dirs are the directories to look for *.go files in.
        // 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 chan bool
diff --git a/test/runtime/README b/test/runtime/README
new file mode 100644 (file)
index 0000000..249031a
--- /dev/null
@@ -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.
diff --git a/test/runtime/inlinegcpc.go b/test/runtime/inlinegcpc.go
new file mode 100644 (file)
index 0000000..0943205
--- /dev/null
@@ -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
+}