[bitvector] Allow BitVector to resize

Allows BitVector to resize, updating its own data and data length to
match the new length. We can fast-path resizes which fit into the same
data length (since high bits are already zero), and replace the pattern
where a BitVector is cloned using CopyFrom.

Change-Id: If79ca782c516e93b2a27c5e335e263554d522e88
Reviewed-on: https://chromium-review.googlesource.com/539522
Reviewed-by: Michael Starzinger <mstarzinger@chromium.org>
Reviewed-by: Ross McIlroy <rmcilroy@chromium.org>
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/master@{#46101}
This commit is contained in:
Leszek Swirski 2017-06-21 15:13:18 +01:00 committed by Commit Bot
parent 4f065cd141
commit 234d1f8a4b
3 changed files with 65 additions and 22 deletions

View File

@ -83,13 +83,22 @@ class BitVector : public ZoneObject {
} }
void CopyFrom(const BitVector& other) { void CopyFrom(const BitVector& other) {
DCHECK(other.length() <= length()); DCHECK_LE(other.length(), length());
for (int i = 0; i < other.data_length_; i++) { CopyFrom(other.data_, other.data_length_);
data_[i] = other.data_[i]; }
}
for (int i = other.data_length_; i < data_length_; i++) { void Resize(int new_length, Zone* zone) {
data_[i] = 0; DCHECK_GT(new_length, length());
int new_data_length = SizeFor(new_length);
if (new_data_length > data_length_) {
uintptr_t* old_data = data_;
int old_data_length = data_length_;
data_ = zone->NewArray<uintptr_t>(new_data_length);
data_length_ = new_data_length;
CopyFrom(old_data, old_data_length);
} }
length_ = new_length;
} }
bool Contains(int i) const { bool Contains(int i) const {
@ -182,9 +191,19 @@ class BitVector : public ZoneObject {
#endif #endif
private: private:
const int length_; int length_;
const int data_length_; int data_length_;
uintptr_t* const data_; uintptr_t* data_;
void CopyFrom(uintptr_t* other_data, int other_data_length) {
DCHECK_LE(other_data_length, data_length_);
for (int i = 0; i < other_data_length; i++) {
data_[i] = other_data[i];
}
for (int i = other_data_length; i < data_length_; i++) {
data_[i] = 0;
}
}
DISALLOW_COPY_AND_ASSIGN(BitVector); DISALLOW_COPY_AND_ASSIGN(BitVector);
}; };
@ -195,8 +214,8 @@ class GrowableBitVector BASE_EMBEDDED {
class Iterator BASE_EMBEDDED { class Iterator BASE_EMBEDDED {
public: public:
Iterator(const GrowableBitVector* target, Zone* zone) Iterator(const GrowableBitVector* target, Zone* zone)
: it_(target->bits_ == NULL ? new (zone) BitVector(1, zone) : it_(target->bits_ == nullptr ? new (zone) BitVector(1, zone)
: target->bits_) {} : target->bits_) {}
bool Done() const { return it_.Done(); } bool Done() const { return it_.Done(); }
void Advance() { it_.Advance(); } void Advance() { it_.Advance(); }
int Current() const { return it_.Current(); } int Current() const { return it_.Current(); }
@ -205,7 +224,7 @@ class GrowableBitVector BASE_EMBEDDED {
BitVector::Iterator it_; BitVector::Iterator it_;
}; };
GrowableBitVector() : bits_(NULL) {} GrowableBitVector() : bits_(nullptr) {}
GrowableBitVector(int length, Zone* zone) GrowableBitVector(int length, Zone* zone)
: bits_(new (zone) BitVector(length, zone)) {} : bits_(new (zone) BitVector(length, zone)) {}
@ -226,23 +245,26 @@ class GrowableBitVector BASE_EMBEDDED {
} }
void Clear() { void Clear() {
if (bits_ != NULL) bits_->Clear(); if (bits_ != nullptr) bits_->Clear();
} }
private: private:
static const int kInitialLength = 1024; static const int kInitialLength = 1024;
bool InBitsRange(int value) const { bool InBitsRange(int value) const {
return bits_ != NULL && bits_->length() > value; return bits_ != nullptr && bits_->length() > value;
} }
void EnsureCapacity(int value, Zone* zone) { void EnsureCapacity(int value, Zone* zone) {
if (InBitsRange(value)) return; if (InBitsRange(value)) return;
int new_length = bits_ == NULL ? kInitialLength : bits_->length(); int new_length = bits_ == nullptr ? kInitialLength : bits_->length();
while (new_length <= value) new_length *= 2; while (new_length <= value) new_length *= 2;
BitVector* new_bits = new (zone) BitVector(new_length, zone);
if (bits_ != NULL) new_bits->CopyFrom(*bits_); if (bits_ == nullptr) {
bits_ = new_bits; bits_ = new (zone) BitVector(new_length, zone);
} else {
bits_->Resize(new_length, zone);
}
} }
BitVector* bits_; BitVector* bits_;

View File

@ -940,10 +940,8 @@ class SpecialRPONumberer : public ZoneObject {
size_t num_loops, ZoneVector<Backedge>* backedges) { size_t num_loops, ZoneVector<Backedge>* backedges) {
// Extend existing loop membership vectors. // Extend existing loop membership vectors.
for (LoopInfo& loop : loops_) { for (LoopInfo& loop : loops_) {
BitVector* new_members = new (zone_) loop.members->Resize(static_cast<int>(schedule_->BasicBlockCount()),
BitVector(static_cast<int>(schedule_->BasicBlockCount()), zone_); zone_);
new_members->CopyFrom(*loop.members);
loop.members = new_members;
} }
// Extend loop information vector. // Extend loop information vector.

View File

@ -119,4 +119,27 @@ TEST(BitVector) {
CHECK(!r.Contains(32)); CHECK(!r.Contains(32));
CHECK(r.Contains(33)); CHECK(r.Contains(33));
} }
{
BitVector v(35, &zone);
v.Add(32);
v.Add(33);
CHECK(v.Contains(32));
CHECK(v.Contains(33));
CHECK(!v.Contains(22));
CHECK(!v.Contains(34));
v.Resize(50, &zone);
CHECK(v.Contains(32));
CHECK(v.Contains(33));
CHECK(!v.Contains(22));
CHECK(!v.Contains(34));
CHECK(!v.Contains(43));
v.Resize(300, &zone);
CHECK(v.Contains(32));
CHECK(v.Contains(33));
CHECK(!v.Contains(22));
CHECK(!v.Contains(34));
CHECK(!v.Contains(43));
CHECK(!v.Contains(243));
}
} }