mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
[git-generate] cd src/cmd/compile/internal/gc rf ' # AutoVar is essentially an ssa helper; move it there. mv AutoVar value.go mv value.go cmd/compile/internal/ssa # Export liveness API and unexport non-API. mv LivenessMap Map mv Map.vals Map.Vals mv Map.deferreturn Map.DeferReturn mv livenessShouldTrack ShouldTrack mv onebitwalktype1 SetTypeBits mv allUnsafe IsUnsafe mv liveness Compute mv BlockEffects blockEffects mv Liveness liveness mv liveness _liveness # make room for import mv emitptrargsmap WriteFuncMap mv WriteFuncMap plive.go mv bvset.go plive.go cmd/compile/internal/liveness ' cd ../liveness rf ' mv _liveness liveness ' Change-Id: I3b86e5025bd9d32a7e19f44714fa16be4125059e Reviewed-on: https://go-review.googlesource.com/c/go/+/279311 Trust: Russ Cox <rsc@golang.org> Run-TryBot: Russ Cox <rsc@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
97 lines
1.9 KiB
Go
97 lines
1.9 KiB
Go
// Copyright 2013 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.
|
|
|
|
package liveness
|
|
|
|
import "cmd/compile/internal/bitvec"
|
|
|
|
// FNV-1 hash function constants.
|
|
const (
|
|
h0 = 2166136261
|
|
hp = 16777619
|
|
)
|
|
|
|
// bvecSet is a set of bvecs, in initial insertion order.
|
|
type bvecSet struct {
|
|
index []int // hash -> uniq index. -1 indicates empty slot.
|
|
uniq []bitvec.BitVec // unique bvecs, in insertion order
|
|
}
|
|
|
|
func (m *bvecSet) grow() {
|
|
// Allocate new index.
|
|
n := len(m.index) * 2
|
|
if n == 0 {
|
|
n = 32
|
|
}
|
|
newIndex := make([]int, n)
|
|
for i := range newIndex {
|
|
newIndex[i] = -1
|
|
}
|
|
|
|
// Rehash into newIndex.
|
|
for i, bv := range m.uniq {
|
|
h := hashbitmap(h0, bv) % uint32(len(newIndex))
|
|
for {
|
|
j := newIndex[h]
|
|
if j < 0 {
|
|
newIndex[h] = i
|
|
break
|
|
}
|
|
h++
|
|
if h == uint32(len(newIndex)) {
|
|
h = 0
|
|
}
|
|
}
|
|
}
|
|
m.index = newIndex
|
|
}
|
|
|
|
// add adds bv to the set and returns its index in m.extractUniqe.
|
|
// The caller must not modify bv after this.
|
|
func (m *bvecSet) add(bv bitvec.BitVec) int {
|
|
if len(m.uniq)*4 >= len(m.index) {
|
|
m.grow()
|
|
}
|
|
|
|
index := m.index
|
|
h := hashbitmap(h0, bv) % uint32(len(index))
|
|
for {
|
|
j := index[h]
|
|
if j < 0 {
|
|
// New bvec.
|
|
index[h] = len(m.uniq)
|
|
m.uniq = append(m.uniq, bv)
|
|
return len(m.uniq) - 1
|
|
}
|
|
jlive := m.uniq[j]
|
|
if bv.Eq(jlive) {
|
|
// Existing bvec.
|
|
return j
|
|
}
|
|
|
|
h++
|
|
if h == uint32(len(index)) {
|
|
h = 0
|
|
}
|
|
}
|
|
}
|
|
|
|
// extractUnique returns this slice of unique bit vectors in m, as
|
|
// indexed by the result of bvecSet.add.
|
|
func (m *bvecSet) extractUnique() []bitvec.BitVec {
|
|
return m.uniq
|
|
}
|
|
|
|
func hashbitmap(h uint32, bv bitvec.BitVec) uint32 {
|
|
n := int((bv.N + 31) / 32)
|
|
for i := 0; i < n; i++ {
|
|
w := bv.B[i]
|
|
h = (h * hp) ^ (w & 0xff)
|
|
h = (h * hp) ^ ((w >> 8) & 0xff)
|
|
h = (h * hp) ^ ((w >> 16) & 0xff)
|
|
h = (h * hp) ^ ((w >> 24) & 0xff)
|
|
}
|
|
|
|
return h
|
|
}
|