mirror of
https://github.com/golang/go
synced 2024-11-23 23:50:08 -07:00
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 <mike.munday@ibm.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
parent
cc09212f59
commit
5654114d04
@ -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)])
|
||||
}
|
@ -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)
|
||||
}
|
@ -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
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user