summaryrefslogtreecommitdiffstats
path: root/runtime/base
diff options
context:
space:
mode:
authorDavid Brazdil <dbrazdil@google.com>2015-04-21 16:36:35 +0100
committerDavid Brazdil <dbrazdil@google.com>2015-04-21 17:17:11 +0100
commit7d275379bf490a87805852129e3fe2e8afe961e7 (patch)
treed0bbe856872c92773931c62e6881b0305a916236 /runtime/base
parent223f2f5b2a20ca8246da1523494900a2424d5956 (diff)
downloadart-7d275379bf490a87805852129e3fe2e8afe961e7.zip
art-7d275379bf490a87805852129e3fe2e8afe961e7.tar.gz
art-7d275379bf490a87805852129e3fe2e8afe961e7.tar.bz2
ART: Update loop info of all nested loops when inlining
When inlining into a nested loop, the inliner would only add the new blocks into the innermost loop info object. This patch fixes that and modifies SsaChecker to verify the property. Change-Id: I21d343a6f7d972f5b7420701f816c65ab3f20566
Diffstat (limited to 'runtime/base')
-rw-r--r--runtime/base/bit_vector.cc26
-rw-r--r--runtime/base/bit_vector.h2
-rw-r--r--runtime/base/bit_vector_test.cc44
3 files changed, 72 insertions, 0 deletions
diff --git a/runtime/base/bit_vector.cc b/runtime/base/bit_vector.cc
index c3e24a7..65cb028 100644
--- a/runtime/base/bit_vector.cc
+++ b/runtime/base/bit_vector.cc
@@ -79,6 +79,32 @@ bool BitVector::SameBitsSet(const BitVector *src) const {
return (memcmp(storage_, src->GetRawStorage(), our_highest_index * kWordBytes) == 0);
}
+bool BitVector::IsSubsetOf(const BitVector *other) const {
+ int this_highest = GetHighestBitSet();
+ int other_highest = other->GetHighestBitSet();
+
+ // If the highest bit set is -1, this is empty and a trivial subset.
+ if (this_highest < 0) {
+ return true;
+ }
+
+ // If the highest bit set is higher, this cannot be a subset.
+ if (this_highest > other_highest) {
+ return false;
+ }
+
+ // Compare each 32-bit word.
+ size_t this_highest_index = BitsToWords(this_highest + 1);
+ for (size_t i = 0; i < this_highest_index; ++i) {
+ uint32_t this_storage = storage_[i];
+ uint32_t other_storage = other->storage_[i];
+ if ((this_storage | other_storage) != other_storage) {
+ return false;
+ }
+ }
+ return true;
+}
+
void BitVector::Intersect(const BitVector* src) {
uint32_t src_storage_size = src->storage_size_;
diff --git a/runtime/base/bit_vector.h b/runtime/base/bit_vector.h
index 557a2ec..be4d363 100644
--- a/runtime/base/bit_vector.h
+++ b/runtime/base/bit_vector.h
@@ -173,6 +173,8 @@ class BitVector {
*/
bool SameBitsSet(const BitVector *src) const;
+ bool IsSubsetOf(const BitVector *other) const;
+
// Count the number of bits that are set.
uint32_t NumSetBits() const;
diff --git a/runtime/base/bit_vector_test.cc b/runtime/base/bit_vector_test.cc
index fe3313d..c51b9b0 100644
--- a/runtime/base/bit_vector_test.cc
+++ b/runtime/base/bit_vector_test.cc
@@ -167,4 +167,48 @@ TEST(BitVector, UnionIfNotIn) {
}
}
+TEST(BitVector, Subset) {
+ {
+ BitVector first(2, true, Allocator::GetMallocAllocator());
+ BitVector second(5, true, Allocator::GetMallocAllocator());
+
+ EXPECT_TRUE(first.IsSubsetOf(&second));
+ second.SetBit(4);
+ EXPECT_TRUE(first.IsSubsetOf(&second));
+ }
+
+ {
+ BitVector first(5, true, Allocator::GetMallocAllocator());
+ BitVector second(5, true, Allocator::GetMallocAllocator());
+
+ first.SetBit(5);
+ EXPECT_FALSE(first.IsSubsetOf(&second));
+ second.SetBit(4);
+ EXPECT_FALSE(first.IsSubsetOf(&second));
+ }
+
+ {
+ BitVector first(5, true, Allocator::GetMallocAllocator());
+ BitVector second(5, true, Allocator::GetMallocAllocator());
+
+ first.SetBit(16);
+ first.SetBit(32);
+ first.SetBit(48);
+ second.SetBit(16);
+ second.SetBit(32);
+ second.SetBit(48);
+
+ EXPECT_TRUE(first.IsSubsetOf(&second));
+ second.SetBit(8);
+ EXPECT_TRUE(first.IsSubsetOf(&second));
+ second.SetBit(40);
+ EXPECT_TRUE(first.IsSubsetOf(&second));
+ second.SetBit(52);
+ EXPECT_TRUE(first.IsSubsetOf(&second));
+
+ first.SetBit(9);
+ EXPECT_FALSE(first.IsSubsetOf(&second));
+ }
+}
+
} // namespace art