1 //===-- evm/function.h - Class to represent a single basic block --*- C++ -*-===//
3 // A basicblock contains nodes, and must end in a terminal instruction node.
4 // Nodes can be instructions, constants. Each node may produce more than one
7 //===----------------------------------------------------------------------===//
9 #ifndef _JITCS_INT_ADT_BITMAP_H_
10 #define _JITCS_INT_ADT_BITMAP_H_
12 #include "jitcs_base.h"
13 #include "jitcs_adt_ref.h"
14 #include "jitcs_int_bitfuncs.h"
15 #include "jitcs_int_power2funcs.h"
16 #include "jitcs_typefuncs.h"
22 void DumpBitmap(IDumper
& o
, const size_t*, size_t);
24 template <unsigned FLAGS
>
26 typedef const size_t CType
;
27 typedef size_t NCType
;
28 static const bool IsConstRef
= (FLAGS
& REF_Const
) != 0;
29 typedef typename
std::conditional
<IsConstRef
, CType
, NCType
>::type WordType
;
30 typedef WordType
* PtrType
;
31 typedef WordType
& RefType
;
33 typedef WordType
* iterator
;
34 typedef WordType
const* const_iterator
;
36 static_assert(sizeof(WordType
) == 4 || sizeof(WordType
) == 8, "surprising size_t size");
38 E_BitsPerWord
= sizeof(WordType
) * 8, // 32 or 64
39 E_Log2OfBitsPerWord
= Log2CT
<E_BitsPerWord
>::Val
, // 5 or 6
40 E_MaskOfBitsPerWord
= (1 << E_Log2OfBitsPerWord
) - 1, // 0x1f or 0x3f
43 struct BitEnumerator
{
46 size_t curpos0
, curbit
;
48 BitEnumerator(const WordType
* p
, size_t n
)
57 BitEnumerator(const BitEnumerator
&) = default;
58 BitEnumerator
& operator =(const BitEnumerator
&) = default;
60 bool isEmpty() const { return curpos0
>= nbits
; }
61 size_t pos() const { return curpos0
+ curbit
; }
62 void next() { ++curbit
; _advance(); }
64 bool operator !() const { return isEmpty(); }
65 size_t operator *() const { assert(!isEmpty()); return pos(); }
66 void operator ++() { assert(!isEmpty()); next(); }
70 _JITCS_DBG_CHECK_(!isEmpty());
71 while (curbit
>= E_BitsPerWord
|| (*ptr
>> curbit
) == 0) {
72 curpos0
+= E_BitsPerWord
;
73 if (isEmpty()) return;
77 curbit
= t0cntnz(*ptr
, curbit
);
82 _Bits() : _ptr(nullptr), _nbits(0) {}
83 _Bits(const _Bits
&) = default;
84 _Bits
& operator = (const _Bits
&) = default;
86 template <unsigned FLAGS2
>
87 _Bits(_Bits
<FLAGS2
> o
) {
88 static_assert((~FLAGS
& FLAGS2
) == 0, "incompatible _Bits flags");
89 //static_assert(std::is_base_of<T, T2>::value, "incompatible _Bits types");
93 _Bits(PtrType o
, size_t n
) {
98 template <unsigned FLAGS2
>
99 _Bits
& operator =(_Bits
<FLAGS2
> o
) {
100 static_assert((~FLAGS
& FLAGS2
) == 0, "incompatible _Bits flags");
105 PtrType
ptr() const { return _ptr
; }
106 size_t bitSize() const { return _nbits
; }
107 size_t wordSize() const { return DivRoundedUpByPowerOf2
<E_BitsPerWord
>(_nbits
); }
109 bool isEmpty() const { return _nbits
== 0; }
110 bool empty() const { return isEmpty(); }
112 bool isValidIndex(size_t r
) const { return r
>= 0 && r
< bitSize(); }
114 iterator
wordBegin() { return ptr(); }
115 iterator
wordEnd() { return ptr() + wordSize(); }
116 const_iterator
wordBegin() const { return wordCBegin(); }
117 const_iterator
wordEnd() const { return wordCEnd(); }
118 const_iterator
wordCBegin() const { return ptr(); }
119 const_iterator
wordCEnd() const { return ptr() + wordSize(); }
121 BitEnumerator
enumBits() const { return BitEnumerator(_ptr
, _nbits
); }
123 size_t getWordNoForIndex(size_t r
) const { return r
>> E_Log2OfBitsPerWord
; }
124 size_t getBitNoForIndex(size_t r
) const { return r
& E_MaskOfBitsPerWord
; }
125 RefType
getWordForIndex(size_t r
) const { return _ptr
[getWordNoForIndex(r
)]; }
126 size_t getBitMaskForIndex(size_t r
) const { return 1 << getBitNoForIndex(r
); }
127 size_t getLastWordBitNo() const { return bitSize() & E_MaskOfBitsPerWord
; }
128 size_t getLastWordShift() const { return E_BitsPerWord
- getLastWordBitNo(); }
129 bool hasIncompleteLastWord() const { return getLastWordBitNo() != 0; }
131 bool test(size_t r
) const {
133 return (getWordForIndex(r
) & getBitMaskForIndex(r
)) != 0;
135 bool operator [](size_t i
) const { return test(i
); }
137 size_t countSetBits() const {
138 size_t n
= wordSize();
140 if (hasIncompleteLastWord()) {
141 sum
+= popcnt(_ptr
[n
- 1] << getLastWordShift());
144 for (size_t i
= 0; i
< n
; ++i
) {
145 sum
+= popcnt(_ptr
[i
]);
149 bool isAllZeroes() const {
150 size_t n
= wordSize();
151 if (hasIncompleteLastWord()) {
152 if ((_ptr
[n
- 1] << getLastWordShift()) != 0) return false;
154 for (size_t i
= 0; i
< n
; ++i
) {
155 if (_ptr
[i
] != 0) return false;
159 bool isAllOnes() const {
160 size_t n
= wordSize();
161 if (hasIncompleteLastWord()) {
162 if (((~_ptr
[n
- 1]) << getLastWordShift()) != 0) return false;
164 for (size_t i
= 0; i
< n
; ++i
) {
165 if ((~_ptr
[i
]) != 0) return false;
169 template <unsigned FLAGS2
>
170 bool isSubsetOf(const _Bits
<FLAGS2
>& p
) const {
171 _checkNotLongerThan(p
);
172 size_t n
= wordSize();
173 if (hasIncompleteLastWord()) {
174 if ((_ptr
[n
- 1] & ~p
._ptr
[n
- 1]) << getLastWordShift()) return false;
177 for (size_t i
= 0; i
< n
; ++i
) {
178 if (_ptr
[i
] & ~p
._ptr
[i
]) return false;
182 template <unsigned FLAGS2
>
183 bool equals(const _Bits
<FLAGS2
>& p
) const {
184 _checkNotLongerThan(p
);
185 //if (bitSize() != p.bitSize()) return false;
186 size_t n
= wordSize();
187 if (hasIncompleteLastWord()) {
188 if ((_ptr
[n
- 1] ^ p
._ptr
[n
- 1]) << getLastWordShift()) return false;
191 for (size_t i
= 0; i
< n
; ++i
) {
192 if (_ptr
[i
] != p
._ptr
[i
]) return false;
197 void mark(size_t r
) {
198 guarantee
<(FLAGS
& REF_Const
) == 0>
199 ("mutation disabled for immutable bitmap views");
201 RefType rw
= getWordForIndex(r
);
202 rw
|= getBitMaskForIndex(r
);
204 void clear(size_t r
) {
205 guarantee
<(FLAGS
& REF_Const
) == 0>
206 ("mutation disabled for immutable bitmap views");
208 RefType rw
= getWordForIndex(r
);
209 rw
&= ~getBitMaskForIndex(r
);
211 bool testAndMark(size_t r
) {
212 guarantee
<(FLAGS
& REF_Const
) == 0>
213 ("mutation disabled for immutable bitmap views");
215 RefType rw
= getWordForIndex(r
);
216 WordType m
= getBitMaskForIndex(r
);
217 bool res
= (rw
& m
) != 0;
221 bool testAndClear(size_t r
) {
222 guarantee
<(FLAGS
& REF_Const
) == 0>
223 ("mutation disabled for immutable bitmap views");
225 RefType rw
= getWordForIndex(r
);
226 WordType m
= getBitMaskForIndex(r
);
227 bool res
= (rw
& m
) != 0;
231 bool testAndComplement(size_t r
) {
232 guarantee
<(FLAGS
& REF_Const
) == 0>
233 ("mutation disabled for immutable bitmap views");
235 RefType rw
= getWordForIndex(r
);
236 WordType m
= getBitMaskForIndex(r
);
237 bool res
= (rw
& m
) != 0;
243 guarantee
<(FLAGS
& REF_Const
) == 0>
244 ("mutation disabled for immutable bitmap views");
245 for (size_t i
= 0, n
= wordSize(); i
< n
; ++i
) {
250 guarantee
<(FLAGS
& REF_Const
) == 0>
251 ("mutation disabled for immutable bitmap views");
252 for (size_t i
= 0, n
= wordSize(); i
< n
; ++i
) {
256 template <unsigned FLAGS2
>
257 void copyFrom(const _Bits
<FLAGS2
>& p
) {
258 _checkNotLongerThan(p
);
259 for (size_t i
= 0, n
= wordSize(); i
< n
; ++i
) {
263 template <unsigned FLAGS2
>
264 void intersectWith(const _Bits
<FLAGS2
>& p
) {
265 _checkNotLongerThan(p
);
266 for (size_t i
= 0, n
= wordSize(); i
< n
; ++i
) {
267 _ptr
[i
] &= p
._ptr
[i
];
270 template <unsigned FLAGS2
>
271 void uniteWith(const _Bits
<FLAGS2
>& p
) {
272 _checkNotLongerThan(p
);
273 for (size_t i
= 0, n
= wordSize(); i
< n
; ++i
) {
274 _ptr
[i
] |= p
._ptr
[i
];
277 template <unsigned FLAGS2
>
278 void setFrom(const _Bits
<FLAGS2
>& p
) {
281 template <unsigned FLAGS2
>
282 void clearFrom(const _Bits
<FLAGS2
>& p
) {
283 _checkNotLongerThan(p
);
284 for (size_t i
= 0, n
= wordSize(); i
< n
; ++i
) {
285 _ptr
[i
] &= ~p
._ptr
[i
];
289 void dump(IDumper
& o
) const { DumpBitmap(o
, _ptr
, _nbits
); }
292 void _checkIndex(size_t r
) const { _JITCS_DBG_CHECK_(isValidIndex(r
)); }
293 template <unsigned FLAGS2
>
294 void _checkNotLongerThan(const _Bits
<FLAGS2
>& bmp
) const {
295 _JITCS_DBG_CHECK_(bitSize() <= bmp
.bitSize());
303 typedef _Bits
<REF_Any
> BitSlice
;
304 typedef _Bits
<REF_Const
> ConstBitSlice
;
307 struct DynBitSlice
: BitSlice
{
308 size_t _short_data
[RoundUpToPowerOf2CT
<N
, E_BitsPerWord
>::Val
];
310 DynBitSlice(size_t nbits
, bool clear
) {
311 size_t n
= DivRoundedUpByPowerOf2
< E_BitsPerWord
>(nbits
);
312 _ptr
= n
<= RoundUpToPowerOf2CT
<N
, E_BitsPerWord
>::Val
? _short_data
: new size_t[n
];
314 if (clear
) clearAll();
317 if (isUsingHeap()) delete[] _ptr
;
319 bool isUsingHeap() const { return _ptr
!= _short_data
; }
323 } // end of jitcs namespace
326 // _JITCS_INT_ADT_BITMAP_H_