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

Side by Side Diff: src/IceBitVector.h

Issue 1838973005: Subzero. Liveness memory management. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Addresses comments. Created 4 years, 8 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
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 Bits[Pos] ^= ~ElementType(0); 239 Bits[Pos] ^= ~ElementType(0);
240 } else { 240 } else {
241 const ElementType Mask = 241 const ElementType Mask =
242 (ElementType(1) << (size() - (Pos * NumBitsPerPos))) - 1; 242 (ElementType(1) << (size() - (Pos * NumBitsPerPos))) - 1;
243 Bits[Pos] ^= Mask; 243 Bits[Pos] ^= Mask;
244 } 244 }
245 invert<Pos + 1>(); 245 invert<Pos + 1>();
246 } 246 }
247 }; 247 };
248 248
249 class BitVector { 249 template <template <typename> class AT> class BitVectorTmpl {
250 typedef unsigned long BitWord; 250 typedef unsigned long BitWord;
251 using Allocator = CfgLocalAllocator<BitWord>; 251 using Allocator = AT<BitWord>;
252 252
253 enum { BITWORD_SIZE = (unsigned)sizeof(BitWord) * CHAR_BIT }; 253 enum { BITWORD_SIZE = (unsigned)sizeof(BitWord) * CHAR_BIT };
254 254
255 static_assert(BITWORD_SIZE == 64 || BITWORD_SIZE == 32, 255 static_assert(BITWORD_SIZE == 64 || BITWORD_SIZE == 32,
256 "Unsupported word size"); 256 "Unsupported word size");
257 257
258 BitWord *Bits; // Actual bits. 258 BitWord *Bits; // Actual bits.
259 unsigned Size; // Size of bitvector in bits. 259 unsigned Size; // Size of bitvector in bits.
260 unsigned Capacity; // Size of allocated memory in BitWord. 260 unsigned Capacity; // Size of allocated memory in BitWord.
261 Allocator Alloc; 261 Allocator Alloc;
262 262
263 public: 263 public:
264 typedef unsigned size_type; 264 typedef unsigned size_type;
265 // Encapsulation of a single bit. 265 // Encapsulation of a single bit.
266 class reference { 266 class reference {
267 friend class BitVector; 267 friend class BitVectorTmpl;
268 268
269 BitWord *WordRef; 269 BitWord *WordRef;
270 unsigned BitPos; 270 unsigned BitPos;
271 271
272 reference(); // Undefined 272 reference(); // Undefined
273 273
274 public: 274 public:
275 reference(BitVector &b, unsigned Idx) { 275 reference(BitVectorTmpl &b, unsigned Idx) {
276 WordRef = &b.Bits[Idx / BITWORD_SIZE]; 276 WordRef = &b.Bits[Idx / BITWORD_SIZE];
277 BitPos = Idx % BITWORD_SIZE; 277 BitPos = Idx % BITWORD_SIZE;
278 } 278 }
279 279
280 reference(const reference &) = default; 280 reference(const reference &) = default;
281 281
282 reference &operator=(reference t) { 282 reference &operator=(reference t) {
283 *this = bool(t); 283 *this = bool(t);
284 return *this; 284 return *this;
285 } 285 }
286 286
287 reference &operator=(bool t) { 287 reference &operator=(bool t) {
288 if (t) 288 if (t)
289 *WordRef |= BitWord(1) << BitPos; 289 *WordRef |= BitWord(1) << BitPos;
290 else 290 else
291 *WordRef &= ~(BitWord(1) << BitPos); 291 *WordRef &= ~(BitWord(1) << BitPos);
292 return *this; 292 return *this;
293 } 293 }
294 294
295 operator bool() const { 295 operator bool() const {
296 return ((*WordRef) & (BitWord(1) << BitPos)) ? true : false; 296 return ((*WordRef) & (BitWord(1) << BitPos)) ? true : false;
297 } 297 }
298 }; 298 };
299 299
300 /// BitVector default ctor - Creates an empty bitvector. 300 /// BitVectorTmpl default ctor - Creates an empty bitvector.
301 BitVector(Allocator A = Allocator()) 301 BitVectorTmpl(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 /// BitVectorTmpl 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 BitVectorTmpl(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); 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 /// BitVectorTmpl copy ctor.
318 BitVector(const BitVector &RHS) : Size(RHS.size()), Alloc(RHS.Alloc) { 318 BitVectorTmpl(const BitVectorTmpl &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); 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 BitVectorTmpl(BitVectorTmpl &&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 ~BitVectorTmpl() {
337 if (Bits != nullptr) { 337 if (Bits != nullptr) {
338 Alloc.deallocate(Bits, Capacity); 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; }
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
413 void clear() { Size = 0; } 413 void clear() { Size = 0; }
414 414
415 /// resize - Grow or shrink the bitvector. 415 /// resize - Grow or shrink the bitvector.
416 void resize(unsigned N, bool t = false) { 416 void resize(unsigned N, bool t = false) {
417 if (N > Capacity * BITWORD_SIZE) { 417 if (N > Capacity * BITWORD_SIZE) {
418 unsigned OldCapacity = Capacity; 418 unsigned OldCapacity = Capacity;
419 grow(N); 419 grow(N);
420 init_words(&Bits[OldCapacity], (Capacity - OldCapacity), t); 420 init_words(&Bits[OldCapacity], (Capacity - OldCapacity), t);
421 } 421 }
422 422
423 // Set any old unused bits that are now included in the BitVector. This 423 // Set any old unused bits that are now included in the BitVectorTmpl. This
424 // may set bits that are not included in the new vector, but we will clear 424 // may set bits that are not included in the new vector, but we will clear
425 // them back out below. 425 // them back out below.
426 if (N > Size) 426 if (N > Size)
427 set_unused_bits(t); 427 set_unused_bits(t);
428 428
429 // Update the size, and clear out any bits that are now unused 429 // Update the size, and clear out any bits that are now unused
430 unsigned OldSize = Size; 430 unsigned OldSize = Size;
431 Size = N; 431 Size = N;
432 if (t || N < OldSize) 432 if (t || N < OldSize)
433 clear_unused_bits(); 433 clear_unused_bits();
434 } 434 }
435 435
436 void reserve(unsigned N) { 436 void reserve(unsigned N) {
437 if (N > Capacity * BITWORD_SIZE) 437 if (N > Capacity * BITWORD_SIZE)
438 grow(N); 438 grow(N);
439 } 439 }
440 440
441 // Set, reset, flip 441 // Set, reset, flip
442 BitVector &set() { 442 BitVectorTmpl &set() {
443 init_words(Bits, Capacity, true); 443 init_words(Bits, Capacity, true);
444 clear_unused_bits(); 444 clear_unused_bits();
445 return *this; 445 return *this;
446 } 446 }
447 447
448 BitVector &set(unsigned Idx) { 448 BitVectorTmpl &set(unsigned Idx) {
449 assert(Bits && "Bits never allocated"); 449 assert(Bits && "Bits never allocated");
450 Bits[Idx / BITWORD_SIZE] |= BitWord(1) << (Idx % BITWORD_SIZE); 450 Bits[Idx / BITWORD_SIZE] |= BitWord(1) << (Idx % BITWORD_SIZE);
451 return *this; 451 return *this;
452 } 452 }
453 453
454 /// set - Efficiently set a range of bits in [I, E) 454 /// set - Efficiently set a range of bits in [I, E)
455 BitVector &set(unsigned I, unsigned E) { 455 BitVectorTmpl &set(unsigned I, unsigned E) {
456 assert(I <= E && "Attempted to set backwards range!"); 456 assert(I <= E && "Attempted to set backwards range!");
457 assert(E <= size() && "Attempted to set out-of-bounds range!"); 457 assert(E <= size() && "Attempted to set out-of-bounds range!");
458 458
459 if (I == E) 459 if (I == E)
460 return *this; 460 return *this;
461 461
462 if (I / BITWORD_SIZE == E / BITWORD_SIZE) { 462 if (I / BITWORD_SIZE == E / BITWORD_SIZE) {
463 BitWord EMask = 1UL << (E % BITWORD_SIZE); 463 BitWord EMask = 1UL << (E % BITWORD_SIZE);
464 BitWord IMask = 1UL << (I % BITWORD_SIZE); 464 BitWord IMask = 1UL << (I % BITWORD_SIZE);
465 BitWord Mask = EMask - IMask; 465 BitWord Mask = EMask - IMask;
466 Bits[I / BITWORD_SIZE] |= Mask; 466 Bits[I / BITWORD_SIZE] |= Mask;
467 return *this; 467 return *this;
468 } 468 }
469 469
470 BitWord PrefixMask = ~0UL << (I % BITWORD_SIZE); 470 BitWord PrefixMask = ~0UL << (I % BITWORD_SIZE);
471 Bits[I / BITWORD_SIZE] |= PrefixMask; 471 Bits[I / BITWORD_SIZE] |= PrefixMask;
472 I = llvm::RoundUpToAlignment(I, BITWORD_SIZE); 472 I = llvm::RoundUpToAlignment(I, BITWORD_SIZE);
473 473
474 for (; I + BITWORD_SIZE <= E; I += BITWORD_SIZE) 474 for (; I + BITWORD_SIZE <= E; I += BITWORD_SIZE)
475 Bits[I / BITWORD_SIZE] = ~0UL; 475 Bits[I / BITWORD_SIZE] = ~0UL;
476 476
477 BitWord PostfixMask = (1UL << (E % BITWORD_SIZE)) - 1; 477 BitWord PostfixMask = (1UL << (E % BITWORD_SIZE)) - 1;
478 if (I < E) 478 if (I < E)
479 Bits[I / BITWORD_SIZE] |= PostfixMask; 479 Bits[I / BITWORD_SIZE] |= PostfixMask;
480 480
481 return *this; 481 return *this;
482 } 482 }
483 483
484 BitVector &reset() { 484 BitVectorTmpl &reset() {
485 init_words(Bits, Capacity, false); 485 init_words(Bits, Capacity, false);
486 return *this; 486 return *this;
487 } 487 }
488 488
489 BitVector &reset(unsigned Idx) { 489 BitVectorTmpl &reset(unsigned Idx) {
490 Bits[Idx / BITWORD_SIZE] &= ~(BitWord(1) << (Idx % BITWORD_SIZE)); 490 Bits[Idx / BITWORD_SIZE] &= ~(BitWord(1) << (Idx % BITWORD_SIZE));
491 return *this; 491 return *this;
492 } 492 }
493 493
494 /// reset - Efficiently reset a range of bits in [I, E) 494 /// reset - Efficiently reset a range of bits in [I, E)
495 BitVector &reset(unsigned I, unsigned E) { 495 BitVectorTmpl &reset(unsigned I, unsigned E) {
496 assert(I <= E && "Attempted to reset backwards range!"); 496 assert(I <= E && "Attempted to reset backwards range!");
497 assert(E <= size() && "Attempted to reset out-of-bounds range!"); 497 assert(E <= size() && "Attempted to reset out-of-bounds range!");
498 498
499 if (I == E) 499 if (I == E)
500 return *this; 500 return *this;
501 501
502 if (I / BITWORD_SIZE == E / BITWORD_SIZE) { 502 if (I / BITWORD_SIZE == E / BITWORD_SIZE) {
503 BitWord EMask = 1UL << (E % BITWORD_SIZE); 503 BitWord EMask = 1UL << (E % BITWORD_SIZE);
504 BitWord IMask = 1UL << (I % BITWORD_SIZE); 504 BitWord IMask = 1UL << (I % BITWORD_SIZE);
505 BitWord Mask = EMask - IMask; 505 BitWord Mask = EMask - IMask;
506 Bits[I / BITWORD_SIZE] &= ~Mask; 506 Bits[I / BITWORD_SIZE] &= ~Mask;
507 return *this; 507 return *this;
508 } 508 }
509 509
510 BitWord PrefixMask = ~0UL << (I % BITWORD_SIZE); 510 BitWord PrefixMask = ~0UL << (I % BITWORD_SIZE);
511 Bits[I / BITWORD_SIZE] &= ~PrefixMask; 511 Bits[I / BITWORD_SIZE] &= ~PrefixMask;
512 I = llvm::RoundUpToAlignment(I, BITWORD_SIZE); 512 I = llvm::RoundUpToAlignment(I, BITWORD_SIZE);
513 513
514 for (; I + BITWORD_SIZE <= E; I += BITWORD_SIZE) 514 for (; I + BITWORD_SIZE <= E; I += BITWORD_SIZE)
515 Bits[I / BITWORD_SIZE] = 0UL; 515 Bits[I / BITWORD_SIZE] = 0UL;
516 516
517 BitWord PostfixMask = (1UL << (E % BITWORD_SIZE)) - 1; 517 BitWord PostfixMask = (1UL << (E % BITWORD_SIZE)) - 1;
518 if (I < E) 518 if (I < E)
519 Bits[I / BITWORD_SIZE] &= ~PostfixMask; 519 Bits[I / BITWORD_SIZE] &= ~PostfixMask;
520 520
521 return *this; 521 return *this;
522 } 522 }
523 523
524 BitVector &flip() { 524 BitVectorTmpl &flip() {
525 for (unsigned i = 0; i < NumBitWords(size()); ++i) 525 for (unsigned i = 0; i < NumBitWords(size()); ++i)
526 Bits[i] = ~Bits[i]; 526 Bits[i] = ~Bits[i];
527 clear_unused_bits(); 527 clear_unused_bits();
528 return *this; 528 return *this;
529 } 529 }
530 530
531 BitVector &flip(unsigned Idx) { 531 BitVectorTmpl &flip(unsigned Idx) {
532 Bits[Idx / BITWORD_SIZE] ^= BitWord(1) << (Idx % BITWORD_SIZE); 532 Bits[Idx / BITWORD_SIZE] ^= BitWord(1) << (Idx % BITWORD_SIZE);
533 return *this; 533 return *this;
534 } 534 }
535 535
536 // Indexing. 536 // Indexing.
537 reference operator[](unsigned Idx) { 537 reference operator[](unsigned Idx) {
538 assert(Idx < Size && "Out-of-bounds Bit access."); 538 assert(Idx < Size && "Out-of-bounds Bit access.");
539 return reference(*this, Idx); 539 return reference(*this, Idx);
540 } 540 }
541 541
542 bool operator[](unsigned Idx) const { 542 bool operator[](unsigned Idx) const {
543 assert(Idx < Size && "Out-of-bounds Bit access."); 543 assert(Idx < Size && "Out-of-bounds Bit access.");
544 BitWord Mask = BitWord(1) << (Idx % BITWORD_SIZE); 544 BitWord Mask = BitWord(1) << (Idx % BITWORD_SIZE);
545 return (Bits[Idx / BITWORD_SIZE] & Mask) != 0; 545 return (Bits[Idx / BITWORD_SIZE] & Mask) != 0;
546 } 546 }
547 547
548 bool test(unsigned Idx) const { return (*this)[Idx]; } 548 bool test(unsigned Idx) const { return (*this)[Idx]; }
549 549
550 /// Test if any common bits are set. 550 /// Test if any common bits are set.
551 bool anyCommon(const BitVector &RHS) const { 551 bool anyCommon(const BitVectorTmpl &RHS) const {
552 unsigned ThisWords = NumBitWords(size()); 552 unsigned ThisWords = NumBitWords(size());
553 unsigned RHSWords = NumBitWords(RHS.size()); 553 unsigned RHSWords = NumBitWords(RHS.size());
554 for (unsigned i = 0, e = std::min(ThisWords, RHSWords); i != e; ++i) 554 for (unsigned i = 0, e = std::min(ThisWords, RHSWords); i != e; ++i)
555 if (Bits[i] & RHS.Bits[i]) 555 if (Bits[i] & RHS.Bits[i])
556 return true; 556 return true;
557 return false; 557 return false;
558 } 558 }
559 559
560 // Comparison operators. 560 // Comparison operators.
561 bool operator==(const BitVector &RHS) const { 561 bool operator==(const BitVectorTmpl &RHS) const {
562 unsigned ThisWords = NumBitWords(size()); 562 unsigned ThisWords = NumBitWords(size());
563 unsigned RHSWords = NumBitWords(RHS.size()); 563 unsigned RHSWords = NumBitWords(RHS.size());
564 unsigned i; 564 unsigned i;
565 for (i = 0; i != std::min(ThisWords, RHSWords); ++i) 565 for (i = 0; i != std::min(ThisWords, RHSWords); ++i)
566 if (Bits[i] != RHS.Bits[i]) 566 if (Bits[i] != RHS.Bits[i])
567 return false; 567 return false;
568 568
569 // Verify that any extra words are all zeros. 569 // Verify that any extra words are all zeros.
570 if (i != ThisWords) { 570 if (i != ThisWords) {
571 for (; i != ThisWords; ++i) 571 for (; i != ThisWords; ++i)
572 if (Bits[i]) 572 if (Bits[i])
573 return false; 573 return false;
574 } else if (i != RHSWords) { 574 } else if (i != RHSWords) {
575 for (; i != RHSWords; ++i) 575 for (; i != RHSWords; ++i)
576 if (RHS.Bits[i]) 576 if (RHS.Bits[i])
577 return false; 577 return false;
578 } 578 }
579 return true; 579 return true;
580 } 580 }
581 581
582 bool operator!=(const BitVector &RHS) const { return !(*this == RHS); } 582 bool operator!=(const BitVectorTmpl &RHS) const { return !(*this == RHS); }
583 583
584 /// Intersection, union, disjoint union. 584 /// Intersection, union, disjoint union.
585 BitVector &operator&=(const BitVector &RHS) { 585 BitVectorTmpl &operator&=(const BitVectorTmpl &RHS) {
586 unsigned ThisWords = NumBitWords(size()); 586 unsigned ThisWords = NumBitWords(size());
587 unsigned RHSWords = NumBitWords(RHS.size()); 587 unsigned RHSWords = NumBitWords(RHS.size());
588 unsigned i; 588 unsigned i;
589 for (i = 0; i != std::min(ThisWords, RHSWords); ++i) 589 for (i = 0; i != std::min(ThisWords, RHSWords); ++i)
590 Bits[i] &= RHS.Bits[i]; 590 Bits[i] &= RHS.Bits[i];
591 591
592 // Any bits that are just in this bitvector become zero, because they aren't 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 593 // in the RHS bit vector. Any words only in RHS are ignored because they
594 // are already zero in the LHS. 594 // are already zero in the LHS.
595 for (; i != ThisWords; ++i) 595 for (; i != ThisWords; ++i)
596 Bits[i] = 0; 596 Bits[i] = 0;
597 597
598 return *this; 598 return *this;
599 } 599 }
600 600
601 /// reset - Reset bits that are set in RHS. Same as *this &= ~RHS. 601 /// reset - Reset bits that are set in RHS. Same as *this &= ~RHS.
602 BitVector &reset(const BitVector &RHS) { 602 BitVectorTmpl &reset(const BitVectorTmpl &RHS) {
603 unsigned ThisWords = NumBitWords(size()); 603 unsigned ThisWords = NumBitWords(size());
604 unsigned RHSWords = NumBitWords(RHS.size()); 604 unsigned RHSWords = NumBitWords(RHS.size());
605 unsigned i; 605 unsigned i;
606 for (i = 0; i != std::min(ThisWords, RHSWords); ++i) 606 for (i = 0; i != std::min(ThisWords, RHSWords); ++i)
607 Bits[i] &= ~RHS.Bits[i]; 607 Bits[i] &= ~RHS.Bits[i];
608 return *this; 608 return *this;
609 } 609 }
610 610
611 /// test - Check if (This - RHS) is zero. 611 /// test - Check if (This - RHS) is zero.
612 /// This is the same as reset(RHS) and any(). 612 /// This is the same as reset(RHS) and any().
613 bool test(const BitVector &RHS) const { 613 bool test(const BitVectorTmpl &RHS) const {
614 unsigned ThisWords = NumBitWords(size()); 614 unsigned ThisWords = NumBitWords(size());
615 unsigned RHSWords = NumBitWords(RHS.size()); 615 unsigned RHSWords = NumBitWords(RHS.size());
616 unsigned i; 616 unsigned i;
617 for (i = 0; i != std::min(ThisWords, RHSWords); ++i) 617 for (i = 0; i != std::min(ThisWords, RHSWords); ++i)
618 if ((Bits[i] & ~RHS.Bits[i]) != 0) 618 if ((Bits[i] & ~RHS.Bits[i]) != 0)
619 return true; 619 return true;
620 620
621 for (; i != ThisWords; ++i) 621 for (; i != ThisWords; ++i)
622 if (Bits[i] != 0) 622 if (Bits[i] != 0)
623 return true; 623 return true;
624 624
625 return false; 625 return false;
626 } 626 }
627 627
628 BitVector &operator|=(const BitVector &RHS) { 628 BitVectorTmpl &operator|=(const BitVectorTmpl &RHS) {
629 if (size() < RHS.size()) 629 if (size() < RHS.size())
630 resize(RHS.size()); 630 resize(RHS.size());
631 for (size_t i = 0, e = NumBitWords(RHS.size()); i != e; ++i) 631 for (size_t i = 0, e = NumBitWords(RHS.size()); i != e; ++i)
632 Bits[i] |= RHS.Bits[i]; 632 Bits[i] |= RHS.Bits[i];
633 return *this; 633 return *this;
634 } 634 }
635 635
636 BitVector &operator^=(const BitVector &RHS) { 636 BitVectorTmpl &operator^=(const BitVectorTmpl &RHS) {
637 if (size() < RHS.size()) 637 if (size() < RHS.size())
638 resize(RHS.size()); 638 resize(RHS.size());
639 for (size_t i = 0, e = NumBitWords(RHS.size()); i != e; ++i) 639 for (size_t i = 0, e = NumBitWords(RHS.size()); i != e; ++i)
640 Bits[i] ^= RHS.Bits[i]; 640 Bits[i] ^= RHS.Bits[i];
641 return *this; 641 return *this;
642 } 642 }
643 643
644 // Assignment operator. 644 // Assignment operator.
645 const BitVector &operator=(const BitVector &RHS) { 645 const BitVectorTmpl &operator=(const BitVectorTmpl &RHS) {
646 if (this == &RHS) 646 if (this == &RHS)
647 return *this; 647 return *this;
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 658 // Currently, BitVectorTmpl is only used by liveness analysis. With the
659 // following assert, we make sure BitVectors grow in a single step from 0 to 659 // following assert, we make sure BitVectorTmpls grow in a single step from
660 // their final capacity, rather than growing slowly and "leaking" memory in 660 // 0 to their final capacity, rather than growing slowly and "leaking"
661 // the process. 661 // memory in the process.
662 assert(Capacity == 0); 662 assert(Capacity == 0);
663 663
664 // Grow the bitvector to have enough elements. 664 // Grow the bitvector to have enough elements.
665 const auto OldCapacity = Capacity; 665 const auto OldCapacity = Capacity;
666 Capacity = RHSWords; 666 Capacity = RHSWords;
667 assert(Capacity > 0 && "negative capacity?"); 667 assert(Capacity > 0 && "negative capacity?");
668 BitWord *NewBits = Alloc.allocate(Capacity); 668 BitWord *NewBits = Alloc.allocate(Capacity);
669 std::memcpy(NewBits, RHS.Bits, Capacity * sizeof(BitWord)); 669 std::memcpy(NewBits, RHS.Bits, Capacity * sizeof(BitWord));
670 670
671 // Destroy the old bits. 671 // Destroy the old bits.
672 Alloc.deallocate(Bits, OldCapacity); 672 Alloc.deallocate(Bits, OldCapacity);
673 Bits = NewBits; 673 Bits = NewBits;
674 674
675 return *this; 675 return *this;
676 } 676 }
677 677
678 const BitVector &operator=(BitVector &&RHS) { 678 const BitVectorTmpl &operator=(BitVectorTmpl &&RHS) {
679 if (this == &RHS) 679 if (this == &RHS)
680 return *this; 680 return *this;
681 681
682 Alloc.deallocate(Bits, Capacity); 682 Alloc.deallocate(Bits, Capacity);
683 Bits = RHS.Bits; 683 Bits = RHS.Bits;
684 Size = RHS.Size; 684 Size = RHS.Size;
685 Capacity = RHS.Capacity; 685 Capacity = RHS.Capacity;
686 686
687 RHS.Bits = nullptr; 687 RHS.Bits = nullptr;
688 688
689 return *this; 689 return *this;
690 } 690 }
691 691
692 void swap(BitVector &RHS) { 692 void swap(BitVectorTmpl &RHS) {
693 std::swap(Bits, RHS.Bits); 693 std::swap(Bits, RHS.Bits);
694 std::swap(Size, RHS.Size); 694 std::swap(Size, RHS.Size);
695 std::swap(Capacity, RHS.Capacity); 695 std::swap(Capacity, RHS.Capacity);
696 } 696 }
697 697
698 //===--------------------------------------------------------------------===// 698 //===--------------------------------------------------------------------===//
699 // Portable bit mask operations. 699 // Portable bit mask operations.
700 //===--------------------------------------------------------------------===// 700 //===--------------------------------------------------------------------===//
701 // 701 //
702 // These methods all operate on arrays of uint32_t, each holding 32 bits. The 702 // These methods all operate on arrays of uint32_t, each holding 32 bits. The
703 // fixed word size makes it easier to work with literal bit vector constants 703 // fixed word size makes it easier to work with literal bit vector constants
704 // in portable code. 704 // in portable code.
705 // 705 //
706 // The LSB in each word is the lowest numbered bit. The size of a portable 706 // The LSB in each word is the lowest numbered bit. The size of a portable
707 // bit mask is always a whole multiple of 32 bits. If no bit mask size is 707 // bit mask is always a whole multiple of 32 bits. If no bit mask size is
708 // given, the bit mask is assumed to cover the entire BitVector. 708 // given, the bit mask is assumed to cover the entire BitVectorTmpl.
709 709
710 /// setBitsInMask - Add '1' bits from Mask to this vector. Don't resize. 710 /// setBitsInMask - Add '1' bits from Mask to this vector. Don't resize.
711 /// This computes "*this |= Mask". 711 /// This computes "*this |= Mask".
712 void setBitsInMask(const uint32_t *Mask, unsigned MaskWords = ~0u) { 712 void setBitsInMask(const uint32_t *Mask, unsigned MaskWords = ~0u) {
713 applyMask<true, false>(Mask, MaskWords); 713 applyMask<true, false>(Mask, MaskWords);
714 } 714 }
715 715
716 /// clearBitsInMask - Clear any bits in this vector that are set in Mask. 716 /// clearBitsInMask - Clear any bits in this vector that are set in Mask.
717 /// Don't resize. This computes "*this &= ~Mask". 717 /// Don't resize. This computes "*this &= ~Mask".
718 void clearBitsInMask(const uint32_t *Mask, unsigned MaskWords = ~0u) { 718 void clearBitsInMask(const uint32_t *Mask, unsigned MaskWords = ~0u) {
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
800 if (AddBits) 800 if (AddBits)
801 Bits[i] |= BitWord(M) << b; 801 Bits[i] |= BitWord(M) << b;
802 else 802 else
803 Bits[i] &= ~(BitWord(M) << b); 803 Bits[i] &= ~(BitWord(M) << b);
804 } 804 }
805 if (AddBits) 805 if (AddBits)
806 clear_unused_bits(); 806 clear_unused_bits();
807 } 807 }
808 }; 808 };
809 809
810 using BitVector = BitVectorTmpl<CfgLocalAllocator>;
811
810 } // end of namespace Ice 812 } // end of namespace Ice
811 813
812 namespace std { 814 namespace std {
813 /// Implement std::swap in terms of BitVector swap. 815 /// Implement std::swap in terms of BitVectorTmpl swap.
814 inline void swap(Ice::BitVector &LHS, Ice::BitVector &RHS) { LHS.swap(RHS); } 816 template <template <typename> class AT>
817 inline void swap(Ice::BitVectorTmpl<AT> &LHS, Ice::BitVectorTmpl<AT> &RHS) {
818 LHS.swap(RHS);
819 }
815 } 820 }
816 821
817 #endif // SUBZERO_SRC_ICEBITVECTOR_H 822 #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