ART: Update graph's exit block field if removed

Running DCE on an infinite loop will delete the exit block but the
corresponding field is currently not cleared in the parent graph.
This does not cause any problems at the moment as that information is
only used in codegens to DCHECK that a block is not the exit block.
However, it will be necessary to update the inliner once we start to
inline methods with loops.

With this patch, DCE will update the HGraph::exit_block_ field. DCHECK
was also added to HGraph::InlineInto to make sure that the inlined
graph does have an exit block.

Change-Id: Ia8ddca375bbc6830cd919af6059a52cc9b73a023
diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc
index 47da9cc..2ece5a5 100644
--- a/compiler/optimizing/nodes.cc
+++ b/compiler/optimizing/nodes.cc
@@ -1290,11 +1290,16 @@
     block->RemovePhi(it.Current()->AsPhi());
   }
 
+  if (block->IsExitBlock()) {
+    exit_block_ = nullptr;
+  }
+
   reverse_post_order_.Delete(block);
   blocks_.Put(block->GetBlockId(), nullptr);
 }
 
 void HGraph::InlineInto(HGraph* outer_graph, HInvoke* invoke) {
+  DCHECK(HasExitBlock()) << "Unimplemented scenario";
   if (GetBlocks().Size() == 3) {
     // Simple case of an entry block, a body block, and an exit block.
     // Put the body block's instruction into `invoke`'s block.
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index 67c6b3c..01870c3 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -155,6 +155,7 @@
 
   HBasicBlock* GetEntryBlock() const { return entry_block_; }
   HBasicBlock* GetExitBlock() const { return exit_block_; }
+  bool HasExitBlock() const { return exit_block_ != nullptr; }
 
   void SetEntryBlock(HBasicBlock* block) { entry_block_ = block; }
   void SetExitBlock(HBasicBlock* block) { exit_block_ = block; }