From: Michael Munday Date: Wed, 16 May 2018 10:21:18 +0000 (+0100) Subject: cmd/compile: use math/bits functions where possible X-Git-Tag: go1.11beta1~390 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=5654114d04291be151ff1b1dda09d5b96e0601fa;p=gostls13.git cmd/compile: use math/bits functions where possible 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 TryBot-Result: Gobot Gobot Reviewed-by: Brad Fitzpatrick --- diff --git a/src/cmd/compile/internal/ssa/bits_bootstrap.go b/src/cmd/compile/internal/ssa/bits_bootstrap.go deleted file mode 100644 index 060ed5ca69..0000000000 --- a/src/cmd/compile/internal/ssa/bits_bootstrap.go +++ /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 index a131b0aa42..0000000000 --- a/src/cmd/compile/internal/ssa/bits_go19.go +++ /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) -} diff --git a/src/cmd/compile/internal/ssa/debug.go b/src/cmd/compile/internal/ssa/debug.go index d1d767b0a6..2c5f25171d 100644 --- a/src/cmd/compile/internal/ssa/debug.go +++ b/src/cmd/compile/internal/ssa/debug.go @@ -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 diff --git a/src/cmd/compile/internal/ssa/rewrite.go b/src/cmd/compile/internal/ssa/rewrite.go index 7cf3144ba9..d581160b5f 100644 --- a/src/cmd/compile/internal/ssa/rewrite.go +++ b/src/cmd/compile/internal/ssa/rewrite.go @@ -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.