Makes code simpler and faster (at least on x86).
name old time/op new time/op delta
CountRegs-8 7.40ns ± 1% 0.59ns ± 0% -92.02% (p=0.000 n=9+9)
PickReg/(1<<0)-8 2.07ns ± 0% 0.37ns ± 0% -82.13% (p=0.000 n=9+10)
PickReg/(1<<16)-8 11.8ns ± 0% 0.4ns ± 0% -96.86% (p=0.002 n=8+10)
Change-Id: Ic780b615b75c25b6e7632a0de93b16a8e9ed0f8f
Reviewed-on: https://go-review.googlesource.com/120318
Run-TryBot: Iskander Sharipov <iskander.sharipov@intel.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
"cmd/internal/src"
"cmd/internal/sys"
"fmt"
+ "math/bits"
"unsafe"
)
// countRegs returns the number of set bits in the register mask.
func countRegs(r regMask) int {
- n := 0
- for r != 0 {
- n += int(r & 1)
- r >>= 1
- }
- return n
+ return bits.OnesCount64(uint64(r))
}
// pickReg picks an arbitrary register from the register mask.
func pickReg(r regMask) register {
- // pick the lowest one
if r == 0 {
panic("can't pick a register from an empty set")
}
- for i := register(0); ; i++ {
- if r&1 != 0 {
- return i
- }
- r >>= 1
- }
+ // pick the lowest one
+ return register(bits.TrailingZeros64(uint64(r)))
}
type use struct {