github.com/mh-cbon/go@v0.0.0-20160603070303-9e112a3fe4c0/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 import "fmt" 8 9 const ( 10 WORDBITS = 32 11 WORDMASK = WORDBITS - 1 12 WORDSHIFT = 5 13 ) 14 15 // A bvec is a bit vector. 16 type bvec struct { 17 n int32 // number of bits in vector 18 b []uint32 // words holding bits 19 } 20 21 func bvalloc(n int32) bvec { 22 nword := (n + WORDBITS - 1) / WORDBITS 23 return bvec{n, make([]uint32, nword)} 24 } 25 26 type bulkBvec struct { 27 words []uint32 28 nbit int32 29 nword int32 30 } 31 32 func bvbulkalloc(nbit int32, count int32) bulkBvec { 33 nword := (nbit + WORDBITS - 1) / WORDBITS 34 return bulkBvec{ 35 words: make([]uint32, nword*count), 36 nbit: nbit, 37 nword: nword, 38 } 39 } 40 41 func (b *bulkBvec) next() bvec { 42 out := bvec{b.nbit, b.words[:b.nword]} 43 b.words = b.words[b.nword:] 44 return out 45 } 46 47 // difference 48 func bvandnot(dst bvec, src1 bvec, src2 bvec) { 49 for i, x := range src1.b { 50 dst.b[i] = x &^ src2.b[i] 51 } 52 } 53 54 func bveq(bv1 bvec, bv2 bvec) bool { 55 if bv1.n != bv2.n { 56 Fatalf("bvequal: lengths %d and %d are not equal", bv1.n, bv2.n) 57 } 58 for i, x := range bv1.b { 59 if x != bv2.b[i] { 60 return false 61 } 62 } 63 return true 64 } 65 66 func bvcopy(dst bvec, src bvec) { 67 for i, x := range src.b { 68 dst.b[i] = x 69 } 70 } 71 72 func bvget(bv bvec, i int32) int { 73 if i < 0 || i >= bv.n { 74 Fatalf("bvget: index %d is out of bounds with length %d\n", i, bv.n) 75 } 76 return int((bv.b[i>>WORDSHIFT] >> uint(i&WORDMASK)) & 1) 77 } 78 79 // bvnext returns the smallest index >= i for which bvget(bv, i) == 1. 80 // If there is no such index, bvnext returns -1. 81 func bvnext(bv bvec, i int32) int32 { 82 if i >= bv.n { 83 return -1 84 } 85 86 // Jump i ahead to next word with bits. 87 if bv.b[i>>WORDSHIFT]>>uint(i&WORDMASK) == 0 { 88 i &^= WORDMASK 89 i += WORDBITS 90 for i < bv.n && bv.b[i>>WORDSHIFT] == 0 { 91 i += WORDBITS 92 } 93 } 94 95 if i >= bv.n { 96 return -1 97 } 98 99 // Find 1 bit. 100 w := bv.b[i>>WORDSHIFT] >> uint(i&WORDMASK) 101 102 for w&1 == 0 { 103 w >>= 1 104 i++ 105 } 106 107 return i 108 } 109 110 func bvisempty(bv bvec) bool { 111 for i := int32(0); i < bv.n; i += WORDBITS { 112 if bv.b[i>>WORDSHIFT] != 0 { 113 return false 114 } 115 } 116 return true 117 } 118 119 func bvnot(bv bvec) { 120 i := int32(0) 121 w := int32(0) 122 for ; i < bv.n; i, w = i+WORDBITS, w+1 { 123 bv.b[w] = ^bv.b[w] 124 } 125 } 126 127 // union 128 func bvor(dst bvec, src1 bvec, src2 bvec) { 129 for i, x := range src1.b { 130 dst.b[i] = x | src2.b[i] 131 } 132 } 133 134 // intersection 135 func bvand(dst bvec, src1 bvec, src2 bvec) { 136 for i, x := range src1.b { 137 dst.b[i] = x & src2.b[i] 138 } 139 } 140 141 func bvprint(bv bvec) { 142 fmt.Printf("#*") 143 for i := int32(0); i < bv.n; i++ { 144 fmt.Printf("%d", bvget(bv, i)) 145 } 146 } 147 148 func bvresetall(bv bvec) { 149 for i := range bv.b { 150 bv.b[i] = 0 151 } 152 } 153 154 func bvset(bv bvec, i int32) { 155 if i < 0 || i >= bv.n { 156 Fatalf("bvset: index %d is out of bounds with length %d\n", i, bv.n) 157 } 158 mask := uint32(1 << uint(i%WORDBITS)) 159 bv.b[i/WORDBITS] |= mask 160 }