]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: use math/bits functions where possible
authorMichael Munday <mike.munday@ibm.com>
Wed, 16 May 2018 10:21:18 +0000 (11:21 +0100)
committerMichael Munday <mike.munday@ibm.com>
Mon, 21 May 2018 09:20:25 +0000 (09:20 +0000)
Use the math/bits functions to calculate the number of leading/
trailing zeros, bit length and the population count.

The math/bits package is built as part of the bootstrap process
so we do not need to provide an alternative implementation for
Go versions prior to 1.9.

Passes toolstash-check -all.

Change-Id: I393b4cc1c8accd0ca7cb3599d3926fa6319b574f
Reviewed-on: https://go-review.googlesource.com/113336
Run-TryBot: Michael Munday <mike.munday@ibm.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
src/cmd/compile/internal/ssa/bits_bootstrap.go [deleted file]
src/cmd/compile/internal/ssa/bits_go19.go [deleted file]
src/cmd/compile/internal/ssa/debug.go
src/cmd/compile/internal/ssa/rewrite.go

diff --git a/src/cmd/compile/internal/ssa/bits_bootstrap.go b/src/cmd/compile/internal/ssa/bits_bootstrap.go
deleted file mode 100644 (file)
index 060ed5c..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2018 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.
-
-// +build !go1.9
-
-package ssa
-
-const deBruijn64 = 0x03f79d71b4ca8b09
-
-var deBruijn64tab = [64]byte{
-       0, 1, 56, 2, 57, 49, 28, 3, 61, 58, 42, 50, 38, 29, 17, 4,
-       62, 47, 59, 36, 45, 43, 51, 22, 53, 39, 33, 30, 24, 18, 12, 5,
-       63, 55, 48, 27, 60, 41, 37, 16, 46, 35, 44, 21, 52, 32, 23, 11,
-       54, 26, 40, 15, 34, 20, 31, 10, 25, 14, 19, 9, 13, 8, 7, 6,
-}
-
-// TrailingZeros64 returns the number of trailing zero bits in x; the result is 64 for x == 0.
-func TrailingZeros64(x uint64) int {
-       if x == 0 {
-               return 64
-       }
-       return int(deBruijn64tab[(x&-x)*deBruijn64>>(64-6)])
-}
diff --git a/src/cmd/compile/internal/ssa/bits_go19.go b/src/cmd/compile/internal/ssa/bits_go19.go
deleted file mode 100644 (file)
index a131b0a..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2018 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.
-
-// +build go1.9
-
-package ssa
-
-import "math/bits"
-
-func TrailingZeros64(x uint64) int {
-       return bits.TrailingZeros64(x)
-}
index d1d767b0a638b0e699bb998be0a1926a7eec62d7..2c5f25171d0be80318214fe54537591dc4899e13 100644 (file)
@@ -8,6 +8,7 @@ import (
        "cmd/internal/obj"
        "encoding/hex"
        "fmt"
+       "math/bits"
        "sort"
        "strings"
 )
@@ -92,7 +93,7 @@ func (state *stateAtPC) reset(live []liveSlot) {
                        if mask == 0 {
                                break
                        }
-                       reg := uint8(TrailingZeros64(mask))
+                       reg := uint8(bits.TrailingZeros64(mask))
                        mask &^= 1 << reg
 
                        registers[reg] = append(registers[reg], live.slot)
@@ -116,7 +117,7 @@ func (s *debugState) LocString(loc VarLoc) string {
                if mask == 0 {
                        break
                }
-               reg := uint8(TrailingZeros64(mask))
+               reg := uint8(bits.TrailingZeros64(mask))
                mask &^= 1 << reg
 
                storage = append(storage, s.registers[reg].String())
@@ -613,7 +614,7 @@ func (state *debugState) mergePredecessors(b *Block, blockLocs []*BlockDebug) ([
                        if mask == 0 {
                                break
                        }
-                       reg := uint8(TrailingZeros64(mask))
+                       reg := uint8(bits.TrailingZeros64(mask))
                        mask &^= 1 << reg
 
                        state.currentState.registers[reg] = append(state.currentState.registers[reg], predSlot.slot)
@@ -643,7 +644,7 @@ func (state *debugState) processValue(v *Value, vSlots []SlotID, vReg *Register)
                if clobbers == 0 {
                        break
                }
-               reg := uint8(TrailingZeros64(clobbers))
+               reg := uint8(bits.TrailingZeros64(clobbers))
                clobbers &^= 1 << reg
 
                for _, slot := range locs.registers[reg] {
@@ -812,7 +813,7 @@ func firstReg(set RegisterSet) uint8 {
                // produce locations with no storage.
                return 0
        }
-       return uint8(TrailingZeros64(uint64(set)))
+       return uint8(bits.TrailingZeros64(uint64(set)))
 }
 
 // buildLocationLists builds location lists for all the user variables in
index 7cf3144ba916bf621ff6a99f2b9d28d3021efae2..d581160b5fda3fc881b8465c5dc36008868e3f24 100644 (file)
@@ -11,6 +11,7 @@ import (
        "fmt"
        "io"
        "math"
+       "math/bits"
        "os"
        "path/filepath"
 )
@@ -322,17 +323,16 @@ func isSameSym(sym interface{}, name string) bool {
 
 // nlz returns the number of leading zeros.
 func nlz(x int64) int64 {
-       // log2(0) == 1, so nlz(0) == 64
-       return 63 - log2(x)
+       return int64(bits.LeadingZeros64(uint64(x)))
 }
 
 // ntz returns the number of trailing zeros.
 func ntz(x int64) int64 {
-       return 64 - nlz(^x&(x-1))
+       return int64(bits.TrailingZeros64(uint64(x)))
 }
 
 func oneBit(x int64) bool {
-       return nlz(x)+ntz(x) == 63
+       return bits.OnesCount64(uint64(x)) == 1
 }
 
 // nlo returns the number of leading ones.
@@ -347,34 +347,14 @@ func nto(x int64) int64 {
 
 // log2 returns logarithm in base 2 of uint64(n), with log2(0) = -1.
 // Rounds down.
-func log2(n int64) (l int64) {
-       l = -1
-       x := uint64(n)
-       for ; x >= 0x8000; x >>= 16 {
-               l += 16
-       }
-       if x >= 0x80 {
-               x >>= 8
-               l += 8
-       }
-       if x >= 0x8 {
-               x >>= 4
-               l += 4
-       }
-       if x >= 0x2 {
-               x >>= 2
-               l += 2
-       }
-       if x >= 0x1 {
-               l++
-       }
-       return
+func log2(n int64) int64 {
+       return int64(bits.Len64(uint64(n))) - 1
 }
 
 // log2uint32 returns logarithm in base 2 of uint32(n), with log2(0) = -1.
 // Rounds down.
-func log2uint32(n int64) (l int64) {
-       return log2(int64(uint32(n)))
+func log2uint32(n int64) int64 {
+       return int64(bits.Len32(uint32(n))) - 1
 }
 
 // isPowerOfTwo reports whether n is a power of 2.