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

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

Powered by Google App Engine
This is Rietveld 408576698