github.com/rsc/tmp@v0.0.0-20240517235954-6deaab19748b/bootstrap/internal/gc/bv.go (about) 1 // Do not edit. Bootstrap copy of /Users/rsc/g/go/src/cmd/internal/gc/bv.go 2 3 // Copyright 2013 The Go Authors. All rights reserved. 4 // Use of this source code is governed by a BSD-style 5 // license that can be found in the LICENSE file. 6 7 package gc 8 9 import "fmt" 10 11 const ( 12 WORDSIZE = 4 13 WORDBITS = 32 14 WORDMASK = WORDBITS - 1 15 WORDSHIFT = 5 16 ) 17 18 // A Bvec is a bit vector. 19 type Bvec struct { 20 n int32 // number of bits in vector 21 b []uint32 // words holding bits 22 } 23 24 func bvsize(n uint32) uint32 { 25 return ((n + WORDBITS - 1) / WORDBITS) * WORDSIZE 26 } 27 28 func bvbits(bv Bvec) int32 { 29 return bv.n 30 } 31 32 func bvwords(bv Bvec) int32 { 33 return (bv.n + WORDBITS - 1) / WORDBITS 34 } 35 36 func bvalloc(n int32) Bvec { 37 return Bvec{n, make([]uint32, bvsize(uint32(n))/4)} 38 } 39 40 type bulkBvec struct { 41 words []uint32 42 nbit int32 43 nword int32 44 } 45 46 func bvbulkalloc(nbit int32, count int32) bulkBvec { 47 nword := (nbit + WORDBITS - 1) / WORDBITS 48 return bulkBvec{ 49 words: make([]uint32, nword*count), 50 nbit: nbit, 51 nword: nword, 52 } 53 } 54 55 func (b *bulkBvec) next() Bvec { 56 out := Bvec{b.nbit, b.words[:b.nword]} 57 b.words = b.words[b.nword:] 58 return out 59 } 60 61 /* difference */ 62 func bvandnot(dst Bvec, src1 Bvec, src2 Bvec) { 63 for i, x := range src1.b { 64 dst.b[i] = x &^ src2.b[i] 65 } 66 } 67 68 func bvcmp(bv1 Bvec, bv2 Bvec) int { 69 if bv1.n != bv2.n { 70 Fatal("bvequal: lengths %d and %d are not equal", bv1.n, bv2.n) 71 } 72 for i, x := range bv1.b { 73 if x != bv2.b[i] { 74 return 1 75 } 76 } 77 return 0 78 } 79 80 func bvcopy(dst Bvec, src Bvec) { 81 for i, x := range src.b { 82 dst.b[i] = x 83 } 84 } 85 86 func bvconcat(src1 Bvec, src2 Bvec) Bvec { 87 dst := bvalloc(src1.n + src2.n) 88 for i := int32(0); i < src1.n; i++ { 89 if bvget(src1, i) != 0 { 90 bvset(dst, i) 91 } 92 } 93 for i := int32(0); i < src2.n; i++ { 94 if bvget(src2, i) != 0 { 95 bvset(dst, i+src1.n) 96 } 97 } 98 return dst 99 } 100 101 func bvget(bv Bvec, i int32) int { 102 if i < 0 || i >= bv.n { 103 Fatal("bvget: index %d is out of bounds with length %d\n", i, bv.n) 104 } 105 return int((bv.b[i>>WORDSHIFT] >> uint(i&WORDMASK)) & 1) 106 } 107 108 // bvnext returns the smallest index >= i for which bvget(bv, i) == 1. 109 // If there is no such index, bvnext returns -1. 110 func bvnext(bv Bvec, i int32) int { 111 if i >= bv.n { 112 return -1 113 } 114 115 // Jump i ahead to next word with bits. 116 if bv.b[i>>WORDSHIFT]>>uint(i&WORDMASK) == 0 { 117 i &^= WORDMASK 118 i += WORDBITS 119 for i < bv.n && bv.b[i>>WORDSHIFT] == 0 { 120 i += WORDBITS 121 } 122 } 123 124 if i >= bv.n { 125 return -1 126 } 127 128 // Find 1 bit. 129 w := bv.b[i>>WORDSHIFT] >> uint(i&WORDMASK) 130 131 for w&1 == 0 { 132 w >>= 1 133 i++ 134 } 135 136 return int(i) 137 } 138 139 func bvisempty(bv Bvec) bool { 140 for i := int32(0); i < bv.n; i += WORDBITS { 141 if bv.b[i>>WORDSHIFT] != 0 { 142 return false 143 } 144 } 145 return true 146 } 147 148 func bvnot(bv Bvec) { 149 i := int32(0) 150 w := int32(0) 151 for ; i < bv.n; i, w = i+WORDBITS, w+1 { 152 bv.b[w] = ^bv.b[w] 153 } 154 } 155 156 /* union */ 157 func bvor(dst Bvec, src1 Bvec, src2 Bvec) { 158 for i, x := range src1.b { 159 dst.b[i] = x | src2.b[i] 160 } 161 } 162 163 /* intersection */ 164 func bvand(dst Bvec, src1 Bvec, src2 Bvec) { 165 for i, x := range src1.b { 166 dst.b[i] = x & src2.b[i] 167 } 168 } 169 170 func bvprint(bv Bvec) { 171 fmt.Printf("#*") 172 for i := int32(0); i < bv.n; i++ { 173 fmt.Printf("%d", bvget(bv, i)) 174 } 175 } 176 177 func bvreset(bv Bvec, i int32) { 178 if i < 0 || i >= bv.n { 179 Fatal("bvreset: index %d is out of bounds with length %d\n", i, bv.n) 180 } 181 mask := uint32(^(1 << uint(i%WORDBITS))) 182 bv.b[i/WORDBITS] &= mask 183 } 184 185 func bvresetall(bv Bvec) { 186 for i := range bv.b { 187 bv.b[i] = 0 188 } 189 } 190 191 func bvset(bv Bvec, i int32) { 192 if i < 0 || i >= bv.n { 193 Fatal("bvset: index %d is out of bounds with length %d\n", i, bv.n) 194 } 195 mask := uint32(1 << uint(i%WORDBITS)) 196 bv.b[i/WORDBITS] |= mask 197 }