Recompute dominator tree after DCE.

bug:22031382
Change-Id: Ifebe169897b76872015e3ce0ed7d0a9662f80cef
diff --git a/compiler/optimizing/boolean_simplifier.cc b/compiler/optimizing/boolean_simplifier.cc
index 8100a29..daf7d67 100644
--- a/compiler/optimizing/boolean_simplifier.cc
+++ b/compiler/optimizing/boolean_simplifier.cc
@@ -141,6 +141,12 @@
   block->MergeWith(false_block);
   block->MergeWith(merge_block);
 
+  // No need to update any dominance information, as we are simplifying
+  // a simple diamond shape, where the join block is merged with the
+  // entry block. Any following blocks would have had the join block
+  // as a dominator, and `MergeWith` handles changing that to the
+  // entry block.
+
   // Remove the original condition if it is now unused.
   if (!if_condition->HasUses()) {
     if_condition->GetBlock()->RemoveInstructionOrPhi(if_condition);
diff --git a/compiler/optimizing/dead_code_elimination.cc b/compiler/optimizing/dead_code_elimination.cc
index fdfe518..5de629d 100644
--- a/compiler/optimizing/dead_code_elimination.cc
+++ b/compiler/optimizing/dead_code_elimination.cc
@@ -68,6 +68,7 @@
   ArenaBitVector affected_loops(allocator, graph_->GetBlocks().Size(), false);
 
   MarkReachableBlocks(graph_->GetEntryBlock(), &live_blocks);
+  bool removed_one_or_more_blocks = false;
 
   // Remove all dead blocks. Iterate in post order because removal needs the
   // block's chain of dominators and nested loops need to be updated from the
@@ -84,9 +85,17 @@
       MaybeRecordDeadBlock(block);
       MarkLoopHeadersContaining(*block, &affected_loops);
       block->DisconnectAndDelete();
+      removed_one_or_more_blocks = true;
     }
   }
 
+  // If we removed at least one block, we need to recompute the full
+  // dominator tree.
+  if (removed_one_or_more_blocks) {
+    graph_->ClearDominanceInformation();
+    graph_->ComputeDominanceInformation();
+  }
+
   // Connect successive blocks created by dead branches. Order does not matter.
   for (HReversePostOrderIterator it(*graph_); !it.Done();) {
     HBasicBlock* block  = it.Current();
diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc
index 01eb2d7..3891a15 100644
--- a/compiler/optimizing/nodes.cc
+++ b/compiler/optimizing/nodes.cc
@@ -117,9 +117,24 @@
   //     dominators and the reverse post order.
   SimplifyCFG();
 
-  // (5) Compute the immediate dominator of each block. We visit
-  //     the successors of a block only when all its forward branches
-  //     have been processed.
+  // (5) Compute the dominance information and the reverse post order.
+  ComputeDominanceInformation();
+}
+
+void HGraph::ClearDominanceInformation() {
+  for (HReversePostOrderIterator it(*this); !it.Done(); it.Advance()) {
+    it.Current()->ClearDominanceInformation();
+  }
+  reverse_post_order_.Reset();
+}
+
+void HBasicBlock::ClearDominanceInformation() {
+  dominated_blocks_.Reset();
+  dominator_ = nullptr;
+}
+
+void HGraph::ComputeDominanceInformation() {
+  DCHECK(reverse_post_order_.IsEmpty());
   GrowableArray<size_t> visits(arena_, blocks_.Size());
   visits.SetSize(blocks_.Size());
   reverse_post_order_.Add(entry_block_);
@@ -1133,8 +1148,7 @@
   }
   predecessors_.Reset();
 
-  // Disconnect the block from its successors and update their dominators
-  // and phis.
+  // Disconnect the block from its successors and update their phis.
   for (size_t i = 0, e = successors_.Size(); i < e; ++i) {
     HBasicBlock* successor = successors_.Get(i);
     // Delete this block from the list of predecessors.
@@ -1145,19 +1159,6 @@
     // dominator of `successor` which violates the order DCHECKed at the top.
     DCHECK(!successor->predecessors_.IsEmpty());
 
-    // Recompute the successor's dominator.
-    HBasicBlock* old_dominator = successor->GetDominator();
-    HBasicBlock* new_dominator = successor->predecessors_.Get(0);
-    for (size_t j = 1, f = successor->predecessors_.Size(); j < f; ++j) {
-      new_dominator = graph_->FindCommonDominator(
-          new_dominator, successor->predecessors_.Get(j));
-    }
-    if (old_dominator != new_dominator) {
-      successor->SetDominator(new_dominator);
-      old_dominator->RemoveDominatedBlock(successor);
-      new_dominator->AddDominatedBlock(successor);
-    }
-
     // Remove this block's entries in the successor's phis.
     if (successor->predecessors_.Size() == 1u) {
       // The successor has just one predecessor left. Replace phis with the only
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index 26eee1c..581645f 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -183,6 +183,9 @@
     return true;
   }
 
+  void ComputeDominanceInformation();
+  void ClearDominanceInformation();
+
   void BuildDominatorTree();
   void TransformToSsa();
   void SimplifyCFG();
@@ -590,11 +593,10 @@
     LOG(FATAL) << "Unreachable";
     UNREACHABLE();
   }
+  void ClearDominanceInformation();
 
   int NumberOfBackEdges() const {
-    return loop_information_ == nullptr
-        ? 0
-        : loop_information_->NumberOfBackEdges();
+    return IsLoopHeader() ? loop_information_->NumberOfBackEdges() : 0;
   }
 
   HInstruction* GetFirstInstruction() const { return instructions_.first_instruction_; }