Fix reading Time zone rules using Julian days (#17672)
[platform/upstream/coreclr.git] / src / jit / bitsetasshortlong.h
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.
4
5 // A set of integers in the range [0..N], for some N defined by the "Env" (via "BitSetTraits").
6 //
7 // Represented as a pointer-sized item.  If N bits can fit in this item, the representation is "direct"; otherwise,
8 // the item is a pointer to an array of K size_t's, where K is the number of size_t's necessary to hold N bits.
9
10 #ifndef bitSetAsShortLong_DEFINED
11 #define bitSetAsShortLong_DEFINED 1
12
13 #include "bitset.h"
14 #include "compilerbitsettraits.h"
15
16 typedef size_t* BitSetShortLongRep;
17
18 template <typename Env, typename BitSetTraits>
19 class BitSetOps</*BitSetType*/ BitSetShortLongRep,
20                 /*Brand*/ BSShortLong,
21                 /*Env*/ Env,
22                 /*BitSetTraits*/ BitSetTraits>
23 {
24 public:
25     typedef BitSetShortLongRep Rep;
26
27 private:
28     static const unsigned BitsInSizeT = sizeof(size_t) * BitSetSupport::BitsInByte;
29
30     inline static bool IsShort(Env env)
31     {
32         return BitSetTraits::GetArrSize(env, sizeof(size_t)) <= 1;
33     }
34
35     // The operations on the "long" (pointer-to-array-of-size_t) versions of the representation.
36     static void AssignLong(Env env, BitSetShortLongRep& lhs, BitSetShortLongRep rhs);
37     static BitSetShortLongRep MakeSingletonLong(Env env, unsigned bitNum);
38     static BitSetShortLongRep MakeCopyLong(Env env, BitSetShortLongRep bs);
39     static bool IsEmptyLong(Env env, BitSetShortLongRep bs);
40     static unsigned CountLong(Env env, BitSetShortLongRep bs);
41     static bool IsEmptyUnionLong(Env env, BitSetShortLongRep bs1, BitSetShortLongRep bs2);
42     static void UnionDLong(Env env, BitSetShortLongRep& bs1, BitSetShortLongRep bs2);
43     static void DiffDLong(Env env, BitSetShortLongRep& bs1, BitSetShortLongRep bs2);
44     static void AddElemDLong(Env env, BitSetShortLongRep& bs, unsigned i);
45     static bool TryAddElemDLong(Env env, BitSetShortLongRep& bs, unsigned i);
46     static void RemoveElemDLong(Env env, BitSetShortLongRep& bs, unsigned i);
47     static void ClearDLong(Env env, BitSetShortLongRep& bs);
48     static BitSetShortLongRep MakeUninitArrayBits(Env env);
49     static BitSetShortLongRep MakeEmptyArrayBits(Env env);
50     static BitSetShortLongRep MakeFullArrayBits(Env env);
51     static bool IsMemberLong(Env env, BitSetShortLongRep bs, unsigned i);
52     static bool EqualLong(Env env, BitSetShortLongRep bs1, BitSetShortLongRep bs2);
53     static bool IsSubsetLong(Env env, BitSetShortLongRep bs1, BitSetShortLongRep bs2);
54     static bool IsEmptyIntersectionLong(Env env, BitSetShortLongRep bs1, BitSetShortLongRep bs2);
55     static void IntersectionDLong(Env env, BitSetShortLongRep& bs1, BitSetShortLongRep bs2);
56     static void DataFlowDLong(Env                      env,
57                               BitSetShortLongRep&      out,
58                               const BitSetShortLongRep gen,
59                               const BitSetShortLongRep in);
60     static void LivenessDLong(Env                      env,
61                               BitSetShortLongRep&      in,
62                               const BitSetShortLongRep def,
63                               const BitSetShortLongRep use,
64                               const BitSetShortLongRep out);
65 #ifdef DEBUG
66     static const char* ToStringLong(Env env, BitSetShortLongRep bs);
67 #endif
68
69 public:
70     inline static BitSetShortLongRep UninitVal()
71     {
72         return nullptr;
73     }
74
75     static bool MayBeUninit(BitSetShortLongRep bs)
76     {
77         return bs == UninitVal();
78     }
79
80     static void Assign(Env env, BitSetShortLongRep& lhs, BitSetShortLongRep rhs)
81     {
82         // We can't assert that rhs != UninitVal in the Short case, because in that
83         // case it's a legal value.
84         if (IsShort(env))
85         {
86             // Both are short.
87             lhs = rhs;
88         }
89         else if (lhs == UninitVal())
90         {
91             assert(rhs != UninitVal());
92             lhs = MakeCopy(env, rhs);
93         }
94         else
95         {
96             AssignLong(env, lhs, rhs);
97         }
98     }
99
100     static void AssignAllowUninitRhs(Env env, BitSetShortLongRep& lhs, BitSetShortLongRep rhs)
101     {
102         if (IsShort(env))
103         {
104             // Both are short.
105             lhs = rhs;
106         }
107         else if (rhs == UninitVal())
108         {
109             lhs = rhs;
110         }
111         else if (lhs == UninitVal())
112         {
113             lhs = MakeCopy(env, rhs);
114         }
115         else
116         {
117             AssignLong(env, lhs, rhs);
118         }
119     }
120
121     static void AssignNoCopy(Env env, BitSetShortLongRep& lhs, BitSetShortLongRep rhs)
122     {
123         lhs = rhs;
124     }
125
126     static void ClearD(Env env, BitSetShortLongRep& bs)
127     {
128         if (IsShort(env))
129         {
130             bs = (BitSetShortLongRep) nullptr;
131         }
132         else
133         {
134             assert(bs != UninitVal());
135             ClearDLong(env, bs);
136         }
137     }
138
139     static BitSetShortLongRep MakeSingleton(Env env, unsigned bitNum)
140     {
141         assert(bitNum < BitSetTraits::GetSize(env));
142         if (IsShort(env))
143         {
144             return BitSetShortLongRep(((size_t)1) << bitNum);
145         }
146         else
147         {
148             return MakeSingletonLong(env, bitNum);
149         }
150     }
151
152     static BitSetShortLongRep MakeCopy(Env env, BitSetShortLongRep bs)
153     {
154         if (IsShort(env))
155         {
156             return bs;
157         }
158         else
159         {
160             return MakeCopyLong(env, bs);
161         }
162     }
163
164     static bool IsEmpty(Env env, BitSetShortLongRep bs)
165     {
166         if (IsShort(env))
167         {
168             return bs == nullptr;
169         }
170         else
171         {
172             assert(bs != UninitVal());
173             return IsEmptyLong(env, bs);
174         }
175     }
176
177     static unsigned Count(Env env, BitSetShortLongRep bs)
178     {
179         if (IsShort(env))
180         {
181             return BitSetSupport::CountBitsInIntegral(size_t(bs));
182         }
183         else
184         {
185             assert(bs != UninitVal());
186             return CountLong(env, bs);
187         }
188     }
189
190     static bool IsEmptyUnion(Env env, BitSetShortLongRep bs1, BitSetShortLongRep bs2)
191     {
192         if (IsShort(env))
193         {
194             return (((size_t)bs1) | ((size_t)bs2)) == 0;
195         }
196         else
197         {
198             return IsEmptyUnionLong(env, bs1, bs2);
199         }
200     }
201
202     static void UnionD(Env env, BitSetShortLongRep& bs1, BitSetShortLongRep bs2)
203     {
204         if (IsShort(env))
205         {
206             bs1 = (BitSetShortLongRep)(((size_t)bs1) | ((size_t)bs2));
207         }
208         else
209         {
210             UnionDLong(env, bs1, bs2);
211         }
212     }
213     static BitSetShortLongRep Union(Env env, BitSetShortLongRep bs1, BitSetShortLongRep bs2)
214     {
215         BitSetShortLongRep res = MakeCopy(env, bs1);
216         UnionD(env, res, bs2);
217         return res;
218     }
219
220     static void DiffD(Env env, BitSetShortLongRep& bs1, BitSetShortLongRep bs2)
221     {
222         if (IsShort(env))
223         {
224             bs1 = (BitSetShortLongRep)(((size_t)bs1) & (~(size_t)bs2));
225         }
226         else
227         {
228             DiffDLong(env, bs1, bs2);
229         }
230     }
231     static BitSetShortLongRep Diff(Env env, BitSetShortLongRep bs1, BitSetShortLongRep bs2)
232     {
233         BitSetShortLongRep res = MakeCopy(env, bs1);
234         DiffD(env, res, bs2);
235         return res;
236     }
237
238     static void RemoveElemD(Env env, BitSetShortLongRep& bs, unsigned i)
239     {
240         assert(i < BitSetTraits::GetSize(env));
241         if (IsShort(env))
242         {
243             size_t mask = ((size_t)1) << i;
244             mask        = ~mask;
245             bs          = (BitSetShortLongRep)(((size_t)bs) & mask);
246         }
247         else
248         {
249             assert(bs != UninitVal());
250             RemoveElemDLong(env, bs, i);
251         }
252     }
253     static BitSetShortLongRep RemoveElem(Env env, BitSetShortLongRep bs, unsigned i)
254     {
255         BitSetShortLongRep res = MakeCopy(env, bs);
256         RemoveElemD(env, res, i);
257         return res;
258     }
259
260     static void AddElemD(Env env, BitSetShortLongRep& bs, unsigned i)
261     {
262         assert(i < BitSetTraits::GetSize(env));
263         if (IsShort(env))
264         {
265             size_t mask = ((size_t)1) << i;
266             bs          = (BitSetShortLongRep)(((size_t)bs) | mask);
267         }
268         else
269         {
270             AddElemDLong(env, bs, i);
271         }
272     }
273     static BitSetShortLongRep AddElem(Env env, BitSetShortLongRep bs, unsigned i)
274     {
275         BitSetShortLongRep res = MakeCopy(env, bs);
276         AddElemD(env, res, i);
277         return res;
278     }
279
280     static bool TryAddElemD(Env env, BitSetShortLongRep& bs, unsigned i)
281     {
282         assert(i < BitSetTraits::GetSize(env));
283         if (IsShort(env))
284         {
285             size_t mask  = ((size_t)1) << i;
286             size_t bits  = (size_t)bs;
287             bool   added = (bits & mask) == 0;
288             bs           = (BitSetShortLongRep)(bits | mask);
289             return added;
290         }
291         else
292         {
293             return TryAddElemDLong(env, bs, i);
294         }
295     }
296
297     static bool IsMember(Env env, const BitSetShortLongRep bs, unsigned i)
298     {
299         assert(i < BitSetTraits::GetSize(env));
300         if (IsShort(env))
301         {
302             size_t mask = ((size_t)1) << i;
303             return (((size_t)bs) & mask) != 0;
304         }
305         else
306         {
307             assert(bs != UninitVal());
308             return IsMemberLong(env, bs, i);
309         }
310     }
311
312     static void IntersectionD(Env env, BitSetShortLongRep& bs1, BitSetShortLongRep bs2)
313     {
314         if (IsShort(env))
315         {
316             (size_t&)bs1 &= (size_t)bs2;
317         }
318         else
319         {
320             IntersectionDLong(env, bs1, bs2);
321         }
322     }
323
324     static BitSetShortLongRep Intersection(Env env, BitSetShortLongRep bs1, BitSetShortLongRep bs2)
325     {
326         BitSetShortLongRep res = MakeCopy(env, bs1);
327         IntersectionD(env, res, bs2);
328         return res;
329     }
330     static bool IsEmptyIntersection(Env env, BitSetShortLongRep bs1, BitSetShortLongRep bs2)
331     {
332         if (IsShort(env))
333         {
334             return (((size_t)bs1) & ((size_t)bs2)) == 0;
335         }
336         else
337         {
338             return IsEmptyIntersectionLong(env, bs1, bs2);
339         }
340     }
341
342     static void DataFlowD(Env env, BitSetShortLongRep& out, const BitSetShortLongRep gen, const BitSetShortLongRep in)
343     {
344         if (IsShort(env))
345         {
346             (size_t&)out = (size_t)out & ((size_t)gen | (size_t)in);
347         }
348         else
349         {
350             DataFlowDLong(env, out, gen, in);
351         }
352     }
353
354     static void LivenessD(Env                      env,
355                           BitSetShortLongRep&      in,
356                           const BitSetShortLongRep def,
357                           const BitSetShortLongRep use,
358                           const BitSetShortLongRep out)
359     {
360         if (IsShort(env))
361         {
362             (size_t&)in = (size_t)use | ((size_t)out & ~(size_t)def);
363         }
364         else
365         {
366             LivenessDLong(env, in, def, use, out);
367         }
368     }
369
370     static bool IsSubset(Env env, BitSetShortLongRep bs1, BitSetShortLongRep bs2)
371     {
372         if (IsShort(env))
373         {
374             size_t u1 = (size_t)bs1;
375             size_t u2 = (size_t)bs2;
376             return (u1 & u2) == u1;
377         }
378         else
379         {
380             return IsSubsetLong(env, bs1, bs2);
381         }
382     }
383
384     static bool Equal(Env env, BitSetShortLongRep bs1, BitSetShortLongRep bs2)
385     {
386         if (IsShort(env))
387         {
388             return (size_t)bs1 == (size_t)bs2;
389         }
390         else
391         {
392             return EqualLong(env, bs1, bs2);
393         }
394     }
395
396 #ifdef DEBUG
397     // Returns a string valid until the allocator releases the memory.
398     static const char* ToString(Env env, BitSetShortLongRep bs)
399     {
400         if (IsShort(env))
401         {
402             assert(sizeof(BitSetShortLongRep) == sizeof(size_t));
403             const int CharsForSizeT  = sizeof(size_t) * 2;
404             char*     res            = nullptr;
405             const int ShortAllocSize = CharsForSizeT + 4;
406             res                      = (char*)BitSetTraits::DebugAlloc(env, ShortAllocSize);
407             size_t   bits            = (size_t)bs;
408             unsigned remaining       = ShortAllocSize;
409             char*    ptr             = res;
410             if (sizeof(size_t) == sizeof(int64_t))
411             {
412                 sprintf_s(ptr, remaining, "%016llX", bits);
413             }
414             else
415             {
416                 assert(sizeof(size_t) == sizeof(int));
417                 sprintf_s(ptr, remaining, "%08X", bits);
418             }
419             return res;
420         }
421         else
422         {
423             return ToStringLong(env, bs);
424         }
425     }
426 #endif
427
428     static BitSetShortLongRep MakeEmpty(Env env)
429     {
430         if (IsShort(env))
431         {
432             return nullptr;
433         }
434         else
435         {
436             return MakeEmptyArrayBits(env);
437         }
438     }
439
440     static BitSetShortLongRep MakeFull(Env env)
441     {
442         if (IsShort(env))
443         {
444             // Can't just shift by numBits+1, since that might be 32 (and (1 << 32( == 1, for an unsigned).
445             unsigned numBits = BitSetTraits::GetSize(env);
446             if (numBits == BitsInSizeT)
447             {
448                 // Can't use the implementation below to get all 1's...
449                 return BitSetShortLongRep(size_t(-1));
450             }
451             else
452             {
453                 return BitSetShortLongRep((size_t(1) << numBits) - 1);
454             }
455         }
456         else
457         {
458             return MakeFullArrayBits(env);
459         }
460     }
461
462     class Iter
463     {
464         // The BitSet that we're iterating over. This is updated to point at the current
465         // size_t set of bits.
466         BitSetShortLongRep m_bs;
467
468         // The end of the iteration.
469         BitSetShortLongRep m_bsEnd;
470
471         // The remaining bits to be iterated over in the current size_t set of bits.
472         // In the "short" case, these are all the remaining bits.
473         // In the "long" case, these are remaining bits in the current element;
474         // these and the bits in the remaining elements comprise the remaining bits.
475         size_t m_bits;
476
477         // The number of bits that have already been iterated over (set or clear). If you
478         // add this to the bit number of the next bit in "m_bits", you get the proper bit number of that
479         // bit in "m_bs". This is only updated when we increment m_bs.
480         unsigned m_bitNum;
481
482     public:
483         Iter(Env env, const BitSetShortLongRep& bs) : m_bs(bs), m_bitNum(0)
484         {
485             if (BitSetOps::IsShort(env))
486             {
487                 m_bits = (size_t)bs;
488
489                 // Set the iteration end condition, valid even though this is not a pointer in the short case.
490                 m_bsEnd = bs + 1;
491             }
492             else
493             {
494                 assert(bs != BitSetOps::UninitVal());
495                 m_bits = bs[0];
496
497                 unsigned len = BitSetTraits::GetArrSize(env, sizeof(size_t));
498                 m_bsEnd      = bs + len;
499             }
500         }
501
502         bool NextElem(unsigned* pElem)
503         {
504 #if BITSET_TRACK_OPCOUNTS
505             BitSetStaticsImpl::RecordOp(BitSetStaticsImpl::BSOP_NextBit);
506 #endif
507             for (;;)
508             {
509                 DWORD nextBit;
510                 BOOL  hasBit;
511 #ifdef _HOST_64BIT_
512                 static_assert_no_msg(sizeof(size_t) == 8);
513                 hasBit = BitScanForward64(&nextBit, m_bits);
514 #else
515                 static_assert_no_msg(sizeof(size_t) == 4);
516                 hasBit = BitScanForward(&nextBit, m_bits);
517 #endif
518
519                 // If there's a bit, doesn't matter if we're short or long.
520                 if (hasBit)
521                 {
522                     *pElem = m_bitNum + nextBit;
523                     m_bits &= ~(((size_t)1) << nextBit); // clear bit we just found so we don't find it again
524                     return true;
525                 }
526                 else
527                 {
528                     // Go to the next size_t bit element. For short bitsets, this will hit the end condition
529                     // and exit.
530                     ++m_bs;
531                     if (m_bs == m_bsEnd)
532                     {
533                         return false;
534                     }
535
536                     // If we get here, it's not a short type, so get the next size_t element.
537                     m_bitNum += sizeof(size_t) * BitSetSupport::BitsInByte;
538                     m_bits = *m_bs;
539                 }
540             }
541         }
542     };
543
544     typedef const BitSetShortLongRep& ValArgType;
545     typedef BitSetShortLongRep        RetValType;
546 };
547
548 template <typename Env, typename BitSetTraits>
549 void BitSetOps</*BitSetType*/ BitSetShortLongRep,
550                /*Brand*/ BSShortLong,
551                /*Env*/ Env,
552                /*BitSetTraits*/ BitSetTraits>::AssignLong(Env env, BitSetShortLongRep& lhs, BitSetShortLongRep rhs)
553 {
554     assert(!IsShort(env));
555     unsigned len = BitSetTraits::GetArrSize(env, sizeof(size_t));
556     for (unsigned i = 0; i < len; i++)
557     {
558         lhs[i] = rhs[i];
559     }
560 }
561
562 template <typename Env, typename BitSetTraits>
563 BitSetShortLongRep BitSetOps</*BitSetType*/ BitSetShortLongRep,
564                              /*Brand*/ BSShortLong,
565                              /*Env*/ Env,
566                              /*BitSetTraits*/ BitSetTraits>::MakeSingletonLong(Env env, unsigned bitNum)
567 {
568     assert(!IsShort(env));
569     BitSetShortLongRep res   = MakeEmptyArrayBits(env);
570     unsigned           index = bitNum / BitsInSizeT;
571     res[index]               = ((size_t)1) << (bitNum % BitsInSizeT);
572     return res;
573 }
574
575 template <typename Env, typename BitSetTraits>
576 BitSetShortLongRep BitSetOps</*BitSetType*/ BitSetShortLongRep,
577                              /*Brand*/ BSShortLong,
578                              /*Env*/ Env,
579                              /*BitSetTraits*/ BitSetTraits>::MakeCopyLong(Env env, BitSetShortLongRep bs)
580 {
581     assert(!IsShort(env));
582     BitSetShortLongRep res = MakeUninitArrayBits(env);
583     unsigned           len = BitSetTraits::GetArrSize(env, sizeof(size_t));
584     for (unsigned i = 0; i < len; i++)
585     {
586         res[i] = bs[i];
587     }
588     return res;
589 }
590
591 template <typename Env, typename BitSetTraits>
592 bool BitSetOps</*BitSetType*/ BitSetShortLongRep,
593                /*Brand*/ BSShortLong,
594                /*Env*/ Env,
595                /*BitSetTraits*/ BitSetTraits>::IsEmptyLong(Env env, BitSetShortLongRep bs)
596 {
597     assert(!IsShort(env));
598     unsigned len = BitSetTraits::GetArrSize(env, sizeof(size_t));
599     for (unsigned i = 0; i < len; i++)
600     {
601         if (bs[i] != 0)
602         {
603             return false;
604         }
605     }
606     return true;
607 }
608
609 template <typename Env, typename BitSetTraits>
610 unsigned BitSetOps</*BitSetType*/ BitSetShortLongRep,
611                    /*Brand*/ BSShortLong,
612                    /*Env*/ Env,
613                    /*BitSetTraits*/ BitSetTraits>::CountLong(Env env, BitSetShortLongRep bs)
614 {
615     assert(!IsShort(env));
616     unsigned len = BitSetTraits::GetArrSize(env, sizeof(size_t));
617     unsigned res = 0;
618     for (unsigned i = 0; i < len; i++)
619     {
620         res += BitSetSupport::CountBitsInIntegral(bs[i]);
621     }
622     return res;
623 }
624
625 template <typename Env, typename BitSetTraits>
626 void BitSetOps</*BitSetType*/ BitSetShortLongRep,
627                /*Brand*/ BSShortLong,
628                /*Env*/ Env,
629                /*BitSetTraits*/ BitSetTraits>::UnionDLong(Env env, BitSetShortLongRep& bs1, BitSetShortLongRep bs2)
630 {
631     assert(!IsShort(env));
632     unsigned len = BitSetTraits::GetArrSize(env, sizeof(size_t));
633     for (unsigned i = 0; i < len; i++)
634     {
635         bs1[i] |= bs2[i];
636     }
637 }
638
639 template <typename Env, typename BitSetTraits>
640 void BitSetOps</*BitSetType*/ BitSetShortLongRep,
641                /*Brand*/ BSShortLong,
642                /*Env*/ Env,
643                /*BitSetTraits*/ BitSetTraits>::DiffDLong(Env env, BitSetShortLongRep& bs1, BitSetShortLongRep bs2)
644 {
645     assert(!IsShort(env));
646     unsigned len = BitSetTraits::GetArrSize(env, sizeof(size_t));
647     for (unsigned i = 0; i < len; i++)
648     {
649         bs1[i] &= ~bs2[i];
650     }
651 }
652
653 template <typename Env, typename BitSetTraits>
654 void BitSetOps</*BitSetType*/ BitSetShortLongRep,
655                /*Brand*/ BSShortLong,
656                /*Env*/ Env,
657                /*BitSetTraits*/ BitSetTraits>::AddElemDLong(Env env, BitSetShortLongRep& bs, unsigned i)
658 {
659     assert(!IsShort(env));
660     unsigned index = i / BitsInSizeT;
661     size_t   mask  = ((size_t)1) << (i % BitsInSizeT);
662     bs[index] |= mask;
663 }
664
665 template <typename Env, typename BitSetTraits>
666 bool BitSetOps</*BitSetType*/ BitSetShortLongRep,
667                /*Brand*/ BSShortLong,
668                /*Env*/ Env,
669                /*BitSetTraits*/ BitSetTraits>::TryAddElemDLong(Env env, BitSetShortLongRep& bs, unsigned i)
670 {
671     assert(!IsShort(env));
672     unsigned index = i / BitsInSizeT;
673     size_t   mask  = ((size_t)1) << (i % BitsInSizeT);
674     size_t   bits  = bs[index];
675     bool     added = (bits & mask) == 0;
676     bs[index]      = bits | mask;
677     return added;
678 }
679
680 template <typename Env, typename BitSetTraits>
681 void BitSetOps</*BitSetType*/ BitSetShortLongRep,
682                /*Brand*/ BSShortLong,
683                /*Env*/ Env,
684                /*BitSetTraits*/ BitSetTraits>::RemoveElemDLong(Env env, BitSetShortLongRep& bs, unsigned i)
685 {
686     assert(!IsShort(env));
687     unsigned index = i / BitsInSizeT;
688     size_t   mask  = ((size_t)1) << (i % BitsInSizeT);
689     mask           = ~mask;
690     bs[index] &= mask;
691 }
692
693 template <typename Env, typename BitSetTraits>
694 void BitSetOps</*BitSetType*/ BitSetShortLongRep,
695                /*Brand*/ BSShortLong,
696                /*Env*/ Env,
697                /*BitSetTraits*/ BitSetTraits>::ClearDLong(Env env, BitSetShortLongRep& bs)
698 {
699     assert(!IsShort(env));
700     unsigned len = BitSetTraits::GetArrSize(env, sizeof(size_t));
701     for (unsigned i = 0; i < len; i++)
702     {
703         bs[i] = 0;
704     }
705 }
706
707 template <typename Env, typename BitSetTraits>
708 BitSetShortLongRep BitSetOps</*BitSetType*/ BitSetShortLongRep,
709                              /*Brand*/ BSShortLong,
710                              /*Env*/ Env,
711                              /*BitSetTraits*/ BitSetTraits>::MakeUninitArrayBits(Env env)
712 {
713     assert(!IsShort(env));
714     unsigned len = BitSetTraits::GetArrSize(env, sizeof(size_t));
715     assert(len > 1); // Or else would not require an array.
716     return (BitSetShortLongRep)(BitSetTraits::Alloc(env, len * sizeof(size_t)));
717 }
718
719 template <typename Env, typename BitSetTraits>
720 BitSetShortLongRep BitSetOps</*BitSetType*/ BitSetShortLongRep,
721                              /*Brand*/ BSShortLong,
722                              /*Env*/ Env,
723                              /*BitSetTraits*/ BitSetTraits>::MakeEmptyArrayBits(Env env)
724 {
725     assert(!IsShort(env));
726     unsigned len = BitSetTraits::GetArrSize(env, sizeof(size_t));
727     assert(len > 1); // Or else would not require an array.
728     BitSetShortLongRep res = (BitSetShortLongRep)(BitSetTraits::Alloc(env, len * sizeof(size_t)));
729     for (unsigned i = 0; i < len; i++)
730     {
731         res[i] = 0;
732     }
733     return res;
734 }
735
736 template <typename Env, typename BitSetTraits>
737 BitSetShortLongRep BitSetOps</*BitSetType*/ BitSetShortLongRep,
738                              /*Brand*/ BSShortLong,
739                              /*Env*/ Env,
740                              /*BitSetTraits*/ BitSetTraits>::MakeFullArrayBits(Env env)
741 {
742     assert(!IsShort(env));
743     unsigned len = BitSetTraits::GetArrSize(env, sizeof(size_t));
744     assert(len > 1); // Or else would not require an array.
745     BitSetShortLongRep res = (BitSetShortLongRep)(BitSetTraits::Alloc(env, len * sizeof(size_t)));
746     for (unsigned i = 0; i < len - 1; i++)
747     {
748         res[i] = size_t(-1);
749     }
750     // Start with all ones, shift in zeros in the last elem.
751     unsigned lastElemBits = (BitSetTraits::GetSize(env) - 1) % BitsInSizeT + 1;
752     res[len - 1]          = (size_t(-1) >> (BitsInSizeT - lastElemBits));
753     return res;
754 }
755
756 template <typename Env, typename BitSetTraits>
757 bool BitSetOps</*BitSetType*/ BitSetShortLongRep,
758                /*Brand*/ BSShortLong,
759                /*Env*/ Env,
760                /*BitSetTraits*/ BitSetTraits>::IsMemberLong(Env env, BitSetShortLongRep bs, unsigned i)
761 {
762     assert(!IsShort(env));
763     unsigned index     = i / BitsInSizeT;
764     unsigned bitInElem = (i % BitsInSizeT);
765     size_t   mask      = ((size_t)1) << bitInElem;
766     return (bs[index] & mask) != 0;
767 }
768
769 template <typename Env, typename BitSetTraits>
770 void BitSetOps</*BitSetType*/ BitSetShortLongRep,
771                /*Brand*/ BSShortLong,
772                /*Env*/ Env,
773                /*BitSetTraits*/ BitSetTraits>::IntersectionDLong(Env                 env,
774                                                                  BitSetShortLongRep& bs1,
775                                                                  BitSetShortLongRep  bs2)
776 {
777     assert(!IsShort(env));
778     unsigned len = BitSetTraits::GetArrSize(env, sizeof(size_t));
779     for (unsigned i = 0; i < len; i++)
780     {
781         bs1[i] &= bs2[i];
782     }
783 }
784
785 template <typename Env, typename BitSetTraits>
786 bool BitSetOps</*BitSetType*/ BitSetShortLongRep,
787                /*Brand*/ BSShortLong,
788                /*Env*/ Env,
789                /*BitSetTraits*/ BitSetTraits>::IsEmptyIntersectionLong(Env                env,
790                                                                        BitSetShortLongRep bs1,
791                                                                        BitSetShortLongRep bs2)
792 {
793     assert(!IsShort(env));
794     unsigned len = BitSetTraits::GetArrSize(env, sizeof(size_t));
795     for (unsigned i = 0; i < len; i++)
796     {
797         if ((bs1[i] & bs2[i]) != 0)
798         {
799             return false;
800         }
801     }
802     return true;
803 }
804
805 template <typename Env, typename BitSetTraits>
806 bool BitSetOps</*BitSetType*/ BitSetShortLongRep,
807                /*Brand*/ BSShortLong,
808                /*Env*/ Env,
809                /*BitSetTraits*/ BitSetTraits>::IsEmptyUnionLong(Env env, BitSetShortLongRep bs1, BitSetShortLongRep bs2)
810 {
811     assert(!IsShort(env));
812     unsigned len = BitSetTraits::GetArrSize(env, sizeof(size_t));
813     for (unsigned i = 0; i < len; i++)
814     {
815         if ((bs1[i] | bs2[i]) != 0)
816         {
817             return false;
818         }
819     }
820     return true;
821 }
822
823 template <typename Env, typename BitSetTraits>
824 void BitSetOps</*BitSetType*/ BitSetShortLongRep,
825                /*Brand*/ BSShortLong,
826                /*Env*/ Env,
827                /*BitSetTraits*/ BitSetTraits>::DataFlowDLong(Env                      env,
828                                                              BitSetShortLongRep&      out,
829                                                              const BitSetShortLongRep gen,
830                                                              const BitSetShortLongRep in)
831 {
832     assert(!IsShort(env));
833     unsigned len = BitSetTraits::GetArrSize(env, sizeof(size_t));
834     for (unsigned i = 0; i < len; i++)
835     {
836         out[i] = out[i] & (gen[i] | in[i]);
837     }
838 }
839
840 template <typename Env, typename BitSetTraits>
841 void BitSetOps</*BitSetType*/ BitSetShortLongRep,
842                /*Brand*/ BSShortLong,
843                /*Env*/ Env,
844                /*BitSetTraits*/ BitSetTraits>::LivenessDLong(Env                      env,
845                                                              BitSetShortLongRep&      in,
846                                                              const BitSetShortLongRep def,
847                                                              const BitSetShortLongRep use,
848                                                              const BitSetShortLongRep out)
849 {
850     assert(!IsShort(env));
851     unsigned len = BitSetTraits::GetArrSize(env, sizeof(size_t));
852     for (unsigned i = 0; i < len; i++)
853     {
854         in[i] = use[i] | (out[i] & ~def[i]);
855     }
856 }
857
858 template <typename Env, typename BitSetTraits>
859 bool BitSetOps</*BitSetType*/ BitSetShortLongRep,
860                /*Brand*/ BSShortLong,
861                /*Env*/ Env,
862                /*BitSetTraits*/ BitSetTraits>::EqualLong(Env env, BitSetShortLongRep bs1, BitSetShortLongRep bs2)
863 {
864     assert(!IsShort(env));
865     unsigned len = BitSetTraits::GetArrSize(env, sizeof(size_t));
866     for (unsigned i = 0; i < len; i++)
867     {
868         if (bs1[i] != bs2[i])
869         {
870             return false;
871         }
872     }
873     return true;
874 }
875
876 template <typename Env, typename BitSetTraits>
877 bool BitSetOps</*BitSetType*/ BitSetShortLongRep,
878                /*Brand*/ BSShortLong,
879                /*Env*/ Env,
880                /*BitSetTraits*/ BitSetTraits>::IsSubsetLong(Env env, BitSetShortLongRep bs1, BitSetShortLongRep bs2)
881 {
882     assert(!IsShort(env));
883     unsigned len = BitSetTraits::GetArrSize(env, sizeof(size_t));
884     for (unsigned i = 0; i < len; i++)
885     {
886         if ((bs1[i] & bs2[i]) != bs1[i])
887         {
888             return false;
889         }
890     }
891     return true;
892 }
893
894 #ifdef DEBUG
895 template <typename Env, typename BitSetTraits>
896 const char* BitSetOps</*BitSetType*/ BitSetShortLongRep,
897                       /*Brand*/ BSShortLong,
898                       /*Env*/ Env,
899                       /*BitSetTraits*/ BitSetTraits>::ToStringLong(Env env, BitSetShortLongRep bs)
900 {
901     assert(!IsShort(env));
902     unsigned  len           = BitSetTraits::GetArrSize(env, sizeof(size_t));
903     const int CharsForSizeT = sizeof(size_t) * 2;
904     unsigned  allocSz       = len * CharsForSizeT + 4;
905     unsigned  remaining     = allocSz;
906     char*     res           = (char*)BitSetTraits::DebugAlloc(env, allocSz);
907     char*     temp          = res;
908     for (unsigned i = len; 0 < i; i--)
909     {
910         size_t bits = bs[i - 1];
911         for (unsigned bytesDone = 0; bytesDone < sizeof(size_t); bytesDone += sizeof(unsigned))
912         {
913             unsigned bits0 = (unsigned)bits;
914             sprintf_s(temp, remaining, "%08X", bits0);
915             temp += 8;
916             remaining -= 8;
917             bytesDone += 4;
918             assert(sizeof(unsigned) == 4);
919             // Doing this twice by 16, rather than once by 32, avoids warnings when size_t == unsigned.
920             bits = bits >> 16;
921             bits = bits >> 16;
922         }
923     }
924     return res;
925 }
926 #endif
927
928 #endif // bitSetAsShortLong_DEFINED