Bug 1867190 - Add prefs for PHC probablities r=glandium
[gecko.git] / js / src / jit / BitSet.h
blob4e34b1ecb1002669a92f4e977662728db1f63728
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: set ts=8 sts=2 et sw=2 tw=80:
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef jit_BitSet_h
8 #define jit_BitSet_h
10 #include "mozilla/Assertions.h"
11 #include "mozilla/MathAlgorithms.h"
13 #include <stddef.h>
14 #include <stdint.h>
16 namespace js {
17 namespace jit {
19 class TempAllocator;
21 // Provides constant time set insertion and removal, and fast linear
22 // set operations such as intersection, difference, and union.
23 // N.B. All set operations must be performed on sets with the same number
24 // of bits.
25 class BitSet {
26 public:
27 static const size_t BitsPerWord = 8 * sizeof(uint32_t);
29 static size_t RawLengthForBits(size_t bits) {
30 return (bits + BitsPerWord - 1) / BitsPerWord;
33 private:
34 uint32_t* bits_;
35 const unsigned int numBits_;
37 static inline uint32_t bitForValue(unsigned int value) {
38 return 1l << uint32_t(value % BitsPerWord);
41 static inline unsigned int wordForValue(unsigned int value) {
42 return value / BitsPerWord;
45 inline unsigned int numWords() const { return RawLengthForBits(numBits_); }
47 BitSet(const BitSet&) = delete;
48 void operator=(const BitSet&) = delete;
50 public:
51 class Iterator;
53 explicit BitSet(unsigned int numBits) : bits_(nullptr), numBits_(numBits) {}
55 [[nodiscard]] bool init(TempAllocator& alloc);
57 unsigned int getNumBits() const { return numBits_; }
59 // O(1): Check if this set contains the given value.
60 bool contains(unsigned int value) const {
61 MOZ_ASSERT(bits_);
62 MOZ_ASSERT(value < numBits_);
64 return !!(bits_[wordForValue(value)] & bitForValue(value));
67 // O(numBits): Check if this set contains any value.
68 bool empty() const;
70 // O(1): Insert the given value into this set.
71 void insert(unsigned int value) {
72 MOZ_ASSERT(bits_);
73 MOZ_ASSERT(value < numBits_);
75 bits_[wordForValue(value)] |= bitForValue(value);
78 // O(numBits): Insert every element of the given set into this set.
79 void insertAll(const BitSet& other);
81 // O(1): Remove the given value from this set.
82 void remove(unsigned int value) {
83 MOZ_ASSERT(bits_);
84 MOZ_ASSERT(value < numBits_);
86 bits_[wordForValue(value)] &= ~bitForValue(value);
89 // O(numBits): Remove the every element of the given set from this set.
90 void removeAll(const BitSet& other);
92 // O(numBits): Intersect this set with the given set.
93 void intersect(const BitSet& other);
95 // O(numBits): Intersect this set with the given set; return whether the
96 // intersection caused the set to change.
97 bool fixedPointIntersect(const BitSet& other);
99 // O(numBits): Does inplace complement of the set.
100 void complement();
102 // O(numBits): Clear this set.
103 void clear();
105 uint32_t* raw() const { return bits_; }
106 size_t rawLength() const { return numWords(); }
109 class BitSet::Iterator {
110 private:
111 BitSet& set_;
112 unsigned index_;
113 unsigned word_;
114 uint32_t value_;
116 void skipEmpty() {
117 // Skip words containing only zeros.
118 unsigned numWords = set_.numWords();
119 const uint32_t* bits = set_.bits_;
120 while (value_ == 0) {
121 word_++;
122 if (word_ == numWords) {
123 return;
126 index_ = word_ * BitSet::BitsPerWord;
127 value_ = bits[word_];
130 // Be careful: the result of CountTrailingZeroes32 is undefined if the
131 // input is 0.
132 int numZeros = mozilla::CountTrailingZeroes32(value_);
133 index_ += numZeros;
134 value_ >>= numZeros;
136 MOZ_ASSERT_IF(index_ < set_.numBits_, set_.contains(index_));
139 public:
140 explicit Iterator(BitSet& set)
141 : set_(set), index_(0), word_(0), value_(set.bits_[0]) {
142 skipEmpty();
145 inline bool more() const { return word_ < set_.numWords(); }
146 explicit operator bool() const { return more(); }
148 inline void operator++() {
149 MOZ_ASSERT(more());
150 MOZ_ASSERT(index_ < set_.numBits_);
152 index_++;
153 value_ >>= 1;
155 skipEmpty();
158 unsigned int operator*() {
159 MOZ_ASSERT(index_ < set_.numBits_);
160 return index_;
164 } // namespace jit
165 } // namespace js
167 #endif /* jit_BitSet_h */