github.com/zxy12/go_duplicate_112_new@v0.0.0-20200807091221-747231827200/src/cmd/compile/internal/gc/bv.go (about) 1 // Copyright 2013 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package gc 6 7 const ( 8 wordBits = 32 9 wordMask = wordBits - 1 10 wordShift = 5 11 ) 12 13 // A bvec is a bit vector. 14 type bvec struct { 15 n int32 // number of bits in vector 16 b []uint32 // words holding bits 17 } 18 19 func bvalloc(n int32) bvec { 20 nword := (n + wordBits - 1) / wordBits 21 return bvec{n, make([]uint32, nword)} 22 } 23 24 type bulkBvec struct { 25 words []uint32 26 nbit int32 27 nword int32 28 } 29 30 func bvbulkalloc(nbit int32, count int32) bulkBvec { 31 nword := (nbit + wordBits - 1) / wordBits 32 size := int64(nword) * int64(count) 33 if int64(int32(size*4)) != size*4 { 34 Fatalf("bvbulkalloc too big: nbit=%d count=%d nword=%d size=%d", nbit, count, nword, size) 35 } 36 return bulkBvec{ 37 words: make([]uint32, size), 38 nbit: nbit, 39 nword: nword, 40 } 41 } 42 43 func (b *bulkBvec) next() bvec { 44 out := bvec{b.nbit, b.words[:b.nword]} 45 b.words = b.words[b.nword:] 46 return out 47 } 48 49 func (bv1 bvec) Eq(bv2 bvec) bool { 50 if bv1.n != bv2.n { 51 Fatalf("bvequal: lengths %d and %d are not equal", bv1.n, bv2.n) 52 } 53 for i, x := range bv1.b { 54 if x != bv2.b[i] { 55 return false 56 } 57 } 58 return true 59 } 60 61 func (dst bvec) Copy(src bvec) { 62 copy(dst.b, src.b) 63 } 64 65 func (bv bvec) Get(i int32) bool { 66 if i < 0 || i >= bv.n { 67 Fatalf("bvget: index %d is out of bounds with length %d\n", i, bv.n) 68 } 69 mask := uint32(1 << uint(i%wordBits)) 70 return bv.b[i>>wordShift]&mask != 0 71 } 72 73 func (bv bvec) Set(i int32) { 74 if i < 0 || i >= bv.n { 75 Fatalf("bvset: index %d is out of bounds with length %d\n", i, bv.n) 76 } 77 mask := uint32(1 << uint(i%wordBits)) 78 bv.b[i/wordBits] |= mask 79 } 80 81 func (bv bvec) Unset(i int32) { 82 if i < 0 || i >= bv.n { 83 Fatalf("bvunset: index %d is out of bounds with length %d\n", i, bv.n) 84 } 85 mask := uint32(1 << uint(i%wordBits)) 86 bv.b[i/wordBits] &^= mask 87 } 88 89 // bvnext returns the smallest index >= i for which bvget(bv, i) == 1. 90 // If there is no such index, bvnext returns -1. 91 func (bv bvec) Next(i int32) int32 { 92 if i >= bv.n { 93 return -1 94 } 95 96 // Jump i ahead to next word with bits. 97 if bv.b[i>>wordShift]>>uint(i&wordMask) == 0 { 98 i &^= wordMask 99 i += wordBits 100 for i < bv.n && bv.b[i>>wordShift] == 0 { 101 i += wordBits 102 } 103 } 104 105 if i >= bv.n { 106 return -1 107 } 108 109 // Find 1 bit. 110 w := bv.b[i>>wordShift] >> uint(i&wordMask) 111 112 for w&1 == 0 { 113 w >>= 1 114 i++ 115 } 116 117 return i 118 } 119 120 // Len returns the minimum number of bits required to represent bv. 121 // The result is 0 if no bits are set in bv. 122 func (bv bvec) Len() int32 { 123 for wi := len(bv.b) - 1; wi >= 0; wi-- { 124 if w := bv.b[wi]; w != 0 { 125 for i := wordBits - 1; i >= 0; i-- { 126 if w>>uint(i) != 0 { 127 return int32(wi)*wordBits + int32(i) + 1 128 } 129 } 130 } 131 } 132 return 0 133 } 134 135 func (bv bvec) IsEmpty() bool { 136 for _, x := range bv.b { 137 if x != 0 { 138 return false 139 } 140 } 141 return true 142 } 143 144 func (bv bvec) Not() { 145 for i, x := range bv.b { 146 bv.b[i] = ^x 147 } 148 } 149 150 // union 151 func (dst bvec) Or(src1, src2 bvec) { 152 if len(src1.b) == 0 { 153 return 154 } 155 _, _ = dst.b[len(src1.b)-1], src2.b[len(src1.b)-1] // hoist bounds checks out of the loop 156 157 for i, x := range src1.b { 158 dst.b[i] = x | src2.b[i] 159 } 160 } 161 162 // intersection 163 func (dst bvec) And(src1, src2 bvec) { 164 if len(src1.b) == 0 { 165 return 166 } 167 _, _ = dst.b[len(src1.b)-1], src2.b[len(src1.b)-1] // hoist bounds checks out of the loop 168 169 for i, x := range src1.b { 170 dst.b[i] = x & src2.b[i] 171 } 172 } 173 174 // difference 175 func (dst bvec) AndNot(src1, src2 bvec) { 176 if len(src1.b) == 0 { 177 return 178 } 179 _, _ = dst.b[len(src1.b)-1], src2.b[len(src1.b)-1] // hoist bounds checks out of the loop 180 181 for i, x := range src1.b { 182 dst.b[i] = x &^ src2.b[i] 183 } 184 } 185 186 func (bv bvec) String() string { 187 s := make([]byte, 2+bv.n) 188 copy(s, "#*") 189 for i := int32(0); i < bv.n; i++ { 190 ch := byte('0') 191 if bv.Get(i) { 192 ch = '1' 193 } 194 s[2+i] = ch 195 } 196 return string(s) 197 } 198 199 func (bv bvec) Clear() { 200 for i := range bv.b { 201 bv.b[i] = 0 202 } 203 } 204 205 // FNV-1 hash function constants. 206 const ( 207 H0 = 2166136261 208 Hp = 16777619 209 ) 210 211 func hashbitmap(h uint32, bv bvec) uint32 { 212 n := int((bv.n + 31) / 32) 213 for i := 0; i < n; i++ { 214 w := bv.b[i] 215 h = (h * Hp) ^ (w & 0xff) 216 h = (h * Hp) ^ ((w >> 8) & 0xff) 217 h = (h * Hp) ^ ((w >> 16) & 0xff) 218 h = (h * Hp) ^ ((w >> 24) & 0xff) 219 } 220 221 return h 222 } 223 224 // bvecSet is a set of bvecs, in initial insertion order. 225 type bvecSet struct { 226 index []int // hash -> uniq index. -1 indicates empty slot. 227 uniq []bvec // unique bvecs, in insertion order 228 } 229 230 func (m *bvecSet) grow() { 231 // Allocate new index. 232 n := len(m.index) * 2 233 if n == 0 { 234 n = 32 235 } 236 newIndex := make([]int, n) 237 for i := range newIndex { 238 newIndex[i] = -1 239 } 240 241 // Rehash into newIndex. 242 for i, bv := range m.uniq { 243 h := hashbitmap(H0, bv) % uint32(len(newIndex)) 244 for { 245 j := newIndex[h] 246 if j < 0 { 247 newIndex[h] = i 248 break 249 } 250 h++ 251 if h == uint32(len(newIndex)) { 252 h = 0 253 } 254 } 255 } 256 m.index = newIndex 257 } 258 259 // add adds bv to the set and returns its index in m.extractUniqe. 260 // The caller must not modify bv after this. 261 func (m *bvecSet) add(bv bvec) int { 262 if len(m.uniq)*4 >= len(m.index) { 263 m.grow() 264 } 265 266 index := m.index 267 h := hashbitmap(H0, bv) % uint32(len(index)) 268 for { 269 j := index[h] 270 if j < 0 { 271 // New bvec. 272 index[h] = len(m.uniq) 273 m.uniq = append(m.uniq, bv) 274 return len(m.uniq) - 1 275 } 276 jlive := m.uniq[j] 277 if bv.Eq(jlive) { 278 // Existing bvec. 279 return j 280 } 281 282 h++ 283 if h == uint32(len(index)) { 284 h = 0 285 } 286 } 287 } 288 289 // extractUniqe returns this slice of unique bit vectors in m, as 290 // indexed by the result of bvecSet.add. 291 func (m *bvecSet) extractUniqe() []bvec { 292 return m.uniq 293 }