Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(146)

Side by Side Diff: src/IceBitVector.h

Issue 1738683003: Subzero. Moar performance tweaks. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Addresses comments Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | src/IceCfg.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 //===- subzero/src/IceBitVector.h - Inline bit vector. ----------*- C++ -*-===// 1 //===- subzero/src/IceBitVector.h - Inline bit vector. ----------*- C++ -*-===//
2 // 2 //
3 // The Subzero Code Generator 3 // The Subzero Code Generator
4 // 4 //
5 // This file is distributed under the University of Illinois Open Source 5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details. 6 // License. See LICENSE.TXT for details.
7 // 7 //
8 //===----------------------------------------------------------------------===// 8 //===----------------------------------------------------------------------===//
9 /// 9 ///
10 /// \file 10 /// \file
11 /// \brief Defines and implements a bit vector with inline storage. It is a drop 11 /// \brief Defines and implements a bit vector classes.
Jim Stichnoth 2016/02/26 15:18:23 s/a //
12 /// in replacement for llvm::SmallBitVector in subzero -- i.e., not all of 12 ///
13 /// llvm::SmallBitVector interface is implemented. 13 /// SmallBitVector is a drop in replacement for llvm::SmallBitVector. It uses
14 /// inline storage, at the expense of limited, static size.
15 ///
16 /// BitVector is a allocator aware version of llvm::BitVector. Its
Jim Stichnoth 2016/02/26 15:18:23 an allocator-aware
17 /// implementation was copied ipsis literis from llvm.
14 /// 18 ///
15 //===----------------------------------------------------------------------===// 19 //===----------------------------------------------------------------------===//
16 20
17 #ifndef SUBZERO_SRC_ICEBITVECTOR_H 21 #ifndef SUBZERO_SRC_ICEBITVECTOR_H
18 #define SUBZERO_SRC_ICEBITVECTOR_H 22 #define SUBZERO_SRC_ICEBITVECTOR_H
19 23
20 #include "IceDefs.h" 24 #include "IceMemory.h"
21 #include "IceOperand.h" 25 #include "IceOperand.h"
22 26
23 #include "llvm/Support/MathExtras.h" 27 #include "llvm/Support/MathExtras.h"
24 28
25 #include <algorithm> 29 #include <algorithm>
30 #include <cassert>
26 #include <climits> 31 #include <climits>
27 #include <memory> 32 #include <memory>
28 #include <type_traits> 33 #include <type_traits>
34 #include <utility>
29 35
30 namespace Ice { 36 namespace Ice {
31 class SmallBitVector { 37 class SmallBitVector {
32 public: 38 public:
33 using ElementType = uint64_t; 39 using ElementType = uint64_t;
34 static constexpr SizeT BitIndexSize = 6; // log2(NumBitsPerPos); 40 static constexpr SizeT BitIndexSize = 6; // log2(NumBitsPerPos);
35 static constexpr SizeT NumBitsPerPos = sizeof(ElementType) * CHAR_BIT; 41 static constexpr SizeT NumBitsPerPos = sizeof(ElementType) * CHAR_BIT;
36 static_assert(1 << BitIndexSize == NumBitsPerPos, "Invalid BitIndexSize."); 42 static_assert(1 << BitIndexSize == NumBitsPerPos, "Invalid BitIndexSize.");
37 43
38 SmallBitVector(const SmallBitVector &BV) { *this = BV; } 44 SmallBitVector(const SmallBitVector &BV) { *this = BV; }
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
233 Bits[Pos] ^= ~ElementType(0); 239 Bits[Pos] ^= ~ElementType(0);
234 } else { 240 } else {
235 const ElementType Mask = 241 const ElementType Mask =
236 (ElementType(1) << (size() - (Pos * NumBitsPerPos))) - 1; 242 (ElementType(1) << (size() - (Pos * NumBitsPerPos))) - 1;
237 Bits[Pos] ^= Mask; 243 Bits[Pos] ^= Mask;
238 } 244 }
239 invert<Pos + 1>(); 245 invert<Pos + 1>();
240 } 246 }
241 }; 247 };
242 248
249 class BitVector {
250 typedef unsigned long BitWord;
251 using Allocator = CfgLocalAllocator<BitWord>;
252
253 enum { BITWORD_SIZE = (unsigned)sizeof(BitWord) * CHAR_BIT };
254
255 static_assert(BITWORD_SIZE == 64 || BITWORD_SIZE == 32,
256 "Unsupported word size");
257
258 BitWord *Bits; // Actual bits.
259 unsigned Size; // Size of bitvector in bits.
260 unsigned Capacity; // Size of allocated memory in BitWord.
261 Allocator Alloc;
262
263 public:
264 typedef unsigned size_type;
265 // Encapsulation of a single bit.
266 class reference {
267 friend class BitVector;
268
269 BitWord *WordRef;
270 unsigned BitPos;
271
272 reference(); // Undefined
273
274 public:
275 reference(BitVector &b, unsigned Idx) {
276 WordRef = &b.Bits[Idx / BITWORD_SIZE];
277 BitPos = Idx % BITWORD_SIZE;
278 }
279
280 reference(const reference &) = default;
281
282 reference &operator=(reference t) {
283 *this = bool(t);
284 return *this;
285 }
286
287 reference &operator=(bool t) {
288 if (t)
289 *WordRef |= BitWord(1) << BitPos;
290 else
291 *WordRef &= ~(BitWord(1) << BitPos);
292 return *this;
293 }
294
295 operator bool() const {
296 return ((*WordRef) & (BitWord(1) << BitPos)) ? true : false;
297 }
298 };
299
300 /// BitVector default ctor - Creates an empty bitvector.
301 BitVector(Allocator A = Allocator())
302 : Size(0), Capacity(0), Alloc(std::move(A)) {
303 Bits = nullptr;
304 }
305
306 /// BitVector ctor - Creates a bitvector of specified number of bits. All
307 /// bits are initialized to the specified value.
308 explicit BitVector(unsigned s, bool t = false, Allocator A = Allocator())
309 : Size(s), Alloc(std::move(A)) {
310 Capacity = NumBitWords(s);
311 Bits = Alloc.allocate(Capacity * sizeof(BitWord));
312 init_words(Bits, Capacity, t);
313 if (t)
314 clear_unused_bits();
315 }
316
317 /// BitVector copy ctor.
318 BitVector(const BitVector &RHS) : Size(RHS.size()), Alloc(RHS.Alloc) {
319 if (Size == 0) {
320 Bits = nullptr;
321 Capacity = 0;
322 return;
323 }
324
325 Capacity = NumBitWords(RHS.size());
326 Bits = Alloc.allocate(Capacity * sizeof(BitWord));
327 std::memcpy(Bits, RHS.Bits, Capacity * sizeof(BitWord));
328 }
329
330 BitVector(BitVector &&RHS)
331 : Bits(RHS.Bits), Size(RHS.Size), Capacity(RHS.Capacity),
332 Alloc(std::move(RHS.Alloc)) {
333 RHS.Bits = nullptr;
334 }
335
336 ~BitVector() {
337 if (Bits != nullptr) {
338 Alloc.deallocate(Bits, Capacity * sizeof(BitWord));
339 }
340 }
341
342 /// empty - Tests whether there are no bits in this bitvector.
343 bool empty() const { return Size == 0; }
344
345 /// size - Returns the number of bits in this bitvector.
346 size_type size() const { return Size; }
347
348 /// count - Returns the number of bits which are set.
349 size_type count() const {
350 unsigned NumBits = 0;
351 for (unsigned i = 0; i < NumBitWords(size()); ++i)
352 NumBits += llvm::countPopulation(Bits[i]);
353 return NumBits;
354 }
355
356 /// any - Returns true if any bit is set.
357 bool any() const {
358 for (unsigned i = 0; i < NumBitWords(size()); ++i)
359 if (Bits[i] != 0)
360 return true;
361 return false;
362 }
363
364 /// all - Returns true if all bits are set.
365 bool all() const {
366 for (unsigned i = 0; i < Size / BITWORD_SIZE; ++i)
367 if (Bits[i] != ~0UL)
368 return false;
369
370 // If bits remain check that they are ones. The unused bits are always zero.
371 if (unsigned Remainder = Size % BITWORD_SIZE)
372 return Bits[Size / BITWORD_SIZE] == (1UL << Remainder) - 1;
373
374 return true;
375 }
376
377 /// none - Returns true if none of the bits are set.
378 bool none() const { return !any(); }
379
380 /// find_first - Returns the index of the first set bit, -1 if none
381 /// of the bits are set.
382 int find_first() const {
383 for (unsigned i = 0; i < NumBitWords(size()); ++i)
384 if (Bits[i] != 0)
385 return i * BITWORD_SIZE + llvm::countTrailingZeros(Bits[i]);
386 return -1;
387 }
388
389 /// find_next - Returns the index of the next set bit following the
390 /// "Prev" bit. Returns -1 if the next set bit is not found.
391 int find_next(unsigned Prev) const {
392 ++Prev;
393 if (Prev >= Size)
394 return -1;
395
396 unsigned WordPos = Prev / BITWORD_SIZE;
397 unsigned BitPos = Prev % BITWORD_SIZE;
398 BitWord Copy = Bits[WordPos];
399 // Mask off previous bits.
400 Copy &= ~0UL << BitPos;
401
402 if (Copy != 0)
403 return WordPos * BITWORD_SIZE + llvm::countTrailingZeros(Copy);
404
405 // Check subsequent words.
406 for (unsigned i = WordPos + 1; i < NumBitWords(size()); ++i)
407 if (Bits[i] != 0)
408 return i * BITWORD_SIZE + llvm::countTrailingZeros(Bits[i]);
409 return -1;
410 }
411
412 /// clear - Clear all bits.
413 void clear() { Size = 0; }
414
415 /// resize - Grow or shrink the bitvector.
416 void resize(unsigned N, bool t = false) {
417 if (N > Capacity * BITWORD_SIZE) {
418 unsigned OldCapacity = Capacity;
419 grow(N);
420 init_words(&Bits[OldCapacity], (Capacity - OldCapacity), t);
421 }
422
423 // Set any old unused bits that are now included in the BitVector. This
424 // may set bits that are not included in the new vector, but we will clear
425 // them back out below.
426 if (N > Size)
427 set_unused_bits(t);
428
429 // Update the size, and clear out any bits that are now unused
430 unsigned OldSize = Size;
431 Size = N;
432 if (t || N < OldSize)
433 clear_unused_bits();
434 }
435
436 void reserve(unsigned N) {
437 if (N > Capacity * BITWORD_SIZE)
438 grow(N);
439 }
440
441 // Set, reset, flip
442 BitVector &set() {
443 init_words(Bits, Capacity, true);
444 clear_unused_bits();
445 return *this;
446 }
447
448 BitVector &set(unsigned Idx) {
449 assert(Bits && "Bits never allocated");
450 Bits[Idx / BITWORD_SIZE] |= BitWord(1) << (Idx % BITWORD_SIZE);
451 return *this;
452 }
453
454 /// set - Efficiently set a range of bits in [I, E)
455 BitVector &set(unsigned I, unsigned E) {
456 assert(I <= E && "Attempted to set backwards range!");
457 assert(E <= size() && "Attempted to set out-of-bounds range!");
458
459 if (I == E)
460 return *this;
461
462 if (I / BITWORD_SIZE == E / BITWORD_SIZE) {
463 BitWord EMask = 1UL << (E % BITWORD_SIZE);
464 BitWord IMask = 1UL << (I % BITWORD_SIZE);
465 BitWord Mask = EMask - IMask;
466 Bits[I / BITWORD_SIZE] |= Mask;
467 return *this;
468 }
469
470 BitWord PrefixMask = ~0UL << (I % BITWORD_SIZE);
471 Bits[I / BITWORD_SIZE] |= PrefixMask;
472 I = llvm::RoundUpToAlignment(I, BITWORD_SIZE);
473
474 for (; I + BITWORD_SIZE <= E; I += BITWORD_SIZE)
475 Bits[I / BITWORD_SIZE] = ~0UL;
476
477 BitWord PostfixMask = (1UL << (E % BITWORD_SIZE)) - 1;
478 if (I < E)
479 Bits[I / BITWORD_SIZE] |= PostfixMask;
480
481 return *this;
482 }
483
484 BitVector &reset() {
485 init_words(Bits, Capacity, false);
486 return *this;
487 }
488
489 BitVector &reset(unsigned Idx) {
490 Bits[Idx / BITWORD_SIZE] &= ~(BitWord(1) << (Idx % BITWORD_SIZE));
491 return *this;
492 }
493
494 /// reset - Efficiently reset a range of bits in [I, E)
495 BitVector &reset(unsigned I, unsigned E) {
496 assert(I <= E && "Attempted to reset backwards range!");
497 assert(E <= size() && "Attempted to reset out-of-bounds range!");
498
499 if (I == E)
500 return *this;
501
502 if (I / BITWORD_SIZE == E / BITWORD_SIZE) {
503 BitWord EMask = 1UL << (E % BITWORD_SIZE);
504 BitWord IMask = 1UL << (I % BITWORD_SIZE);
505 BitWord Mask = EMask - IMask;
506 Bits[I / BITWORD_SIZE] &= ~Mask;
507 return *this;
508 }
509
510 BitWord PrefixMask = ~0UL << (I % BITWORD_SIZE);
511 Bits[I / BITWORD_SIZE] &= ~PrefixMask;
512 I = llvm::RoundUpToAlignment(I, BITWORD_SIZE);
513
514 for (; I + BITWORD_SIZE <= E; I += BITWORD_SIZE)
515 Bits[I / BITWORD_SIZE] = 0UL;
516
517 BitWord PostfixMask = (1UL << (E % BITWORD_SIZE)) - 1;
518 if (I < E)
519 Bits[I / BITWORD_SIZE] &= ~PostfixMask;
520
521 return *this;
522 }
523
524 BitVector &flip() {
525 for (unsigned i = 0; i < NumBitWords(size()); ++i)
526 Bits[i] = ~Bits[i];
527 clear_unused_bits();
528 return *this;
529 }
530
531 BitVector &flip(unsigned Idx) {
532 Bits[Idx / BITWORD_SIZE] ^= BitWord(1) << (Idx % BITWORD_SIZE);
533 return *this;
534 }
535
536 // Indexing.
537 reference operator[](unsigned Idx) {
538 assert(Idx < Size && "Out-of-bounds Bit access.");
539 return reference(*this, Idx);
540 }
541
542 bool operator[](unsigned Idx) const {
543 assert(Idx < Size && "Out-of-bounds Bit access.");
544 BitWord Mask = BitWord(1) << (Idx % BITWORD_SIZE);
545 return (Bits[Idx / BITWORD_SIZE] & Mask) != 0;
546 }
547
548 bool test(unsigned Idx) const { return (*this)[Idx]; }
549
550 /// Test if any common bits are set.
551 bool anyCommon(const BitVector &RHS) const {
552 unsigned ThisWords = NumBitWords(size());
553 unsigned RHSWords = NumBitWords(RHS.size());
554 for (unsigned i = 0, e = std::min(ThisWords, RHSWords); i != e; ++i)
555 if (Bits[i] & RHS.Bits[i])
556 return true;
557 return false;
558 }
559
560 // Comparison operators.
561 bool operator==(const BitVector &RHS) const {
562 unsigned ThisWords = NumBitWords(size());
563 unsigned RHSWords = NumBitWords(RHS.size());
564 unsigned i;
565 for (i = 0; i != std::min(ThisWords, RHSWords); ++i)
566 if (Bits[i] != RHS.Bits[i])
567 return false;
568
569 // Verify that any extra words are all zeros.
570 if (i != ThisWords) {
571 for (; i != ThisWords; ++i)
572 if (Bits[i])
573 return false;
574 } else if (i != RHSWords) {
575 for (; i != RHSWords; ++i)
576 if (RHS.Bits[i])
577 return false;
578 }
579 return true;
580 }
581
582 bool operator!=(const BitVector &RHS) const { return !(*this == RHS); }
583
584 /// Intersection, union, disjoint union.
585 BitVector &operator&=(const BitVector &RHS) {
586 unsigned ThisWords = NumBitWords(size());
587 unsigned RHSWords = NumBitWords(RHS.size());
588 unsigned i;
589 for (i = 0; i != std::min(ThisWords, RHSWords); ++i)
590 Bits[i] &= RHS.Bits[i];
591
592 // Any bits that are just in this bitvector become zero, because they aren't
593 // in the RHS bit vector. Any words only in RHS are ignored because they
594 // are already zero in the LHS.
595 for (; i != ThisWords; ++i)
596 Bits[i] = 0;
597
598 return *this;
599 }
600
601 /// reset - Reset bits that are set in RHS. Same as *this &= ~RHS.
602 BitVector &reset(const BitVector &RHS) {
603 unsigned ThisWords = NumBitWords(size());
604 unsigned RHSWords = NumBitWords(RHS.size());
605 unsigned i;
606 for (i = 0; i != std::min(ThisWords, RHSWords); ++i)
607 Bits[i] &= ~RHS.Bits[i];
608 return *this;
609 }
610
611 /// test - Check if (This - RHS) is zero.
612 /// This is the same as reset(RHS) and any().
613 bool test(const BitVector &RHS) const {
614 unsigned ThisWords = NumBitWords(size());
615 unsigned RHSWords = NumBitWords(RHS.size());
616 unsigned i;
617 for (i = 0; i != std::min(ThisWords, RHSWords); ++i)
618 if ((Bits[i] & ~RHS.Bits[i]) != 0)
619 return true;
620
621 for (; i != ThisWords; ++i)
622 if (Bits[i] != 0)
623 return true;
624
625 return false;
626 }
627
628 BitVector &operator|=(const BitVector &RHS) {
629 if (size() < RHS.size())
630 resize(RHS.size());
631 for (size_t i = 0, e = NumBitWords(RHS.size()); i != e; ++i)
632 Bits[i] |= RHS.Bits[i];
633 return *this;
634 }
635
636 BitVector &operator^=(const BitVector &RHS) {
637 if (size() < RHS.size())
638 resize(RHS.size());
639 for (size_t i = 0, e = NumBitWords(RHS.size()); i != e; ++i)
640 Bits[i] ^= RHS.Bits[i];
641 return *this;
642 }
643
644 // Assignment operator.
645 const BitVector &operator=(const BitVector &RHS) {
646 if (this == &RHS)
647 return *this;
648
649 Size = RHS.size();
650 unsigned RHSWords = NumBitWords(Size);
651 if (Size <= Capacity * BITWORD_SIZE) {
652 if (Size)
653 std::memcpy(Bits, RHS.Bits, RHSWords * sizeof(BitWord));
654 clear_unused_bits();
655 return *this;
656 }
657
658 // Grow the bitvector to have enough elements.
659 const auto OldCapacity = Capacity;
660 Capacity = RHSWords;
661 assert(Capacity > 0 && "negative capacity?");
662 BitWord *NewBits = Alloc.allocate(Capacity * sizeof(BitWord));
663 std::memcpy(NewBits, RHS.Bits, Capacity * sizeof(BitWord));
664
665 // Destroy the old bits.
666 Alloc.deallocate(Bits, OldCapacity * sizeof(BitWord));
667 Bits = NewBits;
668
669 return *this;
670 }
671
672 const BitVector &operator=(BitVector &&RHS) {
673 if (this == &RHS)
674 return *this;
675
676 Alloc.deallocate(Bits, Capacity * sizeof(BitWord));
677 Bits = RHS.Bits;
678 Size = RHS.Size;
679 Capacity = RHS.Capacity;
680
681 RHS.Bits = nullptr;
682
683 return *this;
684 }
685
686 void swap(BitVector &RHS) {
687 std::swap(Bits, RHS.Bits);
688 std::swap(Size, RHS.Size);
689 std::swap(Capacity, RHS.Capacity);
690 }
691
692 //===--------------------------------------------------------------------===//
693 // Portable bit mask operations.
694 //===--------------------------------------------------------------------===//
695 //
696 // These methods all operate on arrays of uint32_t, each holding 32 bits. The
697 // fixed word size makes it easier to work with literal bit vector constants
698 // in portable code.
699 //
700 // The LSB in each word is the lowest numbered bit. The size of a portable
701 // bit mask is always a whole multiple of 32 bits. If no bit mask size is
702 // given, the bit mask is assumed to cover the entire BitVector.
703
704 /// setBitsInMask - Add '1' bits from Mask to this vector. Don't resize.
705 /// This computes "*this |= Mask".
706 void setBitsInMask(const uint32_t *Mask, unsigned MaskWords = ~0u) {
707 applyMask<true, false>(Mask, MaskWords);
708 }
709
710 /// clearBitsInMask - Clear any bits in this vector that are set in Mask.
711 /// Don't resize. This computes "*this &= ~Mask".
712 void clearBitsInMask(const uint32_t *Mask, unsigned MaskWords = ~0u) {
713 applyMask<false, false>(Mask, MaskWords);
714 }
715
716 /// setBitsNotInMask - Add a bit to this vector for every '0' bit in Mask.
717 /// Don't resize. This computes "*this |= ~Mask".
718 void setBitsNotInMask(const uint32_t *Mask, unsigned MaskWords = ~0u) {
719 applyMask<true, true>(Mask, MaskWords);
720 }
721
722 /// clearBitsNotInMask - Clear a bit in this vector for every '0' bit in Mask.
723 /// Don't resize. This computes "*this &= Mask".
724 void clearBitsNotInMask(const uint32_t *Mask, unsigned MaskWords = ~0u) {
725 applyMask<false, true>(Mask, MaskWords);
726 }
727
728 private:
729 unsigned NumBitWords(unsigned S) const {
730 return (S + BITWORD_SIZE - 1) / BITWORD_SIZE;
731 }
732
733 // Set the unused bits in the high words.
734 void set_unused_bits(bool t = true) {
735 // Set high words first.
736 unsigned UsedWords = NumBitWords(Size);
737 if (Capacity > UsedWords)
738 init_words(&Bits[UsedWords], (Capacity - UsedWords), t);
739
740 // Then set any stray high bits of the last used word.
741 unsigned ExtraBits = Size % BITWORD_SIZE;
742 if (ExtraBits) {
743 BitWord ExtraBitMask = ~0UL << ExtraBits;
744 if (t)
745 Bits[UsedWords - 1] |= ExtraBitMask;
746 else
747 Bits[UsedWords - 1] &= ~ExtraBitMask;
748 }
749 }
750
751 // Clear the unused bits in the high words.
752 void clear_unused_bits() { set_unused_bits(false); }
753
754 void grow(unsigned NewSize) {
755 const auto OldCapacity = Capacity;
756 Capacity = std::max(NumBitWords(NewSize), Capacity * 2);
757 assert(Capacity > 0 && "realloc-ing zero space");
758 auto *NewBits = Alloc.allocate(Capacity * sizeof(BitWord));
759 std::memcpy(Bits, NewBits, OldCapacity * sizeof(BitWord));
760 Alloc.deallocate(Bits, OldCapacity * sizeof(BitWord));
761 Bits = NewBits;
762
763 clear_unused_bits();
764 }
765
766 void init_words(BitWord *B, unsigned NumWords, bool t) {
767 memset(B, 0 - (int)t, NumWords * sizeof(BitWord));
768 }
769
770 template <bool AddBits, bool InvertMask>
771 void applyMask(const uint32_t *Mask, unsigned MaskWords) {
772 static_assert(BITWORD_SIZE % 32 == 0, "Unsupported BitWord size.");
773 MaskWords = std::min(MaskWords, (size() + 31) / 32);
774 const unsigned Scale = BITWORD_SIZE / 32;
775 unsigned i;
776 for (i = 0; MaskWords >= Scale; ++i, MaskWords -= Scale) {
777 BitWord BW = Bits[i];
778 // This inner loop should unroll completely when BITWORD_SIZE > 32.
779 for (unsigned b = 0; b != BITWORD_SIZE; b += 32) {
780 uint32_t M = *Mask++;
781 if (InvertMask)
782 M = ~M;
783 if (AddBits)
784 BW |= BitWord(M) << b;
785 else
786 BW &= ~(BitWord(M) << b);
787 }
788 Bits[i] = BW;
789 }
790 for (unsigned b = 0; MaskWords; b += 32, --MaskWords) {
791 uint32_t M = *Mask++;
792 if (InvertMask)
793 M = ~M;
794 if (AddBits)
795 Bits[i] |= BitWord(M) << b;
796 else
797 Bits[i] &= ~(BitWord(M) << b);
798 }
799 if (AddBits)
800 clear_unused_bits();
801 }
802 };
803
243 } // end of namespace Ice 804 } // end of namespace Ice
244 805
806 namespace std {
807 /// Implement std::swap in terms of BitVector swap.
808 inline void swap(Ice::BitVector &LHS, Ice::BitVector &RHS) { LHS.swap(RHS); }
809 }
810
245 #endif // SUBZERO_SRC_ICEBITVECTOR_H 811 #endif // SUBZERO_SRC_ICEBITVECTOR_H
OLDNEW
« no previous file with comments | « no previous file | src/IceCfg.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698