]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: use intrinsic for LeadingZeros8 on amd64
authorJosh Bleecher Snyder <josharian@gmail.com>
Mon, 23 Apr 2018 22:38:50 +0000 (15:38 -0700)
committerJosh Bleecher Snyder <josharian@gmail.com>
Wed, 25 Apr 2018 21:34:15 +0000 (21:34 +0000)
The previous change sped up the pure computation form of LeadingZeros8.
This places it somewhat close to the table lookup form.
Depending on something that varies from toolchain to toolchain
(alignment, perhaps?), the slowdown from ditching the table lookup
is either 20% or 5%.

This benchmark is the best case scenario for the table lookup:
It is in the L1 cache already.

I think we're close enough that we can switch to the computational version,
and trust that the memory effects and binary size savings will be worth it.

Code:

func f8(x uint8)   { z = bits.LeadingZeros8(x) }

Before:

"".f8 STEXT nosplit size=34 args=0x8 locals=0x0
0x0000 00000 (x.go:7) TEXT "".f8(SB), NOSPLIT, $0-8
0x0000 00000 (x.go:7) FUNCDATA $0, gclocals·2a5305abe05176240e61b8620e19a815(SB)
0x0000 00000 (x.go:7) FUNCDATA $1, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB)
0x0000 00000 (x.go:7) MOVBLZX "".x+8(SP), AX
0x0005 00005 (x.go:7) MOVBLZX AL, AX
0x0008 00008 (x.go:7) LEAQ math/bits.len8tab(SB), CX
0x000f 00015 (x.go:7) MOVBLZX (CX)(AX*1), AX
0x0013 00019 (x.go:7) ADDQ $-8, AX
0x0017 00023 (x.go:7) NEGQ AX
0x001a 00026 (x.go:7) MOVQ AX, "".z(SB)
0x0021 00033 (x.go:7) RET

After:

"".f8 STEXT nosplit size=30 args=0x8 locals=0x0
0x0000 00000 (x.go:7) TEXT "".f8(SB), NOSPLIT, $0-8
0x0000 00000 (x.go:7) FUNCDATA $0, gclocals·2a5305abe05176240e61b8620e19a815(SB)
0x0000 00000 (x.go:7) FUNCDATA $1, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB)
0x0000 00000 (x.go:7) MOVBLZX "".x+8(SP), AX
0x0005 00005 (x.go:7) MOVBLZX AL, AX
0x0008 00008 (x.go:7) LEAL 1(AX)(AX*1), AX
0x000c 00012 (x.go:7) BSRL AX, AX
0x000f 00015 (x.go:7) ADDQ $-8, AX
0x0013 00019 (x.go:7) NEGQ AX
0x0016 00022 (x.go:7) MOVQ AX, "".z(SB)
0x001d 00029 (x.go:7) RET

Change-Id: Icc7db50a7820fb9a3da8a816d6b6940d7f8e193e
Reviewed-on: https://go-review.googlesource.com/108942
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
src/cmd/compile/internal/gc/ssa.go
test/codegen/mathbits.go

index c0d58f76d44210ff9355d05d0cd8c1f9675f42a5..b286470e2d13bf0f8590d8ba40c93972f880c9fd 100644 (file)
@@ -3163,12 +3163,11 @@ func init() {
                        return s.newValue1(ssa.OpBitLen64, types.Types[TINT], x)
                },
                sys.ARM64, sys.ARM, sys.S390X, sys.MIPS, sys.PPC64)
-       // Note: disabled on AMD64 because the Go code is faster!
-       // addF("math/bits", "Len8",
-       //      func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-       //              return s.newValue1(ssa.OpBitLen8, types.Types[TINT], args[0])
-       //      },
-       //      sys.AMD64)
+       addF("math/bits", "Len8",
+               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
+                       return s.newValue1(ssa.OpBitLen8, types.Types[TINT], args[0])
+               },
+               sys.AMD64)
        addF("math/bits", "Len",
                func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
                        if s.config.PtrSize == 4 {
index 39f46c70c89202f30278f90cc5259faef4ff2e30..55a2c943f66c267f67d31ed13ea777cfee5f837d 100644 (file)
@@ -45,7 +45,7 @@ func LeadingZeros16(n uint16) int {
 }
 
 func LeadingZeros8(n uint8) int {
-       // amd64 LeadingZeros8 not intrinsified (see ssa.go)
+       // amd64:"BSRL","LEAL",-"CMOVQEQ"
        // s390x:"FLOGR"
        // arm:"CLZ" arm64:"CLZ"
        // mips:"CLZ"
@@ -89,7 +89,7 @@ func Len16(n uint16) int {
 }
 
 func Len8(n uint8) int {
-       // amd64 Len8 not intrisified (see ssa.go)
+       // amd64:"BSRL","LEAL",-"CMOVQEQ"
        // s390x:"FLOGR"
        // arm:"CLZ" arm64:"CLZ"
        // mips:"CLZ"