From 7ac756f74b1a7dfc984152d863b3e3c86f90b2c7 Mon Sep 17 00:00:00 2001 From: Heschi Kreinick Date: Mon, 29 Jan 2018 16:09:11 -0500 Subject: [PATCH] cmd/compile/internal/ssa: use math/bits for register sets Using bits.TrailingZeroes instead of iterating over each bit is a small but easy win for the common case of only one or two registers being set. I copied in the implementation for use with pre-1.9 bootstraps. Change-Id: Ieaa768554d7d5239a5617fbf34f1ee0b32ce1de5 Reviewed-on: https://go-review.googlesource.com/92395 Run-TryBot: Heschi Kreinick TryBot-Result: Gobot Gobot Reviewed-by: David Chase --- .../compile/internal/ssa/bits_bootstrap.go | 24 ++++++ src/cmd/compile/internal/ssa/bits_go19.go | 13 +++ src/cmd/compile/internal/ssa/debug.go | 82 +++++++++++-------- 3 files changed, 85 insertions(+), 34 deletions(-) create mode 100644 src/cmd/compile/internal/ssa/bits_bootstrap.go create mode 100644 src/cmd/compile/internal/ssa/bits_go19.go diff --git a/src/cmd/compile/internal/ssa/bits_bootstrap.go b/src/cmd/compile/internal/ssa/bits_bootstrap.go new file mode 100644 index 0000000000..060ed5ca69 --- /dev/null +++ b/src/cmd/compile/internal/ssa/bits_bootstrap.go @@ -0,0 +1,24 @@ +// 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 new file mode 100644 index 0000000000..a131b0aa42 --- /dev/null +++ b/src/cmd/compile/internal/ssa/bits_go19.go @@ -0,0 +1,13 @@ +// 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 048ff7e230..8a71d725c9 100644 --- a/src/cmd/compile/internal/ssa/debug.go +++ b/src/cmd/compile/internal/ssa/debug.go @@ -70,10 +70,16 @@ func (state *stateAtPC) reset(live []liveSlot) { if live.loc.Registers == 0 { continue } - for reg, regMask := 0, 1; reg < len(registers); reg, regMask = reg+1, regMask<<1 { - if live.loc.Registers&RegisterSet(regMask) != 0 { - registers[reg] = append(registers[reg], SlotID(live.slot)) + + mask := uint64(live.loc.Registers) + for { + if mask == 0 { + break } + reg := uint8(TrailingZeros64(mask)) + mask &^= 1 << reg + + registers[reg] = append(registers[reg], SlotID(live.slot)) } } state.slots, state.registers = slots, registers @@ -90,10 +96,14 @@ func (b *BlockDebug) LocString(loc VarLoc) string { storage = append(storage, "stack") } - for reg := 0; reg < 64; reg++ { - if loc.Registers&(1<