]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: reduce inline cost of OCONVOP
authorEgon Elbre <egonelbre@gmail.com>
Sat, 2 Jan 2021 14:28:11 +0000 (16:28 +0200)
committerJosh Bleecher Snyder <josharian@gmail.com>
Wed, 24 Feb 2021 17:00:14 +0000 (17:00 +0000)
OCONVOP doesn't have effect in the compiled code so, it can be safely
excluded from inline cost calculation.

Also make sequence ODEREF OCONVNOP* OADDR cost 1. This is rather common
conversion, such as *(*uint32)(unsafe.Pointer(&x)).

Fixes #42788

Change-Id: I5001f7e89d985c198b6405694cdd5b819cf3f47a
Reviewed-on: https://go-review.googlesource.com/c/go/+/281232
Reviewed-by: Keith Randall <khr@golang.org>
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Trust: Elias Naur <mail@eliasnaur.com>

src/cmd/compile/internal/inline/inl.go
test/inline.go

index 7d70fca6c9ff0e3a0d32c3c642808d34893657e7..0e57c1766760056309d93f2b6bb2e5cf2e0664a8 100644 (file)
@@ -384,6 +384,22 @@ func (v *hairyVisitor) doNode(n ir.Node) bool {
        case ir.OAPPEND:
                v.budget -= inlineExtraAppendCost
 
+       case ir.ODEREF:
+               // *(*X)(unsafe.Pointer(&x)) is low-cost
+               n := n.(*ir.StarExpr)
+
+               ptr := n.X
+               for ptr.Op() == ir.OCONVNOP {
+                       ptr = ptr.(*ir.ConvExpr).X
+               }
+               if ptr.Op() == ir.OADDR {
+                       v.budget += 1 // undo half of default cost of ir.ODEREF+ir.OADDR
+               }
+
+       case ir.OCONVNOP:
+               // This doesn't produce code, but the children might.
+               v.budget++ // undo default cost
+
        case ir.ODCLCONST, ir.OFALL:
                // These nodes don't produce code; omit from inlining budget.
                return false
index 37965c0d9dc8aa45ca0f2127f1adc38eb532d19c..a79f5589fb3a77e4fd42e26199391e2c941adb5a 100644 (file)
@@ -10,6 +10,7 @@
 package foo
 
 import (
+       "math"
        "runtime"
        "unsafe"
 )
@@ -262,3 +263,25 @@ func gd2() int { // ERROR "can inline gd2"
 func gd3() func() { // ERROR "can inline gd3"
        return ii
 }
+
+// Issue #42788 - ensure ODEREF OCONVNOP* OADDR is low cost.
+func EncodeQuad(d []uint32, x [6]float32) { // ERROR "can inline EncodeQuad" "d does not escape"
+       _ = d[:6]
+       d[0] = math.Float32bits(x[0]) // ERROR "inlining call to math.Float32bits"
+       d[1] = math.Float32bits(x[1]) // ERROR "inlining call to math.Float32bits"
+       d[2] = math.Float32bits(x[2]) // ERROR "inlining call to math.Float32bits"
+       d[3] = math.Float32bits(x[3]) // ERROR "inlining call to math.Float32bits"
+       d[4] = math.Float32bits(x[4]) // ERROR "inlining call to math.Float32bits"
+       d[5] = math.Float32bits(x[5]) // ERROR "inlining call to math.Float32bits"
+}
+
+// Ensure OCONVNOP is zero cost.
+func Conv(v uint64) uint64 { // ERROR "can inline Conv"
+       return conv2(conv2(conv2(v))) // ERROR "inlining call to (conv1|conv2)"
+}
+func conv2(v uint64) uint64 { // ERROR "can inline conv2"
+       return conv1(conv1(conv1(conv1(v)))) // ERROR "inlining call to conv1"
+}
+func conv1(v uint64) uint64 { // ERROR "can inline conv1"
+       return uint64(uint64(uint64(uint64(uint64(uint64(uint64(uint64(uint64(uint64(uint64(v)))))))))))
+}