OLD | NEW |
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 |
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
301 BitVector(Allocator A = Allocator()) | 301 BitVector(Allocator A = Allocator()) |
302 : Size(0), Capacity(0), Alloc(std::move(A)) { | 302 : Size(0), Capacity(0), Alloc(std::move(A)) { |
303 Bits = nullptr; | 303 Bits = nullptr; |
304 } | 304 } |
305 | 305 |
306 /// BitVector ctor - Creates a bitvector of specified number of bits. All | 306 /// BitVector ctor - Creates a bitvector of specified number of bits. All |
307 /// bits are initialized to the specified value. | 307 /// bits are initialized to the specified value. |
308 explicit BitVector(unsigned s, bool t = false, Allocator A = Allocator()) | 308 explicit BitVector(unsigned s, bool t = false, Allocator A = Allocator()) |
309 : Size(s), Alloc(std::move(A)) { | 309 : Size(s), Alloc(std::move(A)) { |
310 Capacity = NumBitWords(s); | 310 Capacity = NumBitWords(s); |
311 Bits = Alloc.allocate(Capacity * sizeof(BitWord)); | 311 Bits = Alloc.allocate(Capacity); |
312 init_words(Bits, Capacity, t); | 312 init_words(Bits, Capacity, t); |
313 if (t) | 313 if (t) |
314 clear_unused_bits(); | 314 clear_unused_bits(); |
315 } | 315 } |
316 | 316 |
317 /// BitVector copy ctor. | 317 /// BitVector copy ctor. |
318 BitVector(const BitVector &RHS) : Size(RHS.size()), Alloc(RHS.Alloc) { | 318 BitVector(const BitVector &RHS) : Size(RHS.size()), Alloc(RHS.Alloc) { |
319 if (Size == 0) { | 319 if (Size == 0) { |
320 Bits = nullptr; | 320 Bits = nullptr; |
321 Capacity = 0; | 321 Capacity = 0; |
322 return; | 322 return; |
323 } | 323 } |
324 | 324 |
325 Capacity = NumBitWords(RHS.size()); | 325 Capacity = NumBitWords(RHS.size()); |
326 Bits = Alloc.allocate(Capacity * sizeof(BitWord)); | 326 Bits = Alloc.allocate(Capacity); |
327 std::memcpy(Bits, RHS.Bits, Capacity * sizeof(BitWord)); | 327 std::memcpy(Bits, RHS.Bits, Capacity * sizeof(BitWord)); |
328 } | 328 } |
329 | 329 |
330 BitVector(BitVector &&RHS) | 330 BitVector(BitVector &&RHS) |
331 : Bits(RHS.Bits), Size(RHS.Size), Capacity(RHS.Capacity), | 331 : Bits(RHS.Bits), Size(RHS.Size), Capacity(RHS.Capacity), |
332 Alloc(std::move(RHS.Alloc)) { | 332 Alloc(std::move(RHS.Alloc)) { |
333 RHS.Bits = nullptr; | 333 RHS.Bits = nullptr; |
334 } | 334 } |
335 | 335 |
336 ~BitVector() { | 336 ~BitVector() { |
337 if (Bits != nullptr) { | 337 if (Bits != nullptr) { |
338 Alloc.deallocate(Bits, Capacity * sizeof(BitWord)); | 338 Alloc.deallocate(Bits, Capacity); |
339 } | 339 } |
340 } | 340 } |
341 | 341 |
342 /// empty - Tests whether there are no bits in this bitvector. | 342 /// empty - Tests whether there are no bits in this bitvector. |
343 bool empty() const { return Size == 0; } | 343 bool empty() const { return Size == 0; } |
344 | 344 |
345 /// size - Returns the number of bits in this bitvector. | 345 /// size - Returns the number of bits in this bitvector. |
346 size_type size() const { return Size; } | 346 size_type size() const { return Size; } |
347 | 347 |
348 /// count - Returns the number of bits which are set. | 348 /// count - Returns the number of bits which are set. |
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
648 | 648 |
649 Size = RHS.size(); | 649 Size = RHS.size(); |
650 unsigned RHSWords = NumBitWords(Size); | 650 unsigned RHSWords = NumBitWords(Size); |
651 if (Size <= Capacity * BITWORD_SIZE) { | 651 if (Size <= Capacity * BITWORD_SIZE) { |
652 if (Size) | 652 if (Size) |
653 std::memcpy(Bits, RHS.Bits, RHSWords * sizeof(BitWord)); | 653 std::memcpy(Bits, RHS.Bits, RHSWords * sizeof(BitWord)); |
654 clear_unused_bits(); | 654 clear_unused_bits(); |
655 return *this; | 655 return *this; |
656 } | 656 } |
657 | 657 |
| 658 // Currently, BitVector is only used by liveness analysis. With the |
| 659 // following assert, we make sure BitVectors grow in a single step from 0 to |
| 660 // their final capacity, rather than growing slowly and "leaking" memory in |
| 661 // the process. |
| 662 assert(Capacity == 0); |
| 663 |
658 // Grow the bitvector to have enough elements. | 664 // Grow the bitvector to have enough elements. |
659 const auto OldCapacity = Capacity; | 665 const auto OldCapacity = Capacity; |
660 Capacity = RHSWords; | 666 Capacity = RHSWords; |
661 assert(Capacity > 0 && "negative capacity?"); | 667 assert(Capacity > 0 && "negative capacity?"); |
662 BitWord *NewBits = Alloc.allocate(Capacity * sizeof(BitWord)); | 668 BitWord *NewBits = Alloc.allocate(Capacity); |
663 std::memcpy(NewBits, RHS.Bits, Capacity * sizeof(BitWord)); | 669 std::memcpy(NewBits, RHS.Bits, Capacity * sizeof(BitWord)); |
664 | 670 |
665 // Destroy the old bits. | 671 // Destroy the old bits. |
666 Alloc.deallocate(Bits, OldCapacity * sizeof(BitWord)); | 672 Alloc.deallocate(Bits, OldCapacity); |
667 Bits = NewBits; | 673 Bits = NewBits; |
668 | 674 |
669 return *this; | 675 return *this; |
670 } | 676 } |
671 | 677 |
672 const BitVector &operator=(BitVector &&RHS) { | 678 const BitVector &operator=(BitVector &&RHS) { |
673 if (this == &RHS) | 679 if (this == &RHS) |
674 return *this; | 680 return *this; |
675 | 681 |
676 Alloc.deallocate(Bits, Capacity * sizeof(BitWord)); | 682 Alloc.deallocate(Bits, Capacity); |
677 Bits = RHS.Bits; | 683 Bits = RHS.Bits; |
678 Size = RHS.Size; | 684 Size = RHS.Size; |
679 Capacity = RHS.Capacity; | 685 Capacity = RHS.Capacity; |
680 | 686 |
681 RHS.Bits = nullptr; | 687 RHS.Bits = nullptr; |
682 | 688 |
683 return *this; | 689 return *this; |
684 } | 690 } |
685 | 691 |
686 void swap(BitVector &RHS) { | 692 void swap(BitVector &RHS) { |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
748 } | 754 } |
749 } | 755 } |
750 | 756 |
751 // Clear the unused bits in the high words. | 757 // Clear the unused bits in the high words. |
752 void clear_unused_bits() { set_unused_bits(false); } | 758 void clear_unused_bits() { set_unused_bits(false); } |
753 | 759 |
754 void grow(unsigned NewSize) { | 760 void grow(unsigned NewSize) { |
755 const auto OldCapacity = Capacity; | 761 const auto OldCapacity = Capacity; |
756 Capacity = std::max(NumBitWords(NewSize), Capacity * 2); | 762 Capacity = std::max(NumBitWords(NewSize), Capacity * 2); |
757 assert(Capacity > 0 && "realloc-ing zero space"); | 763 assert(Capacity > 0 && "realloc-ing zero space"); |
758 auto *NewBits = Alloc.allocate(Capacity * sizeof(BitWord)); | 764 auto *NewBits = Alloc.allocate(Capacity); |
759 std::memcpy(Bits, NewBits, OldCapacity * sizeof(BitWord)); | 765 std::memcpy(Bits, NewBits, OldCapacity * sizeof(BitWord)); |
760 Alloc.deallocate(Bits, OldCapacity * sizeof(BitWord)); | 766 Alloc.deallocate(Bits, OldCapacity); |
761 Bits = NewBits; | 767 Bits = NewBits; |
762 | 768 |
763 clear_unused_bits(); | 769 clear_unused_bits(); |
764 } | 770 } |
765 | 771 |
766 void init_words(BitWord *B, unsigned NumWords, bool t) { | 772 void init_words(BitWord *B, unsigned NumWords, bool t) { |
767 memset(B, 0 - (int)t, NumWords * sizeof(BitWord)); | 773 memset(B, 0 - (int)t, NumWords * sizeof(BitWord)); |
768 } | 774 } |
769 | 775 |
770 template <bool AddBits, bool InvertMask> | 776 template <bool AddBits, bool InvertMask> |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
802 }; | 808 }; |
803 | 809 |
804 } // end of namespace Ice | 810 } // end of namespace Ice |
805 | 811 |
806 namespace std { | 812 namespace std { |
807 /// Implement std::swap in terms of BitVector swap. | 813 /// Implement std::swap in terms of BitVector swap. |
808 inline void swap(Ice::BitVector &LHS, Ice::BitVector &RHS) { LHS.swap(RHS); } | 814 inline void swap(Ice::BitVector &LHS, Ice::BitVector &RHS) { LHS.swap(RHS); } |
809 } | 815 } |
810 | 816 |
811 #endif // SUBZERO_SRC_ICEBITVECTOR_H | 817 #endif // SUBZERO_SRC_ICEBITVECTOR_H |
OLD | NEW |