...
Source file src/pkg/cmd/compile/internal/gc/bv.go
1
2
3
4
5 package gc
6
7 const (
8 wordBits = 32
9 wordMask = wordBits - 1
10 wordShift = 5
11 )
12
13
14 type bvec struct {
15 n int32
16 b []uint32
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
90
91 func (bv bvec) Next(i int32) int32 {
92 if i >= bv.n {
93 return -1
94 }
95
96
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
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
121
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
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]
156
157 for i, x := range src1.b {
158 dst.b[i] = x | src2.b[i]
159 }
160 }
161
162
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]
168
169 for i, x := range src1.b {
170 dst.b[i] = x & src2.b[i]
171 }
172 }
173
174
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]
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
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
225 type bvecSet struct {
226 index []int
227 uniq []bvec
228 }
229
230 func (m *bvecSet) grow() {
231
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
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
260
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
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
279 return j
280 }
281
282 h++
283 if h == uint32(len(index)) {
284 h = 0
285 }
286 }
287 }
288
289
290
291 func (m *bvecSet) extractUniqe() []bvec {
292 return m.uniq
293 }
294
View as plain text