ART: Preserve loop headers with try/catch

Algorithm for inserting HTryBoundary instructions would generate a
non-natural loop when a loop header block was covered by a TryItem.
This patch changes the approach to fix the issue.

Bug: 23895756
Change-Id: I0e1ee6cf135cea326a96c97954907d202c9793cc
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index 7498f44..d79852c 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -819,11 +819,17 @@
     return EndsWithTryBoundary() ? 1 : GetSuccessors().size();
   }
 
+  // Create a new block between this block and its predecessors. The new block
+  // is added to the graph, all predecessor edges are relinked to it and an edge
+  // is created to `this`. Returns the new empty block. Reverse post order or
+  // loop and try/catch information are not updated.
+  HBasicBlock* CreateImmediateDominator();
+
   // Split the block into two blocks just before `cursor`. Returns the newly
   // created, latter block. Note that this method will add the block to the
   // graph, create a Goto at the end of the former block and will create an edge
   // between the blocks. It will not, however, update the reverse post order or
-  // loop information.
+  // loop and try/catch information.
   HBasicBlock* SplitBefore(HInstruction* cursor);
 
   // Split the block into two blocks just after `cursor`. Returns the newly
@@ -934,6 +940,8 @@
   // the appropriate try entry will be returned.
   const HTryBoundary* ComputeTryEntryOfSuccessors() const;
 
+  bool HasThrowingInstructions() const;
+
   // Returns whether this block dominates the blocked passed as parameter.
   bool Dominates(HBasicBlock* block) const;
 
@@ -943,7 +951,6 @@
   void SetLifetimeStart(size_t start) { lifetime_start_ = start; }
   void SetLifetimeEnd(size_t end) { lifetime_end_ = end; }
 
-
   bool EndsWithControlFlowInstruction() const;
   bool EndsWithIf() const;
   bool EndsWithTryBoundary() const;