blob: b40339e4840ced8a011fd80eeacc81fb458443ec [file] [log] [blame]
Russ Cox8c195bd2015-02-13 14:40:36 -05001// 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
5package gc
6
7import "fmt"
8
9const (
10 WORDSIZE = 4
11 WORDBITS = 32
12 WORDMASK = WORDBITS - 1
13 WORDSHIFT = 5
14)
15
Russ Cox01531372015-03-02 21:25:33 -050016// A Bvec is a bit vector.
17type Bvec struct {
18 n int32 // number of bits in vector
19 b []uint32 // words holding bits
20}
21
Russ Cox8c195bd2015-02-13 14:40:36 -050022func bvsize(n uint32) uint32 {
23 return ((n + WORDBITS - 1) / WORDBITS) * WORDSIZE
24}
25
Russ Cox01531372015-03-02 21:25:33 -050026func bvbits(bv Bvec) int32 {
Russ Cox8c195bd2015-02-13 14:40:36 -050027 return bv.n
28}
29
Russ Cox01531372015-03-02 21:25:33 -050030func bvwords(bv Bvec) int32 {
Russ Cox8c195bd2015-02-13 14:40:36 -050031 return (bv.n + WORDBITS - 1) / WORDBITS
32}
33
Russ Cox01531372015-03-02 21:25:33 -050034func bvalloc(n int32) Bvec {
35 return Bvec{n, make([]uint32, bvsize(uint32(n))/4)}
36}
37
38type bulkBvec struct {
39 words []uint32
40 nbit int32
41 nword int32
42}
43
44func bvbulkalloc(nbit int32, count int32) bulkBvec {
45 nword := (nbit + WORDBITS - 1) / WORDBITS
46 return bulkBvec{
47 words: make([]uint32, nword*count),
48 nbit: nbit,
49 nword: nword,
50 }
51}
52
53func (b *bulkBvec) next() Bvec {
54 out := Bvec{b.nbit, b.words[:b.nword]}
55 b.words = b.words[b.nword:]
56 return out
Russ Cox8c195bd2015-02-13 14:40:36 -050057}
58
59/* difference */
Russ Cox01531372015-03-02 21:25:33 -050060func bvandnot(dst Bvec, src1 Bvec, src2 Bvec) {
Russ Coxc8198342015-03-12 18:45:30 -040061 for i, x := range src1.b {
62 dst.b[i] = x &^ src2.b[i]
Russ Cox8c195bd2015-02-13 14:40:36 -050063 }
64}
65
Russ Cox01531372015-03-02 21:25:33 -050066func bvcmp(bv1 Bvec, bv2 Bvec) int {
Russ Cox8c195bd2015-02-13 14:40:36 -050067 if bv1.n != bv2.n {
Håvard Haugen3c9fa382015-08-30 23:10:03 +020068 Fatalf("bvequal: lengths %d and %d are not equal", bv1.n, bv2.n)
Russ Cox8c195bd2015-02-13 14:40:36 -050069 }
70 for i, x := range bv1.b {
71 if x != bv2.b[i] {
72 return 1
73 }
74 }
75 return 0
76}
77
Russ Cox01531372015-03-02 21:25:33 -050078func bvcopy(dst Bvec, src Bvec) {
Russ Cox8c195bd2015-02-13 14:40:36 -050079 for i, x := range src.b {
80 dst.b[i] = x
81 }
82}
83
Russ Cox01531372015-03-02 21:25:33 -050084func bvconcat(src1 Bvec, src2 Bvec) Bvec {
Russ Cox382b44e2015-02-23 16:07:24 -050085 dst := bvalloc(src1.n + src2.n)
86 for i := int32(0); i < src1.n; i++ {
Russ Cox8c195bd2015-02-13 14:40:36 -050087 if bvget(src1, i) != 0 {
88 bvset(dst, i)
89 }
90 }
Russ Cox382b44e2015-02-23 16:07:24 -050091 for i := int32(0); i < src2.n; i++ {
Russ Cox8c195bd2015-02-13 14:40:36 -050092 if bvget(src2, i) != 0 {
93 bvset(dst, i+src1.n)
94 }
95 }
96 return dst
97}
98
Russ Cox01531372015-03-02 21:25:33 -050099func bvget(bv Bvec, i int32) int {
Russ Cox8c195bd2015-02-13 14:40:36 -0500100 if i < 0 || i >= bv.n {
Håvard Haugen3c9fa382015-08-30 23:10:03 +0200101 Fatalf("bvget: index %d is out of bounds with length %d\n", i, bv.n)
Russ Cox8c195bd2015-02-13 14:40:36 -0500102 }
103 return int((bv.b[i>>WORDSHIFT] >> uint(i&WORDMASK)) & 1)
104}
105
106// bvnext returns the smallest index >= i for which bvget(bv, i) == 1.
107// If there is no such index, bvnext returns -1.
Russ Cox01531372015-03-02 21:25:33 -0500108func bvnext(bv Bvec, i int32) int {
Russ Cox8c195bd2015-02-13 14:40:36 -0500109 if i >= bv.n {
110 return -1
111 }
112
113 // Jump i ahead to next word with bits.
114 if bv.b[i>>WORDSHIFT]>>uint(i&WORDMASK) == 0 {
115 i &^= WORDMASK
116 i += WORDBITS
117 for i < bv.n && bv.b[i>>WORDSHIFT] == 0 {
118 i += WORDBITS
119 }
120 }
121
122 if i >= bv.n {
123 return -1
124 }
125
126 // Find 1 bit.
Russ Cox382b44e2015-02-23 16:07:24 -0500127 w := bv.b[i>>WORDSHIFT] >> uint(i&WORDMASK)
Russ Cox8c195bd2015-02-13 14:40:36 -0500128
129 for w&1 == 0 {
130 w >>= 1
131 i++
132 }
133
134 return int(i)
135}
136
Russ Cox01531372015-03-02 21:25:33 -0500137func bvisempty(bv Bvec) bool {
Russ Cox382b44e2015-02-23 16:07:24 -0500138 for i := int32(0); i < bv.n; i += WORDBITS {
Russ Cox8c195bd2015-02-13 14:40:36 -0500139 if bv.b[i>>WORDSHIFT] != 0 {
Russ Coxdc7b54b2015-02-17 22:13:49 -0500140 return false
Russ Cox8c195bd2015-02-13 14:40:36 -0500141 }
142 }
Russ Coxdc7b54b2015-02-17 22:13:49 -0500143 return true
Russ Cox8c195bd2015-02-13 14:40:36 -0500144}
145
Russ Cox01531372015-03-02 21:25:33 -0500146func bvnot(bv Bvec) {
Russ Coxc8198342015-03-12 18:45:30 -0400147 i := int32(0)
148 w := int32(0)
Russ Coxd7f6d462015-03-09 00:31:13 -0400149 for ; i < bv.n; i, w = i+WORDBITS, w+1 {
Russ Cox8c195bd2015-02-13 14:40:36 -0500150 bv.b[w] = ^bv.b[w]
151 }
152}
153
154/* union */
Russ Cox01531372015-03-02 21:25:33 -0500155func bvor(dst Bvec, src1 Bvec, src2 Bvec) {
Russ Coxc8198342015-03-12 18:45:30 -0400156 for i, x := range src1.b {
157 dst.b[i] = x | src2.b[i]
Russ Cox8c195bd2015-02-13 14:40:36 -0500158 }
159}
160
161/* intersection */
Russ Cox01531372015-03-02 21:25:33 -0500162func bvand(dst Bvec, src1 Bvec, src2 Bvec) {
Russ Coxc8198342015-03-12 18:45:30 -0400163 for i, x := range src1.b {
164 dst.b[i] = x & src2.b[i]
Russ Cox8c195bd2015-02-13 14:40:36 -0500165 }
166}
167
Russ Cox01531372015-03-02 21:25:33 -0500168func bvprint(bv Bvec) {
Russ Cox8c195bd2015-02-13 14:40:36 -0500169 fmt.Printf("#*")
Russ Cox382b44e2015-02-23 16:07:24 -0500170 for i := int32(0); i < bv.n; i++ {
Russ Cox8c195bd2015-02-13 14:40:36 -0500171 fmt.Printf("%d", bvget(bv, i))
172 }
173}
174
Russ Cox01531372015-03-02 21:25:33 -0500175func bvreset(bv Bvec, i int32) {
Russ Cox8c195bd2015-02-13 14:40:36 -0500176 if i < 0 || i >= bv.n {
Håvard Haugen3c9fa382015-08-30 23:10:03 +0200177 Fatalf("bvreset: index %d is out of bounds with length %d\n", i, bv.n)
Russ Cox8c195bd2015-02-13 14:40:36 -0500178 }
Russ Cox382b44e2015-02-23 16:07:24 -0500179 mask := uint32(^(1 << uint(i%WORDBITS)))
Russ Cox8c195bd2015-02-13 14:40:36 -0500180 bv.b[i/WORDBITS] &= mask
181}
182
Russ Cox01531372015-03-02 21:25:33 -0500183func bvresetall(bv Bvec) {
Russ Cox8c195bd2015-02-13 14:40:36 -0500184 for i := range bv.b {
185 bv.b[i] = 0
186 }
187}
188
Russ Cox01531372015-03-02 21:25:33 -0500189func bvset(bv Bvec, i int32) {
Russ Cox8c195bd2015-02-13 14:40:36 -0500190 if i < 0 || i >= bv.n {
Håvard Haugen3c9fa382015-08-30 23:10:03 +0200191 Fatalf("bvset: index %d is out of bounds with length %d\n", i, bv.n)
Russ Cox8c195bd2015-02-13 14:40:36 -0500192 }
Russ Cox382b44e2015-02-23 16:07:24 -0500193 mask := uint32(1 << uint(i%WORDBITS))
Russ Cox8c195bd2015-02-13 14:40:36 -0500194 bv.b[i/WORDBITS] |= mask
195}