Quick: Kill unreachable blocks instead of just hiding them.

This changes the block type from kDalvikByteCode to kDead
and properly cleans up predecessors and MIRGraph::catches_.

Bug: 18626174
Change-Id: I268bf68f7947604bcb82caf95ee79c6831ee6e2a
diff --git a/compiler/dex/mir_graph.cc b/compiler/dex/mir_graph.cc
index 023abca..4ab083c 100644
--- a/compiler/dex/mir_graph.cc
+++ b/compiler/dex/mir_graph.cc
@@ -2222,21 +2222,7 @@
   }
 }
 
-void BasicBlock::Hide(MIRGraph* mir_graph) {
-  // First lets make it a dalvik bytecode block so it doesn't have any special meaning.
-  block_type = kDalvikByteCode;
-
-  // Mark it as hidden.
-  hidden = true;
-
-  // Detach it from its MIRs so we don't generate code for them. Also detached MIRs
-  // are updated to know that they no longer have a parent.
-  for (MIR* mir = first_mir_insn; mir != nullptr; mir = mir->next) {
-    mir->bb = NullBasicBlockId;
-  }
-  first_mir_insn = nullptr;
-  last_mir_insn = nullptr;
-
+void BasicBlock::Kill(MIRGraph* mir_graph) {
   for (BasicBlockId pred_id : predecessors) {
     BasicBlock* pred_bb = mir_graph->GetBasicBlock(pred_id);
     DCHECK(pred_bb != nullptr);
@@ -2244,24 +2230,11 @@
     // Sadly we have to go through the children by hand here.
     pred_bb->ReplaceChild(id, NullBasicBlockId);
   }
+  predecessors.clear();
 
-  // Iterate through children of bb we are hiding.
-  ChildBlockIterator successorChildIter(this, mir_graph);
-
-  for (BasicBlock* childPtr = successorChildIter.Next(); childPtr != 0; childPtr = successorChildIter.Next()) {
-    // Erase this predecessor from child.
-    childPtr->ErasePredecessor(id);
-  }
-
-  // Remove link to children.
-  taken = NullBasicBlockId;
-  fall_through = NullBasicBlockId;
-  successor_block_list_type = kNotUsed;
+  KillUnreachable(mir_graph);
 }
 
-/*
- * Kill an unreachable block and all blocks that become unreachable by killing this one.
- */
 void BasicBlock::KillUnreachable(MIRGraph* mir_graph) {
   DCHECK(predecessors.empty());  // Unreachable.
 
diff --git a/compiler/dex/mir_graph.h b/compiler/dex/mir_graph.h
index 1a18841..263f47c 100644
--- a/compiler/dex/mir_graph.h
+++ b/compiler/dex/mir_graph.h
@@ -410,15 +410,15 @@
   void ResetOptimizationFlags(uint16_t reset_flags);
 
   /**
-   * @brief Hide the BasicBlock.
-   * @details Set it to kDalvikByteCode, set hidden to true, remove all MIRs,
-   *          remove itself from any predecessor edges, remove itself from any
-   *          child's predecessor array.
+   * @brief Kill the BasicBlock.
+   * @details Unlink predecessors to make this block unreachable, then KillUnreachable().
    */
-  void Hide(MIRGraph* mir_graph);
+  void Kill(MIRGraph* mir_graph);
 
   /**
-   *  @brief Kill the unreachable block and all blocks that become unreachable by killing this one.
+   * @brief Kill the unreachable block and all blocks that become unreachable by killing this one.
+   * @details Set the block type to kDead and set hidden to true, remove all MIRs,
+   *          unlink all successors and recursively kill successors that become unreachable.
    */
   void KillUnreachable(MIRGraph* mir_graph);
 
diff --git a/compiler/dex/ssa_transformation.cc b/compiler/dex/ssa_transformation.cc
index ed33882..b803462 100644
--- a/compiler/dex/ssa_transformation.cc
+++ b/compiler/dex/ssa_transformation.cc
@@ -104,11 +104,11 @@
   num_reachable_blocks_ = dfs_order_.size();
 
   if (num_reachable_blocks_ != num_blocks_) {
-    // Hide all unreachable blocks.
+    // Kill all unreachable blocks.
     AllNodesIterator iter(this);
     for (BasicBlock* bb = iter.Next(); bb != NULL; bb = iter.Next()) {
       if (!bb->visited) {
-        bb->Hide(this);
+        bb->Kill(this);
       }
     }
   }