Fix some bugs in graph construction/simplification methods.

Also fix a brano during SSA construction. The code should
not have been commented out. Added a test to cover what the code
intends.

Change-Id: Ia00ae79dcf75eb0d412f07649d73e7f94dbfb6f0
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index b1c8016..68848de 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -283,18 +283,16 @@
     block->predecessors_.Add(this);
   }
 
-  void RemovePredecessor(HBasicBlock* block, bool remove_in_successor = true) {
-    predecessors_.Delete(block);
-    if (remove_in_successor) {
-      block->successors_.Delete(this);
-    }
+  void ReplaceSuccessor(HBasicBlock* existing, HBasicBlock* new_block) {
+    size_t successor_index = GetSuccessorIndexOf(existing);
+    DCHECK_NE(successor_index, static_cast<size_t>(-1));
+    existing->RemovePredecessor(this);
+    new_block->predecessors_.Add(this);
+    successors_.Put(successor_index, new_block);
   }
 
-  void RemoveSuccessor(HBasicBlock* block, bool remove_in_predecessor = true) {
-    successors_.Delete(block);
-    if (remove_in_predecessor) {
-      block->predecessors_.Delete(this);
-    }
+  void RemovePredecessor(HBasicBlock* block) {
+    predecessors_.Delete(block);
   }
 
   void ClearAllPredecessors() {
@@ -315,6 +313,15 @@
     return -1;
   }
 
+  size_t GetSuccessorIndexOf(HBasicBlock* successor) {
+    for (size_t i = 0, e = successors_.Size(); i < e; ++i) {
+      if (successors_.Get(i) == successor) {
+        return i;
+      }
+    }
+    return -1;
+  }
+
   void AddInstruction(HInstruction* instruction);
   void RemoveInstruction(HInstruction* instruction);
   void InsertInstructionBefore(HInstruction* instruction, HInstruction* cursor);
@@ -455,6 +462,7 @@
   virtual void SetRawInputAt(size_t index, HInstruction* input) = 0;
 
   virtual bool NeedsEnvironment() const { return false; }
+  virtual bool IsControlFlow() const { return false; }
 
   void AddUseAt(HInstruction* user, size_t index) {
     uses_ = new (block_->GetGraph()->GetArena()) HUseListNode<HInstruction>(user, index, uses_);
@@ -733,7 +741,9 @@
 // instruction that branches to the exit block.
 class HReturnVoid : public HTemplateInstruction<0> {
  public:
-  HReturnVoid() { }
+  HReturnVoid() {}
+
+  virtual bool IsControlFlow() const { return true; }
 
   DECLARE_INSTRUCTION(ReturnVoid);
 
@@ -749,6 +759,8 @@
     SetRawInputAt(0, value);
   }
 
+  virtual bool IsControlFlow() const { return true; }
+
   DECLARE_INSTRUCTION(Return);
 
  private:
@@ -760,7 +772,9 @@
 // exit block.
 class HExit : public HTemplateInstruction<0> {
  public:
-  HExit() { }
+  HExit() {}
+
+  virtual bool IsControlFlow() const { return true; }
 
   DECLARE_INSTRUCTION(Exit);
 
@@ -771,12 +785,14 @@
 // Jumps from one block to another.
 class HGoto : public HTemplateInstruction<0> {
  public:
-  HGoto() { }
+  HGoto() {}
 
   HBasicBlock* GetSuccessor() const {
     return GetBlock()->GetSuccessors().Get(0);
   }
 
+  virtual bool IsControlFlow() const { return true; }
+
   DECLARE_INSTRUCTION(Goto);
 
  private:
@@ -799,6 +815,8 @@
     return GetBlock()->GetSuccessors().Get(1);
   }
 
+  virtual bool IsControlFlow() const { return true; }
+
   DECLARE_INSTRUCTION(If);
 
  private: