Rewrite use/def masks to support 128 bits.

Reduce LIR memory usage by holding masks by pointers in the
LIR rather than directly and using pre-defined const masks
for the common cases, allocating very few on the arena.

Change-Id: I0f6d27ef6867acd157184c8c74f9612cebfe6c16
diff --git a/compiler/dex/quick/mir_to_lir-inl.h b/compiler/dex/quick/mir_to_lir-inl.h
index 2f37520..9912101 100644
--- a/compiler/dex/quick/mir_to_lir-inl.h
+++ b/compiler/dex/quick/mir_to_lir-inl.h
@@ -57,7 +57,7 @@
       (opcode == kPseudoExportedPC)) {
     // Always make labels scheduling barriers
     DCHECK(!insn->flags.use_def_invalid);
-    insn->u.m.use_mask = insn->u.m.def_mask = ENCODE_ALL;
+    insn->u.m.use_mask = insn->u.m.def_mask = &kEncodeAll;
   }
   return insn;
 }
@@ -140,19 +140,20 @@
 /*
  * Mark the corresponding bit(s).
  */
-inline void Mir2Lir::SetupRegMask(uint64_t* mask, int reg) {
+inline void Mir2Lir::SetupRegMask(ResourceMask* mask, int reg) {
   DCHECK_EQ((reg & ~RegStorage::kRegValMask), 0);
   DCHECK(reginfo_map_.Get(reg) != nullptr) << "No info for 0x" << reg;
-  *mask |= reginfo_map_.Get(reg)->DefUseMask();
+  *mask = mask->Union(reginfo_map_.Get(reg)->DefUseMask());
 }
 
 /*
  * Set up the proper fields in the resource mask
  */
-inline void Mir2Lir::SetupResourceMasks(LIR* lir, bool leave_mem_ref) {
+inline void Mir2Lir::SetupResourceMasks(LIR* lir) {
   int opcode = lir->opcode;
 
   if (IsPseudoLirOp(opcode)) {
+    lir->u.m.use_mask = lir->u.m.def_mask = &kEncodeNone;
     if (opcode != kPseudoBarrier) {
       lir->flags.fixup = kFixupLabel;
     }
@@ -166,13 +167,27 @@
     lir->flags.fixup = kFixupLabel;
   }
 
-  /* Get the starting size of the instruction's template */
+  /* Get the starting size of the instruction's template. */
   lir->flags.size = GetInsnSize(lir);
   estimated_native_code_size_ += lir->flags.size;
-  /* Set up the mask for resources that are updated */
-  if (!leave_mem_ref && (flags & (IS_LOAD | IS_STORE))) {
-    /* Default to heap - will catch specialized classes later */
-    SetMemRefType(lir, flags & IS_LOAD, kHeapRef);
+
+  /* Set up the mask for resources. */
+  ResourceMask use_mask;
+  ResourceMask def_mask;
+
+  if (flags & (IS_LOAD | IS_STORE)) {
+    /* Set memory reference type (defaults to heap, overridden by ScopedMemRefType). */
+    if (flags & IS_LOAD) {
+      use_mask.SetBit(mem_ref_type_);
+    } else {
+      /* Currently only loads can be marked as kMustNotAlias. */
+      DCHECK(mem_ref_type_ != ResourceMask::kMustNotAlias);
+    }
+    if (flags & IS_STORE) {
+      /* Literals cannot be written to. */
+      DCHECK(mem_ref_type_ != ResourceMask::kLiteral);
+      def_mask.SetBit(mem_ref_type_);
+    }
   }
 
   /*
@@ -180,52 +195,55 @@
    * turn will trash everything.
    */
   if (flags & IS_BRANCH) {
-    lir->u.m.def_mask = lir->u.m.use_mask = ENCODE_ALL;
+    lir->u.m.def_mask = lir->u.m.use_mask = &kEncodeAll;
     return;
   }
 
   if (flags & REG_DEF0) {
-    SetupRegMask(&lir->u.m.def_mask, lir->operands[0]);
+    SetupRegMask(&def_mask, lir->operands[0]);
   }
 
   if (flags & REG_DEF1) {
-    SetupRegMask(&lir->u.m.def_mask, lir->operands[1]);
+    SetupRegMask(&def_mask, lir->operands[1]);
   }
 
   if (flags & REG_DEF2) {
-    SetupRegMask(&lir->u.m.def_mask, lir->operands[2]);
+    SetupRegMask(&def_mask, lir->operands[2]);
   }
 
   if (flags & REG_USE0) {
-    SetupRegMask(&lir->u.m.use_mask, lir->operands[0]);
+    SetupRegMask(&use_mask, lir->operands[0]);
   }
 
   if (flags & REG_USE1) {
-    SetupRegMask(&lir->u.m.use_mask, lir->operands[1]);
+    SetupRegMask(&use_mask, lir->operands[1]);
   }
 
   if (flags & REG_USE2) {
-    SetupRegMask(&lir->u.m.use_mask, lir->operands[2]);
+    SetupRegMask(&use_mask, lir->operands[2]);
   }
 
   if (flags & REG_USE3) {
-    SetupRegMask(&lir->u.m.use_mask, lir->operands[3]);
+    SetupRegMask(&use_mask, lir->operands[3]);
   }
 
   if (flags & REG_USE4) {
-    SetupRegMask(&lir->u.m.use_mask, lir->operands[4]);
+    SetupRegMask(&use_mask, lir->operands[4]);
   }
 
   if (flags & SETS_CCODES) {
-    lir->u.m.def_mask |= ENCODE_CCODE;
+    def_mask.SetBit(ResourceMask::kCCode);
   }
 
   if (flags & USES_CCODES) {
-    lir->u.m.use_mask |= ENCODE_CCODE;
+    use_mask.SetBit(ResourceMask::kCCode);
   }
 
   // Handle target-specific actions
-  SetupTargetResourceMasks(lir, flags);
+  SetupTargetResourceMasks(lir, flags, &def_mask, &use_mask);
+
+  lir->u.m.use_mask = mask_cache_.GetMask(use_mask);
+  lir->u.m.def_mask = mask_cache_.GetMask(def_mask);
 }
 
 inline art::Mir2Lir::RegisterInfo* Mir2Lir::GetRegInfo(RegStorage reg) {