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
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 @@
   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_;