github.com/yukk001/go1.10.8@v0.0.0-20190813125351-6df2d3982e20/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  const (
     8  	wordBits  = 32
     9  	wordMask  = wordBits - 1
    10  	wordShift = 5
    11  )
    12  
    13  // A bvec is a bit vector.
    14  type bvec struct {
    15  	n int32    // number of bits in vector
    16  	b []uint32 // words holding bits
    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  // bvnext returns the smallest index >= i for which bvget(bv, i) == 1.
    90  // If there is no such index, bvnext returns -1.
    91  func (bv bvec) Next(i int32) int32 {
    92  	if i >= bv.n {
    93  		return -1
    94  	}
    95  
    96  	// Jump i ahead to next word with bits.
    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  	// Find 1 bit.
   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  func (bv bvec) IsEmpty() bool {
   121  	for i := int32(0); i < bv.n; i += wordBits {
   122  		if bv.b[i>>wordShift] != 0 {
   123  			return false
   124  		}
   125  	}
   126  	return true
   127  }
   128  
   129  func (bv bvec) Not() {
   130  	i := int32(0)
   131  	w := int32(0)
   132  	for ; i < bv.n; i, w = i+wordBits, w+1 {
   133  		bv.b[w] = ^bv.b[w]
   134  	}
   135  }
   136  
   137  // union
   138  func (dst bvec) Or(src1, src2 bvec) {
   139  	for i, x := range src1.b {
   140  		dst.b[i] = x | src2.b[i]
   141  	}
   142  }
   143  
   144  // intersection
   145  func (dst bvec) And(src1, src2 bvec) {
   146  	for i, x := range src1.b {
   147  		dst.b[i] = x & src2.b[i]
   148  	}
   149  }
   150  
   151  // difference
   152  func (dst bvec) AndNot(src1, src2 bvec) {
   153  	for i, x := range src1.b {
   154  		dst.b[i] = x &^ src2.b[i]
   155  	}
   156  }
   157  
   158  func (bv bvec) String() string {
   159  	s := make([]byte, 2+bv.n)
   160  	copy(s, "#*")
   161  	for i := int32(0); i < bv.n; i++ {
   162  		ch := byte('0')
   163  		if bv.Get(i) {
   164  			ch = '1'
   165  		}
   166  		s[2+i] = ch
   167  	}
   168  	return string(s)
   169  }
   170  
   171  func (bv bvec) Clear() {
   172  	for i := range bv.b {
   173  		bv.b[i] = 0
   174  	}
   175  }