Remove the link from dalvik instruction back to kMirOpCheck.

Free the MIR::meta for another use on PUT/GET instructions.

Change-Id: Ic5a5cc5026e2076031d7b8ce7f2b36c185bfc93a
diff --git a/compiler/dex/local_value_numbering.cc b/compiler/dex/local_value_numbering.cc
index 75883b7..9e83210 100644
--- a/compiler/dex/local_value_numbering.cc
+++ b/compiler/dex/local_value_numbering.cc
@@ -380,9 +380,6 @@
           }
           mir->optimization_flags |= MIR_IGNORE_RANGE_CHECK;
         }
-        if (mir->meta.throw_insn != NULL) {
-          mir->meta.throw_insn->optimization_flags |= mir->optimization_flags;
-        }
         // Use side effect to note range check completed.
         (void)LookupValue(ARRAY_REF, array, index, NO_VALUE);
         // Establish value number for loaded register. Note use of memory version.
@@ -421,9 +418,6 @@
           }
           mir->optimization_flags |= MIR_IGNORE_RANGE_CHECK;
         }
-        if (mir->meta.throw_insn != NULL) {
-          mir->meta.throw_insn->optimization_flags |= mir->optimization_flags;
-        }
         // Use side effect to note range check completed.
         (void)LookupValue(ARRAY_REF, array, index, NO_VALUE);
         // Rev the memory version
@@ -447,9 +441,6 @@
         } else {
           null_checked_.insert(base);
         }
-        if (mir->meta.throw_insn != NULL) {
-          mir->meta.throw_insn->optimization_flags |= mir->optimization_flags;
-        }
         uint16_t field_ref = mir->dalvikInsn.vC;
         uint16_t memory_version = GetMemoryVersion(base, field_ref);
         if (opcode == Instruction::IGET_WIDE) {
@@ -479,9 +470,6 @@
         } else {
           null_checked_.insert(base);
         }
-        if (mir->meta.throw_insn != NULL) {
-          mir->meta.throw_insn->optimization_flags |= mir->optimization_flags;
-        }
         uint16_t field_ref = mir->dalvikInsn.vC;
         AdvanceMemoryVersion(base, field_ref);
       }
diff --git a/compiler/dex/mir_graph.cc b/compiler/dex/mir_graph.cc
index f321cda..8c90edb 100644
--- a/compiler/dex/mir_graph.cc
+++ b/compiler/dex/mir_graph.cc
@@ -126,9 +126,6 @@
   bottom_block->terminated_by_return = orig_block->terminated_by_return;
   orig_block->terminated_by_return = false;
 
-  /* Add it to the quick lookup cache */
-  dex_pc_to_block_map_.Put(bottom_block->start_offset, bottom_block->id);
-
   /* Handle the taken path */
   bottom_block->taken = orig_block->taken;
   if (bottom_block->taken != NullBasicBlockId) {
@@ -177,19 +174,29 @@
   }
 
   // Associate dex instructions in the bottom block with the new container.
-  MIR* p = bottom_block->first_mir_insn;
-  while (p != NULL) {
+  DCHECK(insn != nullptr);
+  DCHECK(insn != orig_block->first_mir_insn);
+  DCHECK(insn == bottom_block->first_mir_insn);
+  DCHECK_EQ(insn->offset, bottom_block->start_offset);
+  DCHECK(static_cast<int>(insn->dalvikInsn.opcode) == kMirOpCheck ||
+         !IsPseudoMirOp(insn->dalvikInsn.opcode));
+  DCHECK_EQ(dex_pc_to_block_map_.Get(insn->offset), orig_block->id);
+  MIR* p = insn;
+  dex_pc_to_block_map_.Put(p->offset, bottom_block->id);
+  while (p != bottom_block->last_mir_insn) {
+    p = p->next;
+    DCHECK(p != nullptr);
     int opcode = p->dalvikInsn.opcode;
     /*
      * Some messiness here to ensure that we only enter real opcodes and only the
      * first half of a potentially throwing instruction that has been split into
-     * CHECK and work portions.  The 2nd half of a split operation will have a non-null
-     * throw_insn pointer that refers to the 1st half.
+     * CHECK and work portions. Since the 2nd half of a split operation is always
+     * the first in a BasicBlock, we can't hit it here.
      */
-    if ((opcode == kMirOpCheck) || (!IsPseudoMirOp(opcode) && (p->meta.throw_insn == NULL))) {
+    if ((opcode == kMirOpCheck) || !IsPseudoMirOp(opcode)) {
+      DCHECK_EQ(dex_pc_to_block_map_.Get(p->offset), orig_block->id);
       dex_pc_to_block_map_.Put(p->offset, bottom_block->id);
     }
-    p = (p == bottom_block->last_mir_insn) ? NULL : p->next;
   }
 
   return bottom_block;
@@ -508,7 +515,6 @@
       static_cast<Instruction::Code>(kMirOpCheck);
   // Associate the two halves
   insn->meta.throw_insn = new_insn;
-  new_insn->meta.throw_insn = insn;
   AppendMIR(new_block, new_insn);
   return new_block;
 }
diff --git a/compiler/dex/mir_graph.h b/compiler/dex/mir_graph.h
index bbcea10..4666d1e 100644
--- a/compiler/dex/mir_graph.h
+++ b/compiler/dex/mir_graph.h
@@ -253,7 +253,7 @@
   union {
     // Incoming edges for phi node.
     BasicBlockId* phi_incoming;
-    // Establish link between two halves of throwing instructions.
+    // Establish link from check instruction (kMirOpCheck) to the actual throwing instruction.
     MIR* throw_insn;
     // Fused cmp branch condition.
     ConditionCode ccode;
diff --git a/compiler/dex/quick/mir_to_lir.cc b/compiler/dex/quick/mir_to_lir.cc
index 6281eff..0a470a5 100644
--- a/compiler/dex/quick/mir_to_lir.cc
+++ b/compiler/dex/quick/mir_to_lir.cc
@@ -762,11 +762,13 @@
       // Combine check and work halves of throwing instruction.
       MIR* work_half = mir->meta.throw_insn;
       mir->dalvikInsn.opcode = work_half->dalvikInsn.opcode;
+      mir->meta = work_half->meta;  // Whatever the work_half had, we need to copy it.
       opcode = work_half->dalvikInsn.opcode;
       SSARepresentation* ssa_rep = work_half->ssa_rep;
       work_half->ssa_rep = mir->ssa_rep;
       mir->ssa_rep = ssa_rep;
       work_half->dalvikInsn.opcode = static_cast<Instruction::Code>(kMirOpCheckPart2);
+      work_half->meta.throw_insn = mir;
     }
 
     if (opcode >= kMirOpFirst) {