1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
8 #if defined(_M_AMD64) || defined(_M_X86)
19 #define LOG2_BITS_PER_ELEMENT 5
20 #define LOG2_ELEMENTS_PER_NODE 2
21 #define LOG2_BITS_PER_NODE (LOG2_BITS_PER_ELEMENT + LOG2_ELEMENTS_PER_NODE)
23 #define BITS_PER_ELEMENT (1 << LOG2_BITS_PER_ELEMENT)
24 #define ELEMENTS_PER_NODE (1 << LOG2_ELEMENTS_PER_NODE)
25 #define BITS_PER_NODE (1 << LOG2_BITS_PER_NODE)
28 typedef unsigned __int64 elemType;
29 typedef unsigned __int64 indexType;
31 typedef unsigned int elemType;
32 typedef unsigned int indexType;
38 class hashBvGlobalData;
40 typedef void bitAction(indexType);
41 typedef void nodeAction(hashBvNode*);
42 typedef void dualNodeAction(hashBv* left, hashBv* right, hashBvNode* a, hashBvNode* b);
47 inline void pBit(indexType i)
53 // ------------------------------------------------------------
54 // this is essentially a hashtable of small fixed bitvectors.
55 // for any index, bits select position as follows:
57 // ------------------------------------------------------------
58 // | ... ... ... | hash | element in node | index in element |
59 // ------------------------------------------------------------
65 // []->node->node->node
73 inline int log2(int number)
86 // return greatest power of 2 that is less than or equal
87 inline int nearest_pow2(unsigned number)
124 elemType elements[ELEMENTS_PER_NODE];
127 hashBvNode(indexType base);
131 static hashBvNode* Create(indexType base, Compiler* comp);
132 void Reconstruct(indexType base);
135 return ELEMENTS_PER_NODE;
137 void setBit(indexType base);
138 void setLowest(indexType numToSet);
139 bool getBit(indexType base);
140 void clrBit(indexType base);
142 bool belongsIn(indexType index);
145 void foreachBit(bitAction x);
146 void freeNode(hashBvGlobalData* glob);
147 bool sameAs(hashBvNode* other);
148 void copyFrom(hashBvNode* other);
150 void AndWith(hashBvNode* other);
151 void OrWith(hashBvNode* other);
152 void XorWith(hashBvNode* other);
153 void Subtract(hashBvNode* other);
155 elemType AndWithChange(hashBvNode* other);
156 elemType OrWithChange(hashBvNode* other);
157 elemType XorWithChange(hashBvNode* other);
158 elemType SubtractWithChange(hashBvNode* other);
160 bool Intersects(hashBvNode* other);
170 // --------------------------------------
172 // --------------------------------------
173 hashBvNode** nodeArr;
174 hashBvNode* initialVector[1];
182 unsigned short log2_hashSize;
183 // used for heuristic resizing... could be overflowed in rare circumstances
184 // but should not affect correctness
185 unsigned short numNodes;
188 hashBv(Compiler* comp);
189 hashBv(hashBv* other);
191 static hashBv* Create(Compiler* comp);
192 static void Init(Compiler* comp);
193 static hashBv* CreateFrom(hashBv* other, Compiler* comp);
199 __forceinline int hashtable_size()
201 return 1 << this->log2_hashSize;
204 hashBvGlobalData* globalData();
206 static hashBvNode*& nodeFreeList(hashBvGlobalData* globalData);
207 static hashBv*& hbvFreeList(hashBvGlobalData* data);
209 hashBvNode** getInsertionPointForIndex(indexType index);
212 hashBvNode* getNodeForIndexHelper(indexType index, bool canAdd);
213 int getHashForIndex(indexType index, int table_size);
214 int getRehashForIndex(indexType thisIndex, int thisTableSize, int newTableSize);
216 // maintain free lists for vectors
217 hashBvNode** getNewVector(int vectorLength);
218 void freeVector(hashBvNode* vect, int vectorLength);
221 hashBvNode* getFreeList();
224 inline hashBvNode* getOrAddNodeForIndex(indexType index)
226 hashBvNode* temp = getNodeForIndexHelper(index, true);
229 hashBvNode* getNodeForIndex(indexType index);
230 void removeNodeAtBase(indexType index);
233 void setBit(indexType index);
234 void setAll(indexType numToSet);
235 bool testBit(indexType index);
236 void clearBit(indexType index);
239 void copyFrom(hashBv* other, Compiler* comp);
241 bool CompareWith(hashBv* other);
243 void AndWith(hashBv* other);
244 void OrWith(hashBv* other);
245 void XorWith(hashBv* other);
246 void Subtract(hashBv* other);
247 void Subtract3(hashBv* other, hashBv* other2);
249 void UnionMinus(hashBv* a, hashBv* b, hashBv* c);
251 bool AndWithChange(hashBv* other);
252 bool OrWithChange(hashBv* other);
253 bool OrWithChangeRight(hashBv* other);
254 bool OrWithChangeLeft(hashBv* other);
255 bool XorWithChange(hashBv* other);
256 bool SubtractWithChange(hashBv* other);
258 bool Intersects(hashBv* other);
260 template <class Action>
261 bool MultiTraverseLHSBigger(hashBv* other);
262 template <class Action>
263 bool MultiTraverseRHSBigger(hashBv* other);
264 template <class Action>
265 bool MultiTraverseEqual(hashBv* other);
266 template <class Action>
267 bool MultiTraverse(hashBv* other);
269 void InorderTraverse(nodeAction a);
270 void InorderTraverseTwo(hashBv* other, dualNodeAction a);
272 void Resize(int newSize);
274 void MergeLists(hashBvNode** a, hashBvNode** b);
281 // --------------------------------------------------------------------
282 // --------------------------------------------------------------------
284 class hbvFreeListNode
287 hbvFreeListNode* next;
291 // --------------------------------------------------------------------
292 // --------------------------------------------------------------------
297 unsigned hashtable_size;
298 unsigned hashtable_index;
300 hashBvNode* currNode;
301 indexType current_element;
302 // base index of current node
303 indexType current_base;
304 // working data of current element
305 elemType current_data;
307 hashBvIterator(hashBv* bv);
308 void initFrom(hashBv* bv);
316 class hashBvGlobalData
319 friend class hashBvNode;
321 hashBvNode* hbvNodeFreeList;
323 unsigned short hbvHashSizeLog2;
324 hbvFreeListNode* hbvFreeVectorList;
327 hashBvIterator hashBvNextIterator;
330 indexType HbvNext(hashBv* bv, Compiler* comp);
333 #define FOREACH_HBV_BIT_SET(index, bv) \
335 for (int hashNum=0; hashNum<(bv)->hashtable_size(); hashNum++) {\
336 hashBvNode *node = (bv)->nodeArr[hashNum];\
338 indexType base = node->baseIndex; \
339 for (int el=0; el<node->numElements(); el++) {\
341 elemType _e = node->elements[el]; \
343 int _result = BitScanForwardPtr((DWORD *) &_i, _e); \
345 (index) = base + (el*BITS_PER_ELEMENT) + _i; \
346 _e ^= (elemType(1) << _i);
348 #define NEXT_HBV_BIT_SET \
358 void SimpleDumpNode(hashBvNode *n);
359 void DumpNode(hashBvNode *n);
360 void SimpleDumpDualNode(hashBv *a, hashBv *b, hashBvNode *n, hashBvNode *m);