[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:
parent
4f065cd141
commit
234d1f8a4b
@ -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_;
|
||||||
|
@ -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.
|
||||||
|
@ -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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user