ART: Store and check exceptional predecessors

Future CL on register allocation for try/catch will require the
knowledge of instructions which throw into a catch block. This patch
stores that information with the basic block and verifies it in the
graph checker.

More checks on try catch also added to the graph checker and an order
of exception handlers is enforced in TryBoundary successors.

Change-Id: I3034c610791ea51d96724bcca97f49ec6ecf2af3
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index 003900c..9b8521d 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -58,6 +58,7 @@
 static const int kDefaultNumberOfBlocks = 8;
 static const int kDefaultNumberOfSuccessors = 2;
 static const int kDefaultNumberOfPredecessors = 2;
+static const int kDefaultNumberOfExceptionalPredecessors = 0;
 static const int kDefaultNumberOfDominatedBlocks = 1;
 static const int kDefaultNumberOfBackEdges = 1;
 
@@ -564,6 +565,7 @@
   explicit HBasicBlock(HGraph* graph, uint32_t dex_pc = kNoDexPc)
       : graph_(graph),
         predecessors_(graph->GetArena(), kDefaultNumberOfPredecessors),
+        exceptional_predecessors_(graph->GetArena(), kDefaultNumberOfExceptionalPredecessors),
         successors_(graph->GetArena(), kDefaultNumberOfSuccessors),
         loop_information_(nullptr),
         dominator_(nullptr),
@@ -578,6 +580,10 @@
     return predecessors_;
   }
 
+  const GrowableArray<HInstruction*>& GetExceptionalPredecessors() const {
+    return exceptional_predecessors_;
+  }
+
   const GrowableArray<HBasicBlock*>& GetSuccessors() const {
     return successors_;
   }
@@ -646,6 +652,8 @@
   HInstruction* GetLastPhi() const { return phis_.last_instruction_; }
   const HInstructionList& GetPhis() const { return phis_; }
 
+  void AddExceptionalPredecessor(HInstruction* exceptional_predecessor);
+
   void AddSuccessor(HBasicBlock* block) {
     successors_.Add(block);
     block->predecessors_.Add(this);
@@ -685,6 +693,10 @@
     predecessors_.Delete(block);
   }
 
+  void RemoveExceptionalPredecessor(HInstruction* instruction) {
+    exceptional_predecessors_.Delete(instruction);
+  }
+
   void RemoveSuccessor(HBasicBlock* block) {
     successors_.Delete(block);
   }
@@ -721,6 +733,15 @@
     return -1;
   }
 
+  size_t GetExceptionalPredecessorIndexOf(HInstruction* exceptional_predecessor) const {
+    for (size_t i = 0, e = exceptional_predecessors_.Size(); i < e; ++i) {
+      if (exceptional_predecessors_.Get(i) == exceptional_predecessor) {
+        return i;
+      }
+    }
+    return -1;
+  }
+
   size_t GetSuccessorIndexOf(HBasicBlock* successor) const {
     for (size_t i = 0, e = successors_.Size(); i < e; ++i) {
       if (successors_.Get(i) == successor) {
@@ -881,6 +902,7 @@
  private:
   HGraph* graph_;
   GrowableArray<HBasicBlock*> predecessors_;
+  GrowableArray<HInstruction*> exceptional_predecessors_;
   GrowableArray<HBasicBlock*> successors_;
   HInstructionList instructions_;
   HInstructionList phis_;