Home | History | Annotate | Download | only in gc
      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 	WORDSIZE  = 4
     11 	WORDBITS  = 32
     12 	WORDMASK  = WORDBITS - 1
     13 	WORDSHIFT = 5
     14 )
     15 
     16 // A Bvec is a bit vector.
     17 type Bvec struct {
     18 	n int32    // number of bits in vector
     19 	b []uint32 // words holding bits
     20 }
     21 
     22 func bvsize(n uint32) uint32 {
     23 	return ((n + WORDBITS - 1) / WORDBITS) * WORDSIZE
     24 }
     25 
     26 func bvbits(bv Bvec) int32 {
     27 	return bv.n
     28 }
     29 
     30 func bvwords(bv Bvec) int32 {
     31 	return (bv.n + WORDBITS - 1) / WORDBITS
     32 }
     33 
     34 func bvalloc(n int32) Bvec {
     35 	return Bvec{n, make([]uint32, bvsize(uint32(n))/4)}
     36 }
     37 
     38 type bulkBvec struct {
     39 	words []uint32
     40 	nbit  int32
     41 	nword int32
     42 }
     43 
     44 func 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 
     53 func (b *bulkBvec) next() Bvec {
     54 	out := Bvec{b.nbit, b.words[:b.nword]}
     55 	b.words = b.words[b.nword:]
     56 	return out
     57 }
     58 
     59 /* difference */
     60 func bvandnot(dst Bvec, src1 Bvec, src2 Bvec) {
     61 	for i, x := range src1.b {
     62 		dst.b[i] = x &^ src2.b[i]
     63 	}
     64 }
     65 
     66 func bvcmp(bv1 Bvec, bv2 Bvec) int {
     67 	if bv1.n != bv2.n {
     68 		Fatal("bvequal: lengths %d and %d are not equal", bv1.n, bv2.n)
     69 	}
     70 	for i, x := range bv1.b {
     71 		if x != bv2.b[i] {
     72 			return 1
     73 		}
     74 	}
     75 	return 0
     76 }
     77 
     78 func bvcopy(dst Bvec, src Bvec) {
     79 	for i, x := range src.b {
     80 		dst.b[i] = x
     81 	}
     82 }
     83 
     84 func bvconcat(src1 Bvec, src2 Bvec) Bvec {
     85 	dst := bvalloc(src1.n + src2.n)
     86 	for i := int32(0); i < src1.n; i++ {
     87 		if bvget(src1, i) != 0 {
     88 			bvset(dst, i)
     89 		}
     90 	}
     91 	for i := int32(0); i < src2.n; i++ {
     92 		if bvget(src2, i) != 0 {
     93 			bvset(dst, i+src1.n)
     94 		}
     95 	}
     96 	return dst
     97 }
     98 
     99 func bvget(bv Bvec, i int32) int {
    100 	if i < 0 || i >= bv.n {
    101 		Fatal("bvget: index %d is out of bounds with length %d\n", i, bv.n)
    102 	}
    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.
    108 func bvnext(bv Bvec, i int32) int {
    109 	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.
    127 	w := bv.b[i>>WORDSHIFT] >> uint(i&WORDMASK)
    128 
    129 	for w&1 == 0 {
    130 		w >>= 1
    131 		i++
    132 	}
    133 
    134 	return int(i)
    135 }
    136 
    137 func bvisempty(bv Bvec) bool {
    138 	for i := int32(0); i < bv.n; i += WORDBITS {
    139 		if bv.b[i>>WORDSHIFT] != 0 {
    140 			return false
    141 		}
    142 	}
    143 	return true
    144 }
    145 
    146 func bvnot(bv Bvec) {
    147 	i := int32(0)
    148 	w := int32(0)
    149 	for ; i < bv.n; i, w = i+WORDBITS, w+1 {
    150 		bv.b[w] = ^bv.b[w]
    151 	}
    152 }
    153 
    154 /* union */
    155 func bvor(dst Bvec, src1 Bvec, src2 Bvec) {
    156 	for i, x := range src1.b {
    157 		dst.b[i] = x | src2.b[i]
    158 	}
    159 }
    160 
    161 /* intersection */
    162 func bvand(dst Bvec, src1 Bvec, src2 Bvec) {
    163 	for i, x := range src1.b {
    164 		dst.b[i] = x & src2.b[i]
    165 	}
    166 }
    167 
    168 func bvprint(bv Bvec) {
    169 	fmt.Printf("#*")
    170 	for i := int32(0); i < bv.n; i++ {
    171 		fmt.Printf("%d", bvget(bv, i))
    172 	}
    173 }
    174 
    175 func bvreset(bv Bvec, i int32) {
    176 	if i < 0 || i >= bv.n {
    177 		Fatal("bvreset: index %d is out of bounds with length %d\n", i, bv.n)
    178 	}
    179 	mask := uint32(^(1 << uint(i%WORDBITS)))
    180 	bv.b[i/WORDBITS] &= mask
    181 }
    182 
    183 func bvresetall(bv Bvec) {
    184 	for i := range bv.b {
    185 		bv.b[i] = 0
    186 	}
    187 }
    188 
    189 func bvset(bv Bvec, i int32) {
    190 	if i < 0 || i >= bv.n {
    191 		Fatal("bvset: index %d is out of bounds with length %d\n", i, bv.n)
    192 	}
    193 	mask := uint32(1 << uint(i%WORDBITS))
    194 	bv.b[i/WORDBITS] |= mask
    195 }
    196