Compile-time tuning: assembly phase

Not as much compile-time gain from reworking the assembly phase as I'd
hoped, but still worthwhile.  Should see ~2% improvement thanks to
the assembly rework.  On the other hand, expect some huge gains for some
application thanks to better detection of large machine-generated init
methods.  Thinkfree shows a 25% improvement.

The major assembly change was to establish thread the LIR nodes that
require fixup into a fixup chain.  Only those are processed during the
final assembly pass(es).  This doesn't help for methods which only
require a single pass to assemble, but does speed up the larger methods
which required multiple assembly passes.

Also replaced the block_map_ basic block lookup table (which contained
space for a BasicBlock* for each dex instruction unit) with a block id
map - cutting its space requirements by half in a 32-bit pointer
environment.

Changes:
  o Reduce size of LIR struct by 12.5% (one of the big memory users)
  o Repurpose the use/def portion of the LIR after optimization complete.
  o Encode instruction bits to LIR
  o Thread LIR nodes requiring pc fixup
  o Change follow-on assembly passes to only consider fixup LIRs
  o Switch on pc-rel fixup kind
  o Fast-path for small methods - single pass assembly
  o Avoid using cb[n]z for null checks (almost always exceed displacement)
  o Improve detection of large initialization methods.
  o Rework def/use flag setup.
  o Remove a sequential search from FindBlock using lookup table of 16-bit
    block ids rather than full block pointers.
  o Eliminate pcRelFixup and use fixup kind instead.
  o Add check for 16-bit overflow on dex offset.

Change-Id: I4c6615f83fed46f84629ad6cfe4237205a9562b4
diff --git a/compiler/dex/quick/mir_to_lir-inl.h b/compiler/dex/quick/mir_to_lir-inl.h
index 0ca8d8d..314c57e 100644
--- a/compiler/dex/quick/mir_to_lir-inl.h
+++ b/compiler/dex/quick/mir_to_lir-inl.h
@@ -58,7 +58,8 @@
   if ((opcode == kPseudoTargetLabel) || (opcode == kPseudoSafepointPC) ||
       (opcode == kPseudoExportedPC)) {
     // Always make labels scheduling barriers
-    insn->use_mask = insn->def_mask = ENCODE_ALL;
+    DCHECK(!insn->flags.use_def_invalid);
+    insn->u.m.use_mask = insn->u.m.def_mask = ENCODE_ALL;
   }
   return insn;
 }
@@ -141,20 +142,21 @@
 inline void Mir2Lir::SetupResourceMasks(LIR* lir) {
   int opcode = lir->opcode;
 
-  if (opcode <= 0) {
-    lir->use_mask = lir->def_mask = 0;
+  if ((opcode < 0) && (opcode != kPseudoBarrier)) {
+    lir->flags.fixup = kFixupLabel;
     return;
   }
 
   uint64_t flags = GetTargetInstFlags(opcode);
 
   if (flags & NEEDS_FIXUP) {
-    lir->flags.pcRelFixup = true;
+    // Note: target-specific setup may specialize the fixup kind.
+    lir->flags.fixup = kFixupLabel;
   }
 
   /* 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 (flags & (IS_LOAD | IS_STORE)) {
     /* Default to heap - will catch specialized classes later */
@@ -166,39 +168,44 @@
    * turn will trash everything.
    */
   if (flags & IS_BRANCH) {
-    lir->def_mask = lir->use_mask = ENCODE_ALL;
+    lir->u.m.def_mask = lir->u.m.use_mask = ENCODE_ALL;
     return;
   }
 
   if (flags & REG_DEF0) {
-    SetupRegMask(&lir->def_mask, lir->operands[0]);
+    SetupRegMask(&lir->u.m.def_mask, lir->operands[0]);
   }
 
   if (flags & REG_DEF1) {
-    SetupRegMask(&lir->def_mask, lir->operands[1]);
+    SetupRegMask(&lir->u.m.def_mask, lir->operands[1]);
   }
 
+  if (flags & REG_USE0) {
+    SetupRegMask(&lir->u.m.use_mask, lir->operands[0]);
+  }
+
+  if (flags & REG_USE1) {
+    SetupRegMask(&lir->u.m.use_mask, lir->operands[1]);
+  }
+
+  if (flags & REG_USE2) {
+    SetupRegMask(&lir->u.m.use_mask, lir->operands[2]);
+  }
+
+  if (flags & REG_USE3) {
+    SetupRegMask(&lir->u.m.use_mask, lir->operands[3]);
+  }
 
   if (flags & SETS_CCODES) {
-    lir->def_mask |= ENCODE_CCODE;
-  }
-
-  if (flags & (REG_USE0 | REG_USE1 | REG_USE2 | REG_USE3)) {
-    int i;
-
-    for (i = 0; i < 4; i++) {
-      if (flags & (1 << (kRegUse0 + i))) {
-        SetupRegMask(&lir->use_mask, lir->operands[i]);
-      }
-    }
+    lir->u.m.def_mask |= ENCODE_CCODE;
   }
 
   if (flags & USES_CCODES) {
-    lir->use_mask |= ENCODE_CCODE;
+    lir->u.m.use_mask |= ENCODE_CCODE;
   }
 
   // Handle target-specific actions
-  SetupTargetResourceMasks(lir);
+  SetupTargetResourceMasks(lir, flags);
 }
 
 inline art::Mir2Lir::RegisterInfo* Mir2Lir::GetRegInfo(int reg) {