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  }