Pack booleans in the already existing bit field.

Also adds is_string_char_at boolean in preparation of
[un]compressed string vectorization support.

Test: test-art-target, test-art-host
Change-Id: Ia99b28564727bf91b3d5cfc49f6d40a4dd1ffd3b
diff --git a/compiler/optimizing/loop_optimization.cc b/compiler/optimizing/loop_optimization.cc
index 5a95abd..da2acd1 100644
--- a/compiler/optimizing/loop_optimization.cc
+++ b/compiler/optimizing/loop_optimization.cc
@@ -1001,8 +1001,9 @@
       vector = new (global_allocator_) HVecStore(
           global_allocator_, org->InputAt(0), opa, opb, type, vector_length_);
     } else  {
+      bool is_string_char_at = org->AsArrayGet()->IsStringCharAt();
       vector = new (global_allocator_) HVecLoad(
-          global_allocator_, org->InputAt(0), opa, type, vector_length_);
+          global_allocator_, org->InputAt(0), opa, type, vector_length_, is_string_char_at);
     }
   } else {
     // Scalar store or load.
@@ -1010,7 +1011,9 @@
     if (opb != nullptr) {
       vector = new (global_allocator_) HArraySet(org->InputAt(0), opa, opb, type, kNoDexPc);
     } else  {
-      vector = new (global_allocator_) HArrayGet(org->InputAt(0), opa, type, kNoDexPc);
+      bool is_string_char_at = org->AsArrayGet()->IsStringCharAt();
+      vector = new (global_allocator_) HArrayGet(
+          org->InputAt(0), opa, type, kNoDexPc, is_string_char_at);
     }
   }
   vector_map_->Put(org, vector);
diff --git a/compiler/optimizing/nodes_vector.h b/compiler/optimizing/nodes_vector.h
index fb9dfb7..c9d6ff8 100644
--- a/compiler/optimizing/nodes_vector.h
+++ b/compiler/optimizing/nodes_vector.h
@@ -98,7 +98,7 @@
 
   DECLARE_ABSTRACT_INSTRUCTION(VecOperation);
 
- private:
+ protected:
   // Additional packed bits.
   static constexpr size_t kFieldType = HInstruction::kNumberOfGenericPackedBits;
   static constexpr size_t kFieldTypeSize =
@@ -107,6 +107,7 @@
   static_assert(kNumberOfVectorOpPackedBits <= kMaxNumberOfPackedBits, "Too many packed fields.");
   using TypeField = BitField<Primitive::Type, kFieldType, kFieldTypeSize>;
 
+ private:
   const size_t vector_length_;
 
   DISALLOW_COPY_AND_ASSIGN(HVecOperation);
@@ -348,22 +349,25 @@
                  bool is_unsigned,
                  bool is_rounded,
                  uint32_t dex_pc = kNoDexPc)
-      : HVecBinaryOperation(arena, left, right, packed_type, vector_length, dex_pc),
-        is_unsigned_(is_unsigned),
-        is_rounded_(is_rounded) {
+      : HVecBinaryOperation(arena, left, right, packed_type, vector_length, dex_pc) {
     DCHECK(left->IsVecOperation() && right->IsVecOperation());
     DCHECK_EQ(left->AsVecOperation()->GetPackedType(), packed_type);
     DCHECK_EQ(right->AsVecOperation()->GetPackedType(), packed_type);
+    SetPackedFlag<kFieldHAddIsUnsigned>(is_unsigned);
+    SetPackedFlag<kFieldHAddIsRounded>(is_rounded);
   }
 
-  bool IsUnsigned() const { return is_unsigned_; }
-  bool IsRounded() const { return is_rounded_; }
+  bool IsUnsigned() const { return GetPackedFlag<kFieldHAddIsUnsigned>(); }
+  bool IsRounded() const { return GetPackedFlag<kFieldHAddIsRounded>(); }
 
   DECLARE_INSTRUCTION(VecHalvingAdd);
 
  private:
-  bool is_unsigned_;
-  bool is_rounded_;
+  // Additional packed bits.
+  static constexpr size_t kFieldHAddIsUnsigned = HVecOperation::kNumberOfVectorOpPackedBits;
+  static constexpr size_t kFieldHAddIsRounded = kFieldHAddIsUnsigned + 1;
+  static constexpr size_t kNumberOfHAddPackedBits = kFieldHAddIsRounded + 1;
+  static_assert(kNumberOfHAddPackedBits <= kMaxNumberOfPackedBits, "Too many packed fields.");
 
   DISALLOW_COPY_AND_ASSIGN(HVecHalvingAdd);
 };
@@ -687,6 +691,7 @@
            HInstruction* index,
            Primitive::Type packed_type,
            size_t vector_length,
+           bool is_string_char_at,
            uint32_t dex_pc = kNoDexPc)
       : HVecMemoryOperation(arena,
                             packed_type,
@@ -696,9 +701,18 @@
                             dex_pc) {
     SetRawInputAt(0, base);
     SetRawInputAt(1, index);
+    SetPackedFlag<kFieldIsStringCharAt>(is_string_char_at);
   }
   DECLARE_INSTRUCTION(VecLoad);
+
+  bool IsStringCharAt() const { return GetPackedFlag<kFieldIsStringCharAt>(); }
+
  private:
+  // Additional packed bits.
+  static constexpr size_t kFieldIsStringCharAt = HVecOperation::kNumberOfVectorOpPackedBits;
+  static constexpr size_t kNumberOfVecLoadPackedBits = kFieldIsStringCharAt + 1;
+  static_assert(kNumberOfVecLoadPackedBits <= kMaxNumberOfPackedBits, "Too many packed fields.");
+
   DISALLOW_COPY_AND_ASSIGN(HVecLoad);
 };