Revert "ART: Implement try/catch blocks in Builder"

Causes OutOfMemory issues, need to investigate.

This reverts commit 0b5c7d1994b76090afcc825e737f2b8c546da2f8.

Change-Id: I263e6cc4df5f9a56ad2ce44e18932ca51d7e349f
diff --git a/compiler/optimizing/builder.cc b/compiler/optimizing/builder.cc
index 742429c..e527e8b 100644
--- a/compiler/optimizing/builder.cc
+++ b/compiler/optimizing/builder.cc
@@ -259,165 +259,6 @@
   return false;
 }
 
-bool HGraphBuilder::IsBlockInPcRange(HBasicBlock* block,
-                                     uint32_t dex_pc_start,
-                                     uint32_t dex_pc_end) {
-  uint32_t dex_pc = block->GetDexPc();
-  return block != entry_block_
-      && block != exit_block_
-      && dex_pc >= dex_pc_start
-      && dex_pc < dex_pc_end;
-}
-
-void HGraphBuilder::CreateBlocksForTryCatch(const DexFile::CodeItem& code_item) {
-  if (code_item.tries_size_ == 0) {
-    return;
-  }
-
-  // Create branch targets at the start/end of the TryItem range. These are
-  // places where the program might fall through into/out of the a block and
-  // where TryBoundary instructions will be inserted later. Other edges which
-  // enter/exit the try blocks are a result of branches/switches.
-  for (size_t idx = 0; idx < code_item.tries_size_; ++idx) {
-    const DexFile::TryItem* try_item = DexFile::GetTryItems(code_item, idx);
-    uint32_t dex_pc_start = try_item->start_addr_;
-    uint32_t dex_pc_end = dex_pc_start + try_item->insn_count_;
-    FindOrCreateBlockStartingAt(dex_pc_start);
-    if (dex_pc_end < code_item.insns_size_in_code_units_) {
-      // TODO: Do not create block if the last instruction cannot fall through.
-      FindOrCreateBlockStartingAt(dex_pc_end);
-    } else {
-      // The TryItem spans until the very end of the CodeItem (or beyond if
-      // invalid) and therefore cannot have any code afterwards.
-    }
-  }
-
-  // Create branch targets for exception handlers.
-  const uint8_t* handlers_ptr = DexFile::GetCatchHandlerData(code_item, 0);
-  uint32_t handlers_size = DecodeUnsignedLeb128(&handlers_ptr);
-  for (uint32_t idx = 0; idx < handlers_size; ++idx) {
-    CatchHandlerIterator iterator(handlers_ptr);
-    for (; iterator.HasNext(); iterator.Next()) {
-      uint32_t address = iterator.GetHandlerAddress();
-      HBasicBlock* block = FindOrCreateBlockStartingAt(address);
-      block->SetIsCatchBlock();
-    }
-    handlers_ptr = iterator.EndDataPointer();
-  }
-}
-
-void HGraphBuilder::InsertTryBoundaryBlocks(const DexFile::CodeItem& code_item) {
-  if (code_item.tries_size_ == 0) {
-    return;
-  }
-
-  for (size_t idx = 0; idx < code_item.tries_size_; ++idx) {
-    const DexFile::TryItem* try_item = DexFile::GetTryItems(code_item, idx);
-    uint32_t try_start = try_item->start_addr_;
-    uint32_t try_end = try_start + try_item->insn_count_;
-
-    // Iterate over all blocks in the dex pc range of the TryItem and:
-    //   (a) split edges which enter/exit the try range,
-    //   (b) create TryBoundary instructions in the new blocks,
-    //   (c) link the new blocks to corresponding exception handlers.
-    for (uint32_t inner_pc = try_start; inner_pc < try_end; ++inner_pc) {
-      HBasicBlock* try_block = FindBlockStartingAt(inner_pc);
-      if (try_block == nullptr) {
-        continue;
-      }
-
-      // Find predecessors which are not covered by the same TryItem range. Such
-      // edges enter the try block and will have a TryBoundary inserted.
-      for (size_t i = 0; i < try_block->GetPredecessors().Size(); ++i) {
-        HBasicBlock* predecessor = try_block->GetPredecessors().Get(i);
-        HTryBoundary* try_boundary = nullptr;
-        if (predecessor->IsSingleTryBoundary()) {
-          try_boundary = predecessor->GetLastInstruction()->AsTryBoundary();
-          if (try_boundary->GetNormalFlowSuccessor() == try_block
-              && try_block->IsFirstIndexOfPredecessor(predecessor, i)) {
-            // The edge was already split because of an exit from a neighbouring
-            // TryItem and `predecessor` is the block with a TryBoundary created
-            // between the two original blocks. We do not split the edge again.
-            DCHECK(!IsBlockInPcRange(predecessor->GetSinglePredecessor(), try_start, try_end));
-            DCHECK(try_boundary->IsTryExit());
-            DCHECK(!try_boundary->IsTryEntry());
-            try_boundary->SetIsTryEntry();
-          } else {
-            // This is an edge between a previously created TryBoundary and its
-            // handler. We skip it because it is exceptional flow.
-            DCHECK(try_block->IsCatchBlock());
-            DCHECK(try_boundary->HasExceptionHandler(try_block));
-            continue;
-          }
-        } else if (!IsBlockInPcRange(predecessor, try_start, try_end)) {
-          // This is an entry point into the TryItem and the edge has not been
-          // split yet. That means that either `predecessor` is not in a TryItem,
-          // or it is in a different TryItem and we happened to iterate over
-          // this block first. We split the edge and `predecessor` may add its
-          // own exception handlers later.
-          try_boundary = new (arena_) HTryBoundary(/* is_entry */ true, /* is_exit */ false);
-          HBasicBlock* try_entry_block = graph_->SplitEdge(predecessor, try_block);
-          try_entry_block->AddInstruction(try_boundary);
-        } else {
-          // Not an edge on the boundary of the try block.
-          continue;
-        }
-        DCHECK(try_boundary != nullptr);
-
-        // Link the TryBoundary block to the handlers of this TryItem.
-        for (CatchHandlerIterator it(code_item, *try_item); it.HasNext(); it.Next()) {
-          try_boundary->AddExceptionHandler(FindBlockStartingAt(it.GetHandlerAddress()));
-        }
-      }
-
-      // Find successors which are not covered by the same TryItem range. Such
-      // edges exit the try block and will have a TryBoundary inserted.
-      for (size_t i = 0; i < try_block->GetSuccessors().Size(); ++i) {
-        HBasicBlock* successor = try_block->GetSuccessors().Get(i);
-        HTryBoundary* try_boundary = nullptr;
-        if (successor->IsSingleTryBoundary()) {
-          // The edge was already split because of an entry into a neighbouring
-          // TryItem. We do not split the edge again.
-          try_boundary = successor->GetLastInstruction()->AsTryBoundary();
-          DCHECK_EQ(try_block, successor->GetSinglePredecessor());
-          DCHECK(try_boundary->IsTryEntry());
-          DCHECK(!try_boundary->IsTryExit());
-          DCHECK(!IsBlockInPcRange(try_boundary->GetNormalFlowSuccessor(), try_start, try_end));
-          try_boundary->SetIsTryExit();
-        } else if (!IsBlockInPcRange(successor, try_start, try_end)) {
-          // This is an exit out of the TryItem and the edge has not been split
-          // yet. That means that either `successor` is not in a TryItem, or it
-          // is in a different TryItem and we happened to iterate over this
-          // block first. We split the edge and `successor` may add its own
-          // exception handlers later.
-          HInstruction* last_instruction = try_block->GetLastInstruction();
-          if (last_instruction->IsReturn() || last_instruction->IsReturnVoid()) {
-            DCHECK_EQ(successor, exit_block_);
-            // Control flow exits the try block with a Return(Void). Because
-            // splitting the edge would invalidate the invariant that Return
-            // always jumps to Exit, we move the Return outside the try block.
-            HBasicBlock* return_block = try_block->SplitBefore(last_instruction);
-            graph_->AddBlock(return_block);
-            successor = return_block;
-          }
-          try_boundary = new (arena_) HTryBoundary(/* is_entry */ false, /* is_exit */ true);
-          HBasicBlock* try_exit_block = graph_->SplitEdge(try_block, successor);
-          try_exit_block->AddInstruction(try_boundary);
-        } else {
-          // Not an edge on the boundary of the try block.
-          continue;
-        }
-        DCHECK(try_boundary != nullptr);
-
-        // Link the TryBoundary block to the handlers of this TryItem.
-        for (CatchHandlerIterator it(code_item, *try_item); it.HasNext(); it.Next()) {
-          try_boundary->AddExceptionHandler(FindBlockStartingAt(it.GetHandlerAddress()));
-        }
-      }
-    }
-  }
-}
-
 bool HGraphBuilder::BuildGraph(const DexFile::CodeItem& code_item) {
   DCHECK(graph_->GetBlocks().IsEmpty());
 
@@ -451,7 +292,24 @@
     return false;
   }
 
-  CreateBlocksForTryCatch(code_item);
+  // Also create blocks for catch handlers.
+  if (code_item.tries_size_ != 0) {
+    const uint8_t* handlers_ptr = DexFile::GetCatchHandlerData(code_item, 0);
+    uint32_t handlers_size = DecodeUnsignedLeb128(&handlers_ptr);
+    for (uint32_t idx = 0; idx < handlers_size; ++idx) {
+      CatchHandlerIterator iterator(handlers_ptr);
+      for (; iterator.HasNext(); iterator.Next()) {
+        uint32_t address = iterator.GetHandlerAddress();
+        HBasicBlock* block = FindBlockStartingAt(address);
+        if (block == nullptr) {
+          block = new (arena_) HBasicBlock(graph_, address);
+          branch_targets_.Put(address, block);
+        }
+        block->SetIsCatchBlock();
+      }
+      handlers_ptr = iterator.EndDataPointer();
+    }
+  }
 
   InitializeParameters(code_item.ins_size_);
 
@@ -467,24 +325,18 @@
     code_ptr += instruction.SizeInCodeUnits();
   }
 
+  // Add the exit block at the end to give it the highest id.
+  graph_->AddBlock(exit_block_);
+  exit_block_->AddInstruction(new (arena_) HExit());
   // Add the suspend check to the entry block.
   entry_block_->AddInstruction(new (arena_) HSuspendCheck(0));
   entry_block_->AddInstruction(new (arena_) HGoto());
-  // Add Exit to the exit block.
-  exit_block_->AddInstruction(new (arena_) HExit());
 
-  // Iterate over blocks covered by TryItems and insert TryBoundaries at entry
-  // and exit points. This requires all control-flow instructions and
-  // non-exceptional edges to have been created.
-  InsertTryBoundaryBlocks(code_item);
-
-  // Add the exit block at the end to give it the highest id.
-  graph_->AddBlock(exit_block_);
   return true;
 }
 
-void HGraphBuilder::MaybeUpdateCurrentBlock(size_t dex_pc) {
-  HBasicBlock* block = FindBlockStartingAt(dex_pc);
+void HGraphBuilder::MaybeUpdateCurrentBlock(size_t index) {
+  HBasicBlock* block = FindBlockStartingAt(index);
   if (block == nullptr) {
     return;
   }
@@ -519,8 +371,10 @@
       (*number_of_branches)++;
       int32_t target = instruction.GetTargetOffset() + dex_pc;
       // Create a block for the target instruction.
-      FindOrCreateBlockStartingAt(target);
-
+      if (FindBlockStartingAt(target) == nullptr) {
+        block = new (arena_) HBasicBlock(graph_, target);
+        branch_targets_.Put(target, block);
+      }
       dex_pc += instruction.SizeInCodeUnits();
       code_ptr += instruction.SizeInCodeUnits();
 
@@ -529,8 +383,9 @@
           // In the normal case we should never hit this but someone can artificially forge a dex
           // file to fall-through out the method code. In this case we bail out compilation.
           return false;
-        } else {
-          FindOrCreateBlockStartingAt(dex_pc);
+        } else if (FindBlockStartingAt(dex_pc) == nullptr) {
+          block = new (arena_) HBasicBlock(graph_, dex_pc);
+          branch_targets_.Put(dex_pc, block);
         }
       }
     } else if (instruction.IsSwitch()) {
@@ -546,7 +401,10 @@
       for (size_t i = 0; i < num_entries; ++i) {
         // The target of the case.
         uint32_t target = dex_pc + table.GetEntryAt(i + offset);
-        FindOrCreateBlockStartingAt(target);
+        if (FindBlockStartingAt(target) == nullptr) {
+          block = new (arena_) HBasicBlock(graph_, target);
+          branch_targets_.Put(target, block);
+        }
 
         // The next case gets its own block.
         if (i < num_entries) {
@@ -563,8 +421,9 @@
         // file to fall-through out the method code. In this case we bail out compilation.
         // (A switch can fall-through so we don't need to check CanFlowThrough().)
         return false;
-      } else {
-        FindOrCreateBlockStartingAt(dex_pc);
+      } else if (FindBlockStartingAt(dex_pc) == nullptr) {
+        block = new (arena_) HBasicBlock(graph_, dex_pc);
+        branch_targets_.Put(dex_pc, block);
       }
     } else {
       code_ptr += instruction.SizeInCodeUnits();
@@ -574,19 +433,9 @@
   return true;
 }
 
-HBasicBlock* HGraphBuilder::FindBlockStartingAt(int32_t dex_pc) const {
-  DCHECK_GE(dex_pc, 0);
-  DCHECK_LT(static_cast<size_t>(dex_pc), branch_targets_.Size());
-  return branch_targets_.Get(dex_pc);
-}
-
-HBasicBlock* HGraphBuilder::FindOrCreateBlockStartingAt(int32_t dex_pc) {
-  HBasicBlock* block = FindBlockStartingAt(dex_pc);
-  if (block == nullptr) {
-    block = new (arena_) HBasicBlock(graph_, dex_pc);
-    branch_targets_.Put(dex_pc, block);
-  }
-  return block;
+HBasicBlock* HGraphBuilder::FindBlockStartingAt(int32_t index) const {
+  DCHECK_GE(index, 0);
+  return branch_targets_.Get(index);
 }
 
 template<typename T>
@@ -2259,29 +2108,15 @@
 
     case Instruction::MOVE_RESULT:
     case Instruction::MOVE_RESULT_WIDE:
-    case Instruction::MOVE_RESULT_OBJECT: {
+    case Instruction::MOVE_RESULT_OBJECT:
       if (latest_result_ == nullptr) {
         // Only dead code can lead to this situation, where the verifier
         // does not reject the method.
       } else {
-        // An Invoke/FilledNewArray and its MoveResult could have landed in
-        // different blocks if there was a try/catch block boundary between
-        // them. We need to insert the StoreLocal after the result definition
-        // but before any potential Temporaries.
-        HStoreLocal* update_local =
-            new (arena_) HStoreLocal(GetLocalAt(instruction.VRegA()), latest_result_);
-        HBasicBlock* block = latest_result_->GetBlock();
-        if (latest_result_->IsInvoke()) {
-          block->InsertInstructionAfter(update_local, latest_result_);
-        } else {
-          DCHECK(latest_result_->IsNewArray());
-          DCHECK(latest_result_->GetNext()->IsTemporary());
-          block->InsertInstructionAfter(update_local, latest_result_->GetNext());
-        }
+        UpdateLocal(instruction.VRegA(), latest_result_);
         latest_result_ = nullptr;
       }
       break;
-    }
 
     case Instruction::CMP_LONG: {
       Binop_23x_cmp(instruction, Primitive::kPrimLong, HCompare::kNoBias, dex_pc);
diff --git a/compiler/optimizing/builder.h b/compiler/optimizing/builder.h
index 58d85e9..052aaf8 100644
--- a/compiler/optimizing/builder.h
+++ b/compiler/optimizing/builder.h
@@ -94,12 +94,8 @@
   bool ComputeBranchTargets(const uint16_t* start,
                             const uint16_t* end,
                             size_t* number_of_branches);
-  void MaybeUpdateCurrentBlock(size_t dex_pc);
-  HBasicBlock* FindBlockStartingAt(int32_t dex_pc) const;
-  HBasicBlock* FindOrCreateBlockStartingAt(int32_t dex_pc);
-  bool IsBlockInPcRange(HBasicBlock* block, uint32_t dex_pc_start, uint32_t dex_pc_end);
-  void CreateBlocksForTryCatch(const DexFile::CodeItem& code_item);
-  void InsertTryBoundaryBlocks(const DexFile::CodeItem& code_item);
+  void MaybeUpdateCurrentBlock(size_t index);
+  HBasicBlock* FindBlockStartingAt(int32_t index) const;
 
   void InitializeLocals(uint16_t count);
   HLocal* GetLocalAt(int register_index) const;
diff --git a/compiler/optimizing/code_generator.cc b/compiler/optimizing/code_generator.cc
index 4607ebe..cd10935 100644
--- a/compiler/optimizing/code_generator.cc
+++ b/compiler/optimizing/code_generator.cc
@@ -146,7 +146,7 @@
 HBasicBlock* CodeGenerator::GetNextBlockToEmit() const {
   for (size_t i = current_block_index_ + 1; i < block_order_->Size(); ++i) {
     HBasicBlock* block = block_order_->Get(i);
-    if (!block->IsSingleJump()) {
+    if (!block->IsSingleGoto()) {
       return block;
     }
   }
@@ -154,7 +154,7 @@
 }
 
 HBasicBlock* CodeGenerator::FirstNonEmptyBlock(HBasicBlock* block) const {
-  while (block->IsSingleJump()) {
+  while (block->IsSingleGoto()) {
     block = block->GetSuccessors().Get(0);
   }
   return block;
@@ -214,7 +214,7 @@
     // Don't generate code for an empty block. Its predecessors will branch to its successor
     // directly. Also, the label of that block will not be emitted, so this helps catch
     // errors where we reference that label.
-    if (block->IsSingleJump()) continue;
+    if (block->IsSingleGoto()) continue;
     Bind(block);
     for (HInstructionIterator it(block->GetInstructions()); !it.Done(); it.Advance()) {
       HInstruction* current = it.Current();
diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc
index ff9373a..9abe2e7 100644
--- a/compiler/optimizing/code_generator_arm.cc
+++ b/compiler/optimizing/code_generator_arm.cc
@@ -431,7 +431,7 @@
     // FirstNonEmptyBlock() which could lead to adjusting a label more than once.
     DCHECK_LT(static_cast<size_t>(block->GetBlockId()), block_labels_.Size());
     Label* block_label = &block_labels_.GetRawStorage()[block->GetBlockId()];
-    DCHECK_EQ(block_label->IsBound(), !block->IsSingleJump());
+    DCHECK_EQ(block_label->IsBound(), !block->IsSingleGoto());
     if (block_label->IsBound()) {
       __ AdjustLabelPosition(block_label);
     }
@@ -962,7 +962,12 @@
       || !IsLeafMethod());
 }
 
-void InstructionCodeGeneratorARM::HandleGoto(HInstruction* got, HBasicBlock* successor) {
+void LocationsBuilderARM::VisitGoto(HGoto* got) {
+  got->SetLocations(nullptr);
+}
+
+void InstructionCodeGeneratorARM::VisitGoto(HGoto* got) {
+  HBasicBlock* successor = got->GetSuccessor();
   DCHECK(!successor->IsExitBlock());
 
   HBasicBlock* block = got->GetBlock();
@@ -983,25 +988,6 @@
   }
 }
 
-void LocationsBuilderARM::VisitGoto(HGoto* got) {
-  got->SetLocations(nullptr);
-}
-
-void InstructionCodeGeneratorARM::VisitGoto(HGoto* got) {
-  HandleGoto(got, got->GetSuccessor());
-}
-
-void LocationsBuilderARM::VisitTryBoundary(HTryBoundary* try_boundary) {
-  try_boundary->SetLocations(nullptr);
-}
-
-void InstructionCodeGeneratorARM::VisitTryBoundary(HTryBoundary* try_boundary) {
-  HBasicBlock* successor = try_boundary->GetNormalFlowSuccessor();
-  if (!successor->IsExitBlock()) {
-    HandleGoto(try_boundary, successor);
-  }
-}
-
 void LocationsBuilderARM::VisitExit(HExit* exit) {
   exit->SetLocations(nullptr);
 }
diff --git a/compiler/optimizing/code_generator_arm.h b/compiler/optimizing/code_generator_arm.h
index a96ecbd..953e733 100644
--- a/compiler/optimizing/code_generator_arm.h
+++ b/compiler/optimizing/code_generator_arm.h
@@ -211,7 +211,6 @@
   void DivRemByPowerOfTwo(HBinaryOperation* instruction);
   void GenerateDivRemWithAnyConstant(HBinaryOperation* instruction);
   void GenerateDivRemConstantIntegral(HBinaryOperation* instruction);
-  void HandleGoto(HInstruction* got, HBasicBlock* successor);
 
   ArmAssembler* const assembler_;
   CodeGeneratorARM* const codegen_;
diff --git a/compiler/optimizing/code_generator_arm64.cc b/compiler/optimizing/code_generator_arm64.cc
index 9b7124d..7ec6b54 100644
--- a/compiler/optimizing/code_generator_arm64.cc
+++ b/compiler/optimizing/code_generator_arm64.cc
@@ -1971,7 +1971,12 @@
   // Will be generated at use site.
 }
 
-void InstructionCodeGeneratorARM64::HandleGoto(HInstruction* got, HBasicBlock* successor) {
+void LocationsBuilderARM64::VisitGoto(HGoto* got) {
+  got->SetLocations(nullptr);
+}
+
+void InstructionCodeGeneratorARM64::VisitGoto(HGoto* got) {
+  HBasicBlock* successor = got->GetSuccessor();
   DCHECK(!successor->IsExitBlock());
   HBasicBlock* block = got->GetBlock();
   HInstruction* previous = got->GetPrevious();
@@ -1990,25 +1995,6 @@
   }
 }
 
-void LocationsBuilderARM64::VisitGoto(HGoto* got) {
-  got->SetLocations(nullptr);
-}
-
-void InstructionCodeGeneratorARM64::VisitGoto(HGoto* got) {
-  HandleGoto(got, got->GetSuccessor());
-}
-
-void LocationsBuilderARM64::VisitTryBoundary(HTryBoundary* try_boundary) {
-  try_boundary->SetLocations(nullptr);
-}
-
-void InstructionCodeGeneratorARM64::VisitTryBoundary(HTryBoundary* try_boundary) {
-  HBasicBlock* successor = try_boundary->GetNormalFlowSuccessor();
-  if (!successor->IsExitBlock()) {
-    HandleGoto(try_boundary, successor);
-  }
-}
-
 void InstructionCodeGeneratorARM64::GenerateTestAndBranch(HInstruction* instruction,
                                                           vixl::Label* true_target,
                                                           vixl::Label* false_target,
diff --git a/compiler/optimizing/code_generator_arm64.h b/compiler/optimizing/code_generator_arm64.h
index 2c61038..bbe3adc 100644
--- a/compiler/optimizing/code_generator_arm64.h
+++ b/compiler/optimizing/code_generator_arm64.h
@@ -181,7 +181,7 @@
   void DivRemByPowerOfTwo(HBinaryOperation* instruction);
   void GenerateDivRemWithAnyConstant(HBinaryOperation* instruction);
   void GenerateDivRemIntegral(HBinaryOperation* instruction);
-  void HandleGoto(HInstruction* got, HBasicBlock* successor);
+
 
   Arm64Assembler* const assembler_;
   CodeGeneratorARM64* const codegen_;
diff --git a/compiler/optimizing/code_generator_mips64.cc b/compiler/optimizing/code_generator_mips64.cc
index aa4fd26..ab684d4 100644
--- a/compiler/optimizing/code_generator_mips64.cc
+++ b/compiler/optimizing/code_generator_mips64.cc
@@ -1938,7 +1938,12 @@
   // Will be generated at use site.
 }
 
-void InstructionCodeGeneratorMIPS64::HandleGoto(HInstruction* got, HBasicBlock* successor) {
+void LocationsBuilderMIPS64::VisitGoto(HGoto* got) {
+  got->SetLocations(nullptr);
+}
+
+void InstructionCodeGeneratorMIPS64::VisitGoto(HGoto* got) {
+  HBasicBlock* successor = got->GetSuccessor();
   DCHECK(!successor->IsExitBlock());
   HBasicBlock* block = got->GetBlock();
   HInstruction* previous = got->GetPrevious();
@@ -1957,25 +1962,6 @@
   }
 }
 
-void LocationsBuilderMIPS64::VisitGoto(HGoto* got) {
-  got->SetLocations(nullptr);
-}
-
-void InstructionCodeGeneratorMIPS64::VisitGoto(HGoto* got) {
-  HandleGoto(got, got->GetSuccessor());
-}
-
-void LocationsBuilderMIPS64::VisitTryBoundary(HTryBoundary* try_boundary) {
-  try_boundary->SetLocations(nullptr);
-}
-
-void InstructionCodeGeneratorMIPS64::VisitTryBoundary(HTryBoundary* try_boundary) {
-  HBasicBlock* successor = try_boundary->GetNormalFlowSuccessor();
-  if (!successor->IsExitBlock()) {
-    HandleGoto(try_boundary, successor);
-  }
-}
-
 void InstructionCodeGeneratorMIPS64::GenerateTestAndBranch(HInstruction* instruction,
                                                            Label* true_target,
                                                            Label* false_target,
diff --git a/compiler/optimizing/code_generator_mips64.h b/compiler/optimizing/code_generator_mips64.h
index c724a21..ec36496 100644
--- a/compiler/optimizing/code_generator_mips64.h
+++ b/compiler/optimizing/code_generator_mips64.h
@@ -196,7 +196,6 @@
                              Label* true_target,
                              Label* false_target,
                              Label* always_true_target);
-  void HandleGoto(HInstruction* got, HBasicBlock* successor);
 
   Mips64Assembler* const assembler_;
   CodeGeneratorMIPS64* const codegen_;
diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc
index 6c82fe9..4d106c4 100644
--- a/compiler/optimizing/code_generator_x86.cc
+++ b/compiler/optimizing/code_generator_x86.cc
@@ -842,7 +842,12 @@
   }
 }
 
-void InstructionCodeGeneratorX86::HandleGoto(HInstruction* got, HBasicBlock* successor) {
+void LocationsBuilderX86::VisitGoto(HGoto* got) {
+  got->SetLocations(nullptr);
+}
+
+void InstructionCodeGeneratorX86::VisitGoto(HGoto* got) {
+  HBasicBlock* successor = got->GetSuccessor();
   DCHECK(!successor->IsExitBlock());
 
   HBasicBlock* block = got->GetBlock();
@@ -862,25 +867,6 @@
   }
 }
 
-void LocationsBuilderX86::VisitGoto(HGoto* got) {
-  got->SetLocations(nullptr);
-}
-
-void InstructionCodeGeneratorX86::VisitGoto(HGoto* got) {
-  HandleGoto(got, got->GetSuccessor());
-}
-
-void LocationsBuilderX86::VisitTryBoundary(HTryBoundary* try_boundary) {
-  try_boundary->SetLocations(nullptr);
-}
-
-void InstructionCodeGeneratorX86::VisitTryBoundary(HTryBoundary* try_boundary) {
-  HBasicBlock* successor = try_boundary->GetNormalFlowSuccessor();
-  if (!successor->IsExitBlock()) {
-    HandleGoto(try_boundary, successor);
-  }
-}
-
 void LocationsBuilderX86::VisitExit(HExit* exit) {
   exit->SetLocations(nullptr);
 }
diff --git a/compiler/optimizing/code_generator_x86.h b/compiler/optimizing/code_generator_x86.h
index 623e832..1ad89c9 100644
--- a/compiler/optimizing/code_generator_x86.h
+++ b/compiler/optimizing/code_generator_x86.h
@@ -201,7 +201,6 @@
                              Label* true_target,
                              Label* false_target,
                              Label* always_true_target);
-  void HandleGoto(HInstruction* got, HBasicBlock* successor);
 
   X86Assembler* const assembler_;
   CodeGeneratorX86* const codegen_;
diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc
index 22f5d96..a8f57cc 100644
--- a/compiler/optimizing/code_generator_x86_64.cc
+++ b/compiler/optimizing/code_generator_x86_64.cc
@@ -786,7 +786,12 @@
   }
 }
 
-void InstructionCodeGeneratorX86_64::HandleGoto(HInstruction* got, HBasicBlock* successor) {
+void LocationsBuilderX86_64::VisitGoto(HGoto* got) {
+  got->SetLocations(nullptr);
+}
+
+void InstructionCodeGeneratorX86_64::VisitGoto(HGoto* got) {
+  HBasicBlock* successor = got->GetSuccessor();
   DCHECK(!successor->IsExitBlock());
 
   HBasicBlock* block = got->GetBlock();
@@ -806,25 +811,6 @@
   }
 }
 
-void LocationsBuilderX86_64::VisitGoto(HGoto* got) {
-  got->SetLocations(nullptr);
-}
-
-void InstructionCodeGeneratorX86_64::VisitGoto(HGoto* got) {
-  HandleGoto(got, got->GetSuccessor());
-}
-
-void LocationsBuilderX86_64::VisitTryBoundary(HTryBoundary* try_boundary) {
-  try_boundary->SetLocations(nullptr);
-}
-
-void InstructionCodeGeneratorX86_64::VisitTryBoundary(HTryBoundary* try_boundary) {
-  HBasicBlock* successor = try_boundary->GetNormalFlowSuccessor();
-  if (!successor->IsExitBlock()) {
-    HandleGoto(try_boundary, successor);
-  }
-}
-
 void LocationsBuilderX86_64::VisitExit(HExit* exit) {
   exit->SetLocations(nullptr);
 }
diff --git a/compiler/optimizing/code_generator_x86_64.h b/compiler/optimizing/code_generator_x86_64.h
index c2aa56b..a18e89a 100644
--- a/compiler/optimizing/code_generator_x86_64.h
+++ b/compiler/optimizing/code_generator_x86_64.h
@@ -202,7 +202,6 @@
                              Label* true_target,
                              Label* false_target,
                              Label* always_true_target);
-  void HandleGoto(HInstruction* got, HBasicBlock* successor);
 
   X86_64Assembler* const assembler_;
   CodeGeneratorX86_64* const codegen_;
diff --git a/compiler/optimizing/graph_checker.cc b/compiler/optimizing/graph_checker.cc
index d7e6bd8..fd28f0b 100644
--- a/compiler/optimizing/graph_checker.cc
+++ b/compiler/optimizing/graph_checker.cc
@@ -81,10 +81,7 @@
   }
 
   // Ensure `block` ends with a branch instruction.
-  // This invariant is not enforced on non-SSA graphs. Graph built from DEX with
-  // dead code that falls out of the method will not end with a control-flow
-  // instruction. Such code is removed during the SSA-building DCE phase.
-  if (GetGraph()->IsInSsaForm() && !block->EndsWithControlFlowInstruction()) {
+  if (!block->EndsWithControlFlowInstruction()) {
     AddError(StringPrintf("Block %d does not end with a branch instruction.",
                           block->GetBlockId()));
   }
@@ -256,22 +253,6 @@
   }
 }
 
-void GraphChecker::VisitReturn(HReturn* ret) {
-  if (!ret->GetBlock()->GetSingleSuccessor()->IsExitBlock()) {
-    AddError(StringPrintf("%s:%d does not jump to the exit block.",
-                          ret->DebugName(),
-                          ret->GetId()));
-  }
-}
-
-void GraphChecker::VisitReturnVoid(HReturnVoid* ret) {
-  if (!ret->GetBlock()->GetSingleSuccessor()->IsExitBlock()) {
-    AddError(StringPrintf("%s:%d does not jump to the exit block.",
-                          ret->DebugName(),
-                          ret->GetId()));
-  }
-}
-
 void SSAChecker::VisitBasicBlock(HBasicBlock* block) {
   super_type::VisitBasicBlock(block);
 
diff --git a/compiler/optimizing/graph_checker.h b/compiler/optimizing/graph_checker.h
index bafa69d..b4314da 100644
--- a/compiler/optimizing/graph_checker.h
+++ b/compiler/optimizing/graph_checker.h
@@ -48,10 +48,6 @@
   // Check that the HasBoundsChecks() flag is set for bounds checks.
   void VisitBoundsCheck(HBoundsCheck* check) OVERRIDE;
 
-  // Check that the Return and ReturnVoid jump to the exit block.
-  void VisitReturn(HReturn* ret) OVERRIDE;
-  void VisitReturnVoid(HReturnVoid* ret) OVERRIDE;
-
   // Was the last visit of the graph valid?
   bool IsValid() const {
     return errors_.empty();
diff --git a/compiler/optimizing/graph_visualizer.cc b/compiler/optimizing/graph_visualizer.cc
index 30d61ef..7d723ef 100644
--- a/compiler/optimizing/graph_visualizer.cc
+++ b/compiler/optimizing/graph_visualizer.cc
@@ -252,22 +252,8 @@
     AddIndent();
     output_ << "successors";
     for (size_t i = 0, e = block->GetSuccessors().Size(); i < e; ++i) {
-      if (!block->IsExceptionalSuccessor(i)) {
-        HBasicBlock* successor = block->GetSuccessors().Get(i);
-        output_ << " \"B" << successor->GetBlockId() << "\" ";
-      }
-    }
-    output_<< std::endl;
-  }
-
-  void PrintExceptionHandlers(HBasicBlock* block) {
-    AddIndent();
-    output_ << "xhandlers";
-    for (size_t i = 0, e = block->GetSuccessors().Size(); i < e; ++i) {
-      if (block->IsExceptionalSuccessor(i)) {
-        HBasicBlock* handler = block->GetSuccessors().Get(i);
-        output_ << " \"B" << handler->GetBlockId() << "\" ";
-      }
+      HBasicBlock* successor = block->GetSuccessors().Get(i);
+      output_ << " \"B" << successor->GetBlockId() << "\" ";
     }
     if (block->IsExitBlock() &&
         (disasm_info_ != nullptr) &&
@@ -379,15 +365,6 @@
                                       << std::noboolalpha;
   }
 
-  void VisitTryBoundary(HTryBoundary* try_boundary) OVERRIDE {
-    StartAttributeStream("is_entry") << std::boolalpha
-                                     << try_boundary->IsTryEntry()
-                                     << std::noboolalpha;
-    StartAttributeStream("is_exit") << std::boolalpha
-                                    << try_boundary->IsTryExit()
-                                    << std::noboolalpha;
-  }
-
   bool IsPass(const char* name) {
     return strcmp(pass_name_, name) == 0;
   }
@@ -602,14 +579,8 @@
     }
     PrintPredecessors(block);
     PrintSuccessors(block);
-    PrintExceptionHandlers(block);
-
-    if (block->IsCatchBlock()) {
-      PrintProperty("flags", "catch_block");
-    } else {
-      PrintEmptyProperty("flags");
-    }
-
+    PrintEmptyProperty("xhandlers");
+    PrintEmptyProperty("flags");
     if (block->GetDominator() != nullptr) {
       PrintProperty("dominator", "B", block->GetDominator()->GetBlockId());
     }
diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc
index 881f9ec..a6390af 100644
--- a/compiler/optimizing/nodes.cc
+++ b/compiler/optimizing/nodes.cc
@@ -189,20 +189,15 @@
   ssa_builder.BuildSsa();
 }
 
-HBasicBlock* HGraph::SplitEdge(HBasicBlock* block, HBasicBlock* successor) {
-  HBasicBlock* new_block = new (arena_) HBasicBlock(this, successor->GetDexPc());
-  AddBlock(new_block);
-  // Use `InsertBetween` to ensure the predecessor index and successor index of
-  // `block` and `successor` are preserved.
-  new_block->InsertBetween(block, successor);
-  return new_block;
-}
-
 void HGraph::SplitCriticalEdge(HBasicBlock* block, HBasicBlock* successor) {
   // Insert a new node between `block` and `successor` to split the
   // critical edge.
-  HBasicBlock* new_block = SplitEdge(block, successor);
+  HBasicBlock* new_block = new (arena_) HBasicBlock(this, successor->GetDexPc());
+  AddBlock(new_block);
   new_block->AddInstruction(new (arena_) HGoto());
+  // Use `InsertBetween` to ensure the predecessor index and successor index of
+  // `block` and `successor` are preserved.
+  new_block->InsertBetween(block, successor);
   if (successor->IsLoopHeader()) {
     // If we split at a back edge boundary, make the new block the back edge.
     HLoopInformation* info = successor->GetLoopInformation();
@@ -1024,35 +1019,6 @@
   }
 }
 
-HBasicBlock* HBasicBlock::SplitBefore(HInstruction* cursor) {
-  DCHECK(!graph_->IsInSsaForm()) << "Support for SSA form not implemented";
-  DCHECK_EQ(cursor->GetBlock(), this);
-
-  HBasicBlock* new_block = new (GetGraph()->GetArena()) HBasicBlock(GetGraph(), GetDexPc());
-  new_block->instructions_.first_instruction_ = cursor;
-  new_block->instructions_.last_instruction_ = instructions_.last_instruction_;
-  instructions_.last_instruction_ = cursor->previous_;
-  if (cursor->previous_ == nullptr) {
-    instructions_.first_instruction_ = nullptr;
-  } else {
-    cursor->previous_->next_ = nullptr;
-    cursor->previous_ = nullptr;
-  }
-
-  new_block->instructions_.SetBlockOfInstructions(new_block);
-  AddInstruction(new (GetGraph()->GetArena()) HGoto());
-
-  for (size_t i = 0, e = GetSuccessors().Size(); i < e; ++i) {
-    HBasicBlock* successor = GetSuccessors().Get(i);
-    new_block->successors_.Add(successor);
-    successor->predecessors_.Put(successor->GetPredecessorIndexOf(this), new_block);
-  }
-  successors_.Reset();
-  AddSuccessor(new_block);
-
-  return new_block;
-}
-
 HBasicBlock* HBasicBlock::SplitAfter(HInstruction* cursor) {
   DCHECK(!cursor->IsControlFlow());
   DCHECK_NE(instructions_.last_instruction_, cursor);
@@ -1082,24 +1048,14 @@
   return new_block;
 }
 
-bool HBasicBlock::IsExceptionalSuccessor(size_t idx) const {
-  return !GetInstructions().IsEmpty()
-      && GetLastInstruction()->IsTryBoundary()
-      && GetLastInstruction()->AsTryBoundary()->IsExceptionalSuccessor(idx);
-}
-
-static bool HasOnlyOneInstruction(const HBasicBlock& block) {
-  return block.GetPhis().IsEmpty()
-      && !block.GetInstructions().IsEmpty()
-      && block.GetFirstInstruction() == block.GetLastInstruction();
-}
-
 bool HBasicBlock::IsSingleGoto() const {
-  return HasOnlyOneInstruction(*this) && GetLastInstruction()->IsGoto();
-}
-
-bool HBasicBlock::IsSingleTryBoundary() const {
-  return HasOnlyOneInstruction(*this) && GetLastInstruction()->IsTryBoundary();
+  HLoopInformation* loop_info = GetLoopInformation();
+  DCHECK(EndsWithControlFlowInstruction());
+  return GetPhis().IsEmpty()
+         && GetFirstInstruction() == GetLastInstruction()
+         && GetLastInstruction()->IsGoto()
+         // Back edges generate the suspend check.
+         && (loop_info == nullptr || !loop_info->IsBackEdge(*this));
 }
 
 bool HBasicBlock::EndsWithControlFlowInstruction() const {
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index f2e9e22..0f5b1ab 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -39,7 +39,6 @@
 class HDoubleConstant;
 class HEnvironment;
 class HFloatConstant;
-class HGraphBuilder;
 class HGraphVisitor;
 class HInstruction;
 class HIntConstant;
@@ -208,12 +207,6 @@
   // Removes `block` from the graph.
   void DeleteDeadBlock(HBasicBlock* block);
 
-  // Splits the edge between `block` and `successor` while preserving the
-  // indices in the predecessor/successor lists. If there are multiple edges
-  // between the blocks, the lowest indices are used.
-  // Returns the new block which is empty and has the same dex pc as `successor`.
-  HBasicBlock* SplitEdge(HBasicBlock* block, HBasicBlock* successor);
-
   void SplitCriticalEdge(HBasicBlock* block, HBasicBlock* successor);
   void SimplifyLoop(HBasicBlock* header);
 
@@ -573,15 +566,6 @@
   }
 
   bool IsSingleGoto() const;
-  bool IsSingleTryBoundary() const;
-
-  // Returns true if this block emits nothing but a jump.
-  bool IsSingleJump() const {
-    HLoopInformation* loop_info = GetLoopInformation();
-    return (IsSingleGoto() || IsSingleTryBoundary())
-           // Back edges generate a suspend check.
-           && (loop_info == nullptr || !loop_info->IsBackEdge(*this));
-  }
 
   void AddBackEdge(HBasicBlock* back_edge) {
     if (loop_information_ == nullptr) {
@@ -690,7 +674,7 @@
     successors_.Put(1, temp);
   }
 
-  size_t GetPredecessorIndexOf(HBasicBlock* predecessor) const {
+  size_t GetPredecessorIndexOf(HBasicBlock* predecessor) {
     for (size_t i = 0, e = predecessors_.Size(); i < e; ++i) {
       if (predecessors_.Get(i) == predecessor) {
         return i;
@@ -699,7 +683,7 @@
     return -1;
   }
 
-  size_t GetSuccessorIndexOf(HBasicBlock* successor) const {
+  size_t GetSuccessorIndexOf(HBasicBlock* successor) {
     for (size_t i = 0, e = successors_.Size(); i < e; ++i) {
       if (successors_.Get(i) == successor) {
         return i;
@@ -708,32 +692,6 @@
     return -1;
   }
 
-  HBasicBlock* GetSinglePredecessor() const {
-    DCHECK_EQ(GetPredecessors().Size(), 1u);
-    return GetPredecessors().Get(0);
-  }
-
-  HBasicBlock* GetSingleSuccessor() const {
-    DCHECK_EQ(GetSuccessors().Size(), 1u);
-    return GetSuccessors().Get(0);
-  }
-
-  // Returns whether the first occurrence of `predecessor` in the list of
-  // predecessors is at index `idx`.
-  bool IsFirstIndexOfPredecessor(HBasicBlock* predecessor, size_t idx) const {
-    DCHECK_EQ(GetPredecessors().Get(idx), predecessor);
-    return GetPredecessorIndexOf(predecessor) == idx;
-  }
-
-  // Returns whether successor at index `idx` is an exception handler.
-  bool IsExceptionalSuccessor(size_t idx) const;
-
-  // Split the block into two blocks just before `cursor`. Returns the newly
-  // created, latter block. Note that this method will create a Goto at the end
-  // of the former block and will create an edge between them. It will not,
-  // however, update the graph, reverse post order or loop information.
-  HBasicBlock* SplitBefore(HInstruction* cursor);
-
   // Split the block into two blocks just after `cursor`. Returns the newly
   // created block. Note that this method just updates raw block information,
   // like predecessors, successors, dominators, and instruction list. It does not
@@ -955,7 +913,6 @@
   M(SuspendCheck, Instruction)                                          \
   M(Temporary, Instruction)                                             \
   M(Throw, Instruction)                                                 \
-  M(TryBoundary, Instruction)                                           \
   M(TypeConversion, Instruction)                                        \
   M(UShr, BinaryOperation)                                              \
   M(Xor, BinaryOperation)                                               \
@@ -1901,7 +1858,7 @@
   bool IsControlFlow() const OVERRIDE { return true; }
 
   HBasicBlock* GetSuccessor() const {
-    return GetBlock()->GetSingleSuccessor();
+    return GetBlock()->GetSuccessors().Get(0);
   }
 
   DECLARE_INSTRUCTION(Goto);
@@ -1935,65 +1892,6 @@
   DISALLOW_COPY_AND_ASSIGN(HIf);
 };
 
-
-// Abstract instruction which marks the beginning and/or end of a try block and
-// links it to the respective exception handlers. Behaves the same as a Goto in
-// non-exceptional control flow.
-// Normal-flow successor is stored at index zero, exception handlers under
-// higher indices in no particular order.
-class HTryBoundary : public HTemplateInstruction<0> {
- public:
-  HTryBoundary(bool is_entry, bool is_exit)
-      : HTemplateInstruction(SideEffects::None()), is_entry_(is_entry), is_exit_(is_exit) {}
-
-  bool IsControlFlow() const OVERRIDE { return true; }
-
-  // Returns the block's non-exceptional successor (index zero).
-  HBasicBlock* GetNormalFlowSuccessor() const { return GetBlock()->GetSuccessors().Get(0); }
-
-  // Returns whether `handler` is among its exception handlers (non-zero index
-  // successors).
-  bool HasExceptionHandler(HBasicBlock* handler) const {
-    DCHECK(handler->IsCatchBlock());
-    return GetBlock()->GetSuccessors().Contains(handler, /* start_from */ 1);
-  }
-
-  // Returns whether successor at index `idx` is an exception handler.
-  bool IsExceptionalSuccessor(size_t idx) const {
-    DCHECK_LT(idx, GetBlock()->GetSuccessors().Size());
-    bool is_handler = (idx != 0);
-    DCHECK(!is_handler || GetBlock()->GetSuccessors().Get(idx)->IsCatchBlock());
-    return is_handler;
-  }
-
-  // If not present already, adds `handler` to its block's list of exception
-  // handlers.
-  void AddExceptionHandler(HBasicBlock* handler) {
-    if (!HasExceptionHandler(handler)) {
-      GetBlock()->AddSuccessor(handler);
-    }
-  }
-
-  bool IsTryEntry() const { return is_entry_; }
-  bool IsTryExit() const { return is_exit_; }
-
-  DECLARE_INSTRUCTION(TryBoundary);
-
- private:
-  // Only for debugging purposes.
-  bool is_entry_;
-  bool is_exit_;
-
-  // Only set by HGraphBuilder.
-  void SetIsTryEntry() { is_entry_ = true; }
-  void SetIsTryExit() { is_exit_ = true; }
-
-  friend HGraphBuilder;
-
-  DISALLOW_COPY_AND_ASSIGN(HTryBoundary);
-};
-
-
 // Deoptimize to interpreter, upon checking a condition.
 class HDeoptimize : public HTemplateInstruction<1> {
  public:
diff --git a/compiler/utils/growable_array.h b/compiler/utils/growable_array.h
index f85e026..e4b1e7d 100644
--- a/compiler/utils/growable_array.h
+++ b/compiler/utils/growable_array.h
@@ -46,8 +46,8 @@
       }
     }
 
-    bool Contains(T value, size_t start_from = 0) const {
-      for (size_t i = start_from; i < num_used_; ++i) {
+    bool Contains(T value) const {
+      for (size_t i = 0; i < num_used_; ++i) {
         if (elem_list_[i] == value) {
           return true;
         }
diff --git a/test/510-checker-try-catch/expected.txt b/test/510-checker-try-catch/expected.txt
deleted file mode 100644
index e69de29..0000000
--- a/test/510-checker-try-catch/expected.txt
+++ /dev/null
diff --git a/test/510-checker-try-catch/info.txt b/test/510-checker-try-catch/info.txt
deleted file mode 100644
index 9ffcb19..0000000
--- a/test/510-checker-try-catch/info.txt
+++ /dev/null
@@ -1 +0,0 @@
-Tests the generation of try/catch blocks in Optimizing.
\ No newline at end of file
diff --git a/test/510-checker-try-catch/smali/Builder.smali b/test/510-checker-try-catch/smali/Builder.smali
deleted file mode 100644
index a388aa1..0000000
--- a/test/510-checker-try-catch/smali/Builder.smali
+++ /dev/null
@@ -1,914 +0,0 @@
-# Copyright (C) 2015 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-.class public LBuilder;
-
-.super Ljava/lang/Object;
-
-# Basic test case with two try blocks and three catch handlers, one of which
-# is shared by the two tries.
-
-## CHECK-START: int Builder.testMultipleTryCatch(int, int, int) builder (after)
-
-## CHECK:  name             "B0"
-## CHECK:  successors       "<<BEnterTry1:B\d+>>"
-## CHECK:  <<Minus1:i\d+>>  IntConstant -1
-## CHECK:  <<Minus2:i\d+>>  IntConstant -2
-## CHECK:  <<Minus3:i\d+>>  IntConstant -3
-
-## CHECK:  name             "<<BTry1:B\d+>>"
-## CHECK:  predecessors     "<<BEnterTry1>>"
-## CHECK:  successors       "<<BExitTry1:B\d+>>"
-## CHECK:  DivZeroCheck
-
-## CHECK:  name             "<<BAdd:B\d+>>"
-## CHECK:  predecessors     "<<BExitTry1>>"
-## CHECK:  successors       "<<BEnterTry2:B\d+>>"
-## CHECK:  Add
-
-## CHECK:  name             "<<BTry2:B\d+>>"
-## CHECK:  predecessors     "<<BEnterTry2>>"
-## CHECK:  successors       "<<BExitTry2:B\d+>>"
-## CHECK:  DivZeroCheck
-
-## CHECK:  name             "<<BReturn:B\d+>>"
-## CHECK:  predecessors     "<<BExitTry2>>" "<<BCatch1:B\d+>>" "<<BCatch2:B\d+>>" "<<BCatch3:B\d+>>"
-## CHECK:  Return
-
-## CHECK:  name             "<<BCatch1>>"
-## CHECK:  predecessors     "<<BEnterTry1>>" "<<BExitTry1>>"
-## CHECK:  successors       "<<BReturn>>"
-## CHECK:  flags            "catch_block"
-## CHECK:  StoreLocal       [v0,<<Minus1>>]
-
-## CHECK:  name             "<<BCatch2>>"
-## CHECK:  predecessors     "<<BEnterTry2>>" "<<BExitTry2>>"
-## CHECK:  successors       "<<BReturn>>"
-## CHECK:  flags            "catch_block"
-## CHECK:  StoreLocal       [v0,<<Minus2>>]
-
-## CHECK:  name             "<<BCatch3>>"
-## CHECK:  predecessors     "<<BEnterTry1>>" "<<BExitTry1>>" "<<BEnterTry2>>" "<<BExitTry2>>"
-## CHECK:  successors       "<<BReturn>>"
-## CHECK:  flags            "catch_block"
-## CHECK:  StoreLocal       [v0,<<Minus3>>]
-
-## CHECK:  name             "<<BEnterTry1>>"
-## CHECK:  predecessors     "B0"
-## CHECK:  successors       "<<BTry1>>"
-## CHECK:  xhandlers        "<<BCatch1>>" "<<BCatch3>>"
-## CHECK:  TryBoundary      is_entry:true is_exit:false
-
-## CHECK:  name             "<<BExitTry1>>"
-## CHECK:  predecessors     "<<BTry1>>"
-## CHECK:  successors       "<<BAdd>>"
-## CHECK:  xhandlers        "<<BCatch1>>" "<<BCatch3>>"
-## CHECK:  TryBoundary      is_entry:false is_exit:true
-
-## CHECK:  name             "<<BEnterTry2>>"
-## CHECK:  predecessors     "<<BAdd>>"
-## CHECK:  successors       "<<BTry2>>"
-## CHECK:  xhandlers        "<<BCatch2>>" "<<BCatch3>>"
-## CHECK:  TryBoundary      is_entry:true is_exit:false
-
-## CHECK:  name             "<<BExitTry2>>"
-## CHECK:  predecessors     "<<BTry2>>"
-## CHECK:  successors       "<<BReturn>>"
-## CHECK:  xhandlers        "<<BCatch2>>" "<<BCatch3>>"
-## CHECK:  TryBoundary      is_entry:false is_exit:true
-
-.method public static testMultipleTryCatch(III)I
-    .registers 3
-
-    :try_start_1
-    div-int/2addr p0, p1
-    :try_end_1
-    .catch Ljava/lang/ArithmeticException; {:try_start_1 .. :try_end_1} :catch_arith
-    .catchall {:try_start_1 .. :try_end_1} :catch_other
-
-    add-int/2addr p0, p0
-
-    :try_start_2
-    div-int/2addr p0, p2
-    :try_end_2
-    .catch Ljava/lang/OutOfMemoryError; {:try_start_2 .. :try_end_2} :catch_mem
-    .catchall {:try_start_2 .. :try_end_2} :catch_other
-
-    :return
-    return p0
-
-    :catch_arith
-    const/4 p0, -0x1
-    goto :return
-
-    :catch_mem
-    const/4 p0, -0x2
-    goto :return
-
-    :catch_other
-    const/4 p0, -0x3
-    goto :return
-.end method
-
-# Test that multiple try-entry blocks are generated if there are multiple entry
-# points into the try block.
-
-## CHECK-START: int Builder.testMultipleEntries(int, int, int, int) builder (after)
-
-## CHECK:  name             "B0"
-## CHECK:  successors       "<<BIf:B\d+>>"
-## CHECK:  <<Minus1:i\d+>>  IntConstant -1
-
-## CHECK:  name             "<<BIf>>"
-## CHECK:  predecessors     "B0"
-## CHECK:  successors       "<<BEnterTry2:B\d+>>" "<<BThen:B\d+>>"
-## CHECK:  If
-
-## CHECK:  name             "<<BThen>>"
-## CHECK:  predecessors     "<<BIf>>"
-## CHECK:  successors       "<<BEnterTry1:B\d+>>"
-## CHECK:  Div
-
-## CHECK:  name             "<<BTry1:B\d+>>"
-## CHECK:  predecessors     "<<BEnterTry1>>"
-## CHECK:  successors       "<<BTry2:B\d+>>"
-## CHECK:  Div
-
-## CHECK:  name             "<<BTry2>>"
-## CHECK:  predecessors     "<<BEnterTry2>>" "<<BTry1>>"
-## CHECK:  successors       "<<BExitTry:B\d+>>"
-## CHECK:  Div
-
-## CHECK:  name             "<<BReturn:B\d+>>"
-## CHECK:  predecessors     "<<BExitTry>>" "<<BCatch:B\d+>>"
-## CHECK:  Return
-
-## CHECK:  name             "<<BCatch>>"
-## CHECK:  predecessors     "<<BEnterTry1>>" "<<BEnterTry2>>" "<<BExitTry>>"
-## CHECK:  successors       "<<BReturn>>"
-## CHECK:  flags            "catch_block"
-## CHECK:  StoreLocal       [v0,<<Minus1>>]
-
-## CHECK:  name             "<<BEnterTry1>>"
-## CHECK:  predecessors     "<<BThen>>"
-## CHECK:  successors       "<<BTry1>>"
-## CHECK:  xhandlers        "<<BCatch>>"
-## CHECK:  TryBoundary      is_entry:true is_exit:false
-
-## CHECK:  name             "<<BEnterTry2>>"
-## CHECK:  predecessors     "<<BIf>>"
-## CHECK:  successors       "<<BTry2>>"
-## CHECK:  xhandlers        "<<BCatch>>"
-## CHECK:  TryBoundary      is_entry:true is_exit:false
-
-## CHECK:  name             "<<BExitTry>>"
-## CHECK:  predecessors     "<<BTry2>>"
-## CHECK:  successors       "<<BReturn>>"
-## CHECK:  xhandlers        "<<BCatch>>"
-## CHECK:  TryBoundary      is_entry:false is_exit:true
-
-.method public static testMultipleEntries(IIII)I
-    .registers 4
-
-    if-eqz p2, :else
-
-    div-int/2addr p0, p1
-
-    :try_start
-    div-int/2addr p0, p2
-
-    :else
-    div-int/2addr p0, p3
-    :try_end
-    .catchall {:try_start .. :try_end} :catch_all
-
-    :return
-    return p0
-
-    :catch_all
-    const/4 p0, -0x1
-    goto :return
-
-.end method
-
-# Test that multiple try-exit blocks are generated if (normal) control flow can
-# jump out of the try block at multiple points.
-
-## CHECK-START: int Builder.testMultipleExits(int, int) builder (after)
-
-## CHECK:  name             "B0"
-## CHECK:  successors       "<<BEnterTry:B\d+>>"
-## CHECK:  <<Minus1:i\d+>>  IntConstant -1
-## CHECK:  <<Minus2:i\d+>>  IntConstant -2
-
-## CHECK:  name             "<<BTry:B\d+>>"
-## CHECK:  predecessors     "<<BEnterTry>>"
-## CHECK:  successors       "<<BExitTry1:B\d+>>" "<<BExitTry2:B\d+>>"
-## CHECK:  Div
-## CHECK:  If
-
-## CHECK:  name             "<<BReturn:B\d+>>"
-## CHECK:  predecessors     "<<BExitTry2>>" "<<BThen:B\d+>>" "<<BCatch:B\d+>>"
-## CHECK:  Return
-
-## CHECK:  name             "<<BThen>>"
-## CHECK:  predecessors     "<<BExitTry1>>"
-## CHECK:  successors       "<<BReturn>>"
-## CHECK:  StoreLocal       [v0,<<Minus1>>]
-
-## CHECK:  name             "<<BCatch>>"
-## CHECK:  predecessors     "<<BEnterTry>>" "<<BExitTry1>>" "<<BExitTry2>>"
-## CHECK:  successors       "<<BReturn>>"
-## CHECK:  flags            "catch_block"
-## CHECK:  StoreLocal       [v0,<<Minus2>>]
-
-## CHECK:  name             "<<BEnterTry>>"
-## CHECK:  predecessors     "B0"
-## CHECK:  successors       "<<BTry>>"
-## CHECK:  xhandlers        "<<BCatch>>"
-## CHECK:  TryBoundary      is_entry:true is_exit:false
-
-## CHECK:  name             "<<BExitTry1>>"
-## CHECK:  predecessors     "<<BTry>>"
-## CHECK:  successors       "<<BThen>>"
-## CHECK:  xhandlers        "<<BCatch>>"
-## CHECK:  TryBoundary      is_entry:false is_exit:true
-
-## CHECK:  name             "<<BExitTry2>>"
-## CHECK:  predecessors     "<<BTry>>"
-## CHECK:  successors       "<<BReturn>>"
-## CHECK:  xhandlers        "<<BCatch>>"
-## CHECK:  TryBoundary      is_entry:false is_exit:true
-
-.method public static testMultipleExits(II)I
-    .registers 2
-
-    :try_start
-    div-int/2addr p0, p1
-    if-eqz p0, :then
-    :try_end
-    .catchall {:try_start .. :try_end} :catch_all
-
-    :return
-    return p0
-
-    :then
-    const/4 p0, -0x1
-    goto :return
-
-    :catch_all
-    const/4 p0, -0x2
-    goto :return
-.end method
-
-# Test that only one TryBoundary is inserted when an edge connects two different
-# try ranges.
-
-## CHECK-START: int Builder.testSharedBoundary(int, int, int) builder (after)
-
-## CHECK:  name             "B0"
-## CHECK:  successors       "<<BEnter1:B\d+>>"
-## CHECK:  <<Minus1:i\d+>>  IntConstant -1
-## CHECK:  <<Minus2:i\d+>>  IntConstant -2
-
-## CHECK:  name             "<<BTry1:B\d+>>"
-## CHECK:  predecessors     "<<BEnter1>>"
-## CHECK:  successors       "<<BExit1Enter2:B\d+>>"
-## CHECK:  Div
-
-## CHECK:  name             "<<BTry2:B\d+>>"
-## CHECK:  predecessors     "<<BExit1Enter2>>"
-## CHECK:  successors       "<<BExit2:B\d+>>"
-## CHECK:  Div
-
-## CHECK:  name             "<<BReturn:B\d+>>"
-## CHECK:  predecessors     "<<BExit2>>" "<<BCatch1:B\d+>>" "<<BCatch2:B\d+>>"
-## CHECK:  Return
-
-## CHECK:  name             "<<BCatch1>>"
-## CHECK:  predecessors     "<<BEnter1>>" "<<BExit1Enter2>>"
-## CHECK:  successors       "<<BReturn>>"
-## CHECK:  flags            "catch_block"
-## CHECK:  StoreLocal       [v0,<<Minus1>>]
-
-## CHECK:  name             "<<BCatch2>>"
-## CHECK:  predecessors     "<<BExit1Enter2>>" "<<BExit2>>"
-## CHECK:  successors       "<<BReturn>>"
-## CHECK:  flags            "catch_block"
-## CHECK:  StoreLocal       [v0,<<Minus2>>]
-
-## CHECK:  name             "<<BEnter1>>"
-## CHECK:  predecessors     "B0"
-## CHECK:  successors       "<<BTry1>>"
-## CHECK:  xhandlers        "<<BCatch1>>"
-## CHECK:  TryBoundary      is_entry:true is_exit:false
-
-## CHECK:  name             "<<BExit1Enter2>>"
-## CHECK:  predecessors     "<<BTry1>>"
-## CHECK:  successors       "<<BTry2>>"
-## CHECK:  xhandlers        "<<BCatch1>>" "<<BCatch2>>"
-## CHECK:  TryBoundary      is_entry:true is_exit:true
-
-## CHECK:  name             "<<BExit2>>"
-## CHECK:  predecessors     "<<BTry2>>"
-## CHECK:  successors       "<<BReturn>>"
-## CHECK:  xhandlers        "<<BCatch2>>"
-## CHECK:  TryBoundary      is_entry:false is_exit:true
-
-.method public static testSharedBoundary(III)I
-    .registers 3
-
-    :try_start_1
-    div-int/2addr p0, p1
-    :try_end_1
-    .catchall {:try_start_1 .. :try_end_1} :catch_all_1
-
-    :try_start_2
-    div-int/2addr p0, p2
-    :try_end_2
-    .catchall {:try_start_2 .. :try_end_2} :catch_all_2
-
-    :return
-    return p0
-
-    :catch_all_1
-    const/4 p0, -0x1
-    goto :return
-
-    :catch_all_2
-    const/4 p0, -0x2
-    goto :return
-.end method
-
-# Same as previous test, only the blocks are processed in the opposite order.
-
-## CHECK-START: int Builder.testSharedBoundary_Reverse(int, int, int) builder (after)
-
-## CHECK:  name             "B0"
-## CHECK:  successors       "<<BGoto:B\d+>>"
-## CHECK:  <<Minus1:i\d+>>  IntConstant -1
-## CHECK:  <<Minus2:i\d+>>  IntConstant -2
-
-## CHECK:  name             "<<BGoto>>"
-## CHECK:  successors       "<<BEnter2:B\d+>>"
-## CHECK:  Goto
-
-## CHECK:  name             "<<BTry1:B\d+>>"
-## CHECK:  predecessors     "<<BExit2Enter1:B\d+>>"
-## CHECK:  successors       "<<BExit1:B\d+>>"
-## CHECK:  Div
-
-## CHECK:  name             "<<BTry2:B\d+>>"
-## CHECK:  predecessors     "<<BEnter2>>"
-## CHECK:  successors       "<<BExit2Enter1>>"
-## CHECK:  Div
-
-## CHECK:  name             "<<BReturn:B\d+>>"
-## CHECK:  predecessors     "<<BExit1>>" "<<BCatch1:B\d+>>" "<<BCatch2:B\d+>>"
-## CHECK:  Return
-
-## CHECK:  name             "<<BCatch1>>"
-## CHECK:  predecessors     "<<BExit2Enter1>>" "<<BExit1>>"
-## CHECK:  successors       "<<BReturn>>"
-## CHECK:  flags            "catch_block"
-## CHECK:  StoreLocal       [v0,<<Minus1>>]
-
-## CHECK:  name             "<<BCatch2>>"
-## CHECK:  predecessors     "<<BEnter2>>" "<<BExit2Enter1>>"
-## CHECK:  successors       "<<BReturn>>"
-## CHECK:  flags            "catch_block"
-## CHECK:  StoreLocal       [v0,<<Minus2>>]
-
-## CHECK:  name             "<<BExit2Enter1>>"
-## CHECK:  predecessors     "<<BTry2>>"
-## CHECK:  successors       "<<BTry1>>"
-## CHECK:  xhandlers        "<<BCatch1>>" "<<BCatch2>>"
-## CHECK:  TryBoundary      is_entry:true is_exit:true
-
-## CHECK:  name             "<<BExit1>>"
-## CHECK:  predecessors     "<<BTry1>>"
-## CHECK:  successors       "<<BReturn>>"
-## CHECK:  xhandlers        "<<BCatch1>>"
-## CHECK:  TryBoundary      is_entry:false is_exit:true
-
-## CHECK:  name             "<<BEnter2>>"
-## CHECK:  predecessors     "<<BGoto>>"
-## CHECK:  successors       "<<BTry2>>"
-## CHECK:  xhandlers        "<<BCatch2>>"
-## CHECK:  TryBoundary      is_entry:true is_exit:false
-
-.method public static testSharedBoundary_Reverse(III)I
-    .registers 3
-
-    goto :try_start_2
-
-    :try_start_1
-    div-int/2addr p0, p1
-    goto :return
-    :try_end_1
-    .catchall {:try_start_1 .. :try_end_1} :catch_all_1
-
-    :try_start_2
-    div-int/2addr p0, p2
-    goto :try_start_1
-    :try_end_2
-    .catchall {:try_start_2 .. :try_end_2} :catch_all_2
-
-    :return
-    return p0
-
-    :catch_all_1
-    const/4 p0, -0x1
-    goto :return
-
-    :catch_all_2
-    const/4 p0, -0x2
-    goto :return
-.end method
-
-# Test that nested tries are split into non-overlapping blocks and TryBoundary
-# blocks are correctly created between them.
-
-## CHECK-START: int Builder.testNestedTry(int, int, int, int) builder (after)
-
-## CHECK:  name             "B0"
-## CHECK:  <<Minus1:i\d+>>  IntConstant -1
-## CHECK:  <<Minus2:i\d+>>  IntConstant -2
-
-## CHECK:  name             "<<BTry1:B\d+>>"
-## CHECK:  predecessors     "<<BEnter1:B\d+>>"
-## CHECK:  successors       "<<BExit1Enter2:B\d+>>"
-## CHECK:  Div
-
-## CHECK:  name             "<<BTry2:B\d+>>"
-## CHECK:  predecessors     "<<BExit1Enter2>>"
-## CHECK:  successors       "<<BExit2Enter3:B\d+>>"
-## CHECK:  Div
-
-## CHECK:  name             "<<BTry3:B\d+>>"
-## CHECK:  predecessors     "<<BExit2Enter3>>"
-## CHECK:  successors       "<<BExit3:B\d+>>"
-## CHECK:  Div
-
-## CHECK:  name             "<<BReturn:B\d+>>"
-## CHECK:  predecessors     "<<BExit3>>" "<<BCatchArith:B\d+>>" "<<BCatchAll:B\d+>>"
-
-## CHECK:  name             "<<BCatchArith>>"
-## CHECK:  predecessors     "<<BExit1Enter2>>" "<<BExit2Enter3>>"
-## CHECK:  successors       "<<BReturn>>"
-## CHECK:  flags            "catch_block"
-## CHECK:  StoreLocal       [v0,<<Minus1>>]
-
-## CHECK:  name             "<<BCatchAll>>"
-## CHECK:  predecessors     "<<BEnter1>>" "<<BExit1Enter2>>" "<<BExit2Enter3>>" "<<BExit3>>"
-## CHECK:  successors       "<<BReturn>>"
-## CHECK:  flags            "catch_block"
-## CHECK:  StoreLocal       [v0,<<Minus2>>]
-
-## CHECK:  name             "<<BEnter1>>"
-## CHECK:  predecessors     "B0"
-## CHECK:  successors       "<<BTry1>>"
-## CHECK:  xhandlers        "<<BCatchAll>>"
-## CHECK:  TryBoundary      is_entry:true is_exit:false
-
-## CHECK:  name             "<<BExit1Enter2>>"
-## CHECK:  predecessors     "<<BTry1>>"
-## CHECK:  successors       "<<BTry2>>"
-## CHECK:  xhandlers        "<<BCatchAll>>" "<<BCatchArith>>"
-## CHECK:  TryBoundary      is_entry:true is_exit:true
-
-## CHECK:  name             "<<BExit2Enter3>>"
-## CHECK:  predecessors     "<<BTry2>>"
-## CHECK:  successors       "<<BTry3>>"
-## CHECK:  xhandlers        "<<BCatchArith>>" "<<BCatchAll>>"
-## CHECK:  TryBoundary      is_entry:true is_exit:true
-
-## CHECK:  name             "<<BExit3>>"
-## CHECK:  predecessors     "<<BTry3>>"
-## CHECK:  successors       "<<BReturn>>"
-## CHECK:  xhandlers        "<<BCatchAll>>"
-## CHECK:  TryBoundary      is_entry:false is_exit:true
-
-.method public static testNestedTry(IIII)I
-    .registers 4
-
-    :try_start_1
-    div-int/2addr p0, p1
-
-    :try_start_2
-    div-int/2addr p0, p2
-    :try_end_2
-    .catch Ljava/lang/ArithmeticException; {:try_start_2 .. :try_end_2} :catch_arith
-
-    div-int/2addr p0, p3
-    :try_end_1
-    .catchall {:try_start_1 .. :try_end_1} :catch_all
-
-    :return
-    return p0
-
-    :catch_arith
-    const/4 p0, -0x1
-    goto :return
-
-    :catch_all
-    const/4 p0, -0x2
-    goto :return
-.end method
-
-# Test control flow that enters a try block, leaves it and returns again.
-
-## CHECK-START: int Builder.testIncontinuousTry(int, int, int, int) builder (after)
-
-## CHECK:  name             "B0"
-## CHECK:  <<Minus1:i\d+>>  IntConstant -1
-
-## CHECK:  name             "<<BTry1:B\d+>>"
-## CHECK:  predecessors     "<<BEnterTry1:B\d+>>"
-## CHECK:  successors       "<<BExitTry1:B\d+>>"
-## CHECK:  Div
-
-## CHECK:  name             "<<BTry2:B\d+>>"
-## CHECK:  predecessors     "<<BEnterTry2:B\d+>>"
-## CHECK:  successors       "<<BExitTry2:B\d+>>"
-## CHECK:  Div
-
-## CHECK:  name             "<<BReturn:B\d+>>"
-## CHECK:  predecessors     "<<BExitTry2>>" "<<BCatch:B\d+>>"
-
-## CHECK:  name             "<<BOutside:B\d+>>"
-## CHECK:  predecessors     "<<BExitTry1>>"
-## CHECK:  successors       "<<BEnterTry2>>"
-## CHECK:  Div
-
-## CHECK:  name             "<<BCatch>>"
-## CHECK:  predecessors     "<<BEnterTry1>>" "<<BExitTry1>>" "<<BEnterTry2>>" "<<BExitTry2>>"
-## CHECK:  successors       "<<BReturn>>"
-## CHECK:  flags            "catch_block"
-## CHECK:  StoreLocal       [v0,<<Minus1>>]
-
-## CHECK:  name             "<<BEnterTry1>>"
-## CHECK:  predecessors     "B0"
-## CHECK:  successors       "<<BTry1>>"
-## CHECK:  xhandlers        "<<BCatch>>"
-## CHECK:  TryBoundary      is_entry:true is_exit:false
-
-## CHECK:  name             "<<BExitTry1>>"
-## CHECK:  predecessors     "<<BTry1>>"
-## CHECK:  successors       "<<BOutside>>"
-## CHECK:  xhandlers        "<<BCatch>>"
-## CHECK:  TryBoundary      is_entry:false is_exit:true
-
-## CHECK:  name             "<<BEnterTry2>>"
-## CHECK:  predecessors     "<<BOutside>>"
-## CHECK:  successors       "<<BTry2>>"
-## CHECK:  xhandlers        "<<BCatch>>"
-## CHECK:  TryBoundary      is_entry:true is_exit:false
-
-## CHECK:  name             "<<BExitTry2>>"
-## CHECK:  predecessors     "<<BTry2>>"
-## CHECK:  successors       "<<BReturn>>"
-## CHECK:  xhandlers        "<<BCatch>>"
-## CHECK:  TryBoundary      is_entry:false is_exit:true
-
-.method public static testIncontinuousTry(IIII)I
-    .registers 4
-
-    :try_start
-    div-int/2addr p0, p1
-    goto :outside
-
-    :inside
-    div-int/2addr p0, p3
-    :try_end
-    .catchall {:try_start .. :try_end} :catch_all
-
-    :return
-    return p0
-
-    :outside
-    div-int/2addr p0, p2
-    goto :inside
-
-    :catch_all
-    const/4 p0, -0x1
-    goto :return
-.end method
-
-# Test that a TryBoundary is inserted between a Throw instruction and the exit
-# block when covered by a try range.
-
-## CHECK-START: int Builder.testThrow(java.lang.Exception) builder (after)
-
-## CHECK:  name             "B0"
-## CHECK:  successors       "<<BEnterTry:B\d+>>"
-## CHECK:  <<Minus1:i\d+>>  IntConstant -1
-
-## CHECK:  name             "<<BTry:B\d+>>"
-## CHECK:  predecessors     "<<BEnterTry>>"
-## CHECK:  successors       "<<BExitTry:B\d+>>"
-## CHECK:  Throw
-
-## CHECK:  name             "<<BCatch:B\d+>>"
-## CHECK:  predecessors     "<<BEnterTry>>" "<<BExitTry>>"
-## CHECK:  successors       "<<BExit:B\d+>>"
-## CHECK:  flags            "catch_block"
-## CHECK:  StoreLocal       [v0,<<Minus1>>]
-
-## CHECK:  name             "<<BEnterTry>>"
-## CHECK:  predecessors     "B0"
-## CHECK:  successors       "<<BTry>>"
-## CHECK:  xhandlers        "<<BCatch>>"
-## CHECK:  TryBoundary      is_entry:true is_exit:false
-
-## CHECK:  name             "<<BExitTry>>"
-## CHECK:  predecessors     "<<BTry>>"
-## CHECK:  successors       "<<BExit>>"
-## CHECK:  xhandlers        "<<BCatch>>"
-## CHECK:  TryBoundary      is_entry:false is_exit:true
-
-## CHECK:  name             "<<BExit>>"
-## CHECK:  predecessors     "<<BExitTry>>" "<<BCatch>>"
-## CHECK:  Exit
-
-.method public static testThrow(Ljava/lang/Exception;)I
-    .registers 2
-
-    :try_start
-    throw p0
-    :try_end
-    .catchall {:try_start .. :try_end} :catch_all
-
-    :catch_all
-    const/4 v0, -0x1
-    return v0
-.end method
-
-# Test graph with a throw/catch loop.
-
-## CHECK-START: int Builder.testCatchLoop(int, int, int) builder (after)
-
-## CHECK:  name             "B0"
-## CHECK:  successors       "<<BEnterTry:B\d+>>"
-
-## CHECK:  name             "<<BTry:B\d+>>"
-## CHECK:  predecessors     "<<BEnterTry>>" "<<BEnterTry>>" "<<BExitTry:B\d+>>"
-## CHECK:  successors       "<<BExitTry>>"
-## CHECK:  flags            "catch_block"
-## CHECK:  Div
-
-## CHECK:  name             "<<BReturn:B\d+>>"
-## CHECK:  predecessors     "<<BExitTry>>"
-
-## CHECK:  name             "<<BEnterTry>>"
-## CHECK:  predecessors     "B0"
-## CHECK:  successors       "<<BTry>>"
-## CHECK:  xhandlers        "<<BTry>>"
-## CHECK:  TryBoundary      is_entry:true is_exit:false
-
-## CHECK:  name             "<<BExitTry>>"
-## CHECK:  predecessors     "<<BTry>>"
-## CHECK:  successors       "<<BReturn>>"
-## CHECK:  xhandlers        "<<BTry>>"
-## CHECK:  TryBoundary      is_entry:false is_exit:true
-
-.method public static testCatchLoop(III)I
-    .registers 4
-
-    :try_start
-    :catch_all
-    div-int/2addr p0, p2
-    :try_end
-    .catchall {:try_start .. :try_end} :catch_all
-
-    :return
-    return p0
-.end method
-
-# Test that handler edges are not split. In this scenario, the catch block is
-# only the handler of the try block.
-
-## CHECK-START: int Builder.testHandlerEdge1(int, int, int) builder (after)
-
-## CHECK:  name             "B0"
-## CHECK:  successors       "<<BEnterTry:B\d+>>"
-
-## CHECK:  name             "<<BTry:B\d+>>"
-## CHECK:  predecessors     "<<BEnterTry>>"
-## CHECK:  successors       "<<BCatch:B\d+>>"
-## CHECK:  Div
-
-## CHECK:  name             "<<BCatch>>"
-## CHECK:  predecessors     "<<BTry>>" "<<BEnterTry>>" "<<BExitTry:B\d+>>"
-## CHECK:  successors       "<<BExitTry>>"
-## CHECK:  flags            "catch_block"
-## CHECK:  Div
-
-## CHECK:  name             "<<BReturn:B\d+>>"
-## CHECK:  predecessors     "<<BExitTry>>"
-
-## CHECK:  name             "<<BEnterTry>>"
-## CHECK:  predecessors     "B0"
-## CHECK:  successors       "<<BTry>>"
-## CHECK:  xhandlers        "<<BCatch>>"
-## CHECK:  TryBoundary      is_entry:true is_exit:false
-
-## CHECK:  name             "<<BExitTry>>"
-## CHECK:  predecessors     "<<BCatch>>"
-## CHECK:  successors       "<<BReturn>>"
-## CHECK:  xhandlers        "<<BCatch>>"
-## CHECK:  TryBoundary      is_entry:false is_exit:true
-
-.method public static testHandlerEdge1(III)I
-    .registers 4
-
-    :try_start
-    div-int/2addr p0, p1
-
-    :catch_all
-    div-int/2addr p0, p2
-    :try_end
-    .catchall {:try_start .. :try_end} :catch_all
-
-    return p0
-.end method
-
-# Test that handler edges are not split. In this scenario, the catch block is
-# the handler and also the successor of the try block.
-
-## CHECK-START: int Builder.testHandlerEdge2(int, int, int) builder (after)
-
-## CHECK:  name             "B0"
-## CHECK:  successors       "<<BEnter1:B\d+>>"
-
-## CHECK:  name             "<<BTry1:B\d+>>"
-## CHECK:  predecessors     "<<BEnter1>>" "<<BExit1Enter2:B\d+>>" "<<BExit2:B\d+>>"
-## CHECK:  successors       "<<BExit1Enter2>>"
-## CHECK:  flags            "catch_block"
-## CHECK:  Div
-
-## CHECK:  name             "<<BTry2:B\d+>>"
-## CHECK:  predecessors     "<<BExit1Enter2>>" "<<BEnter1>>" "<<BExit1Enter2>>"
-## CHECK:  successors       "<<BExit2>>"
-## CHECK:  flags            "catch_block"
-## CHECK:  Div
-
-## CHECK:  name             "<<BReturn:B\d+>>"
-## CHECK:  predecessors     "<<BExit2>>"
-## CHECK:  Return
-
-## CHECK:  name             "<<BEnter1>>"
-## CHECK:  predecessors     "B0"
-## CHECK:  successors       "<<BTry1>>"
-## CHECK:  xhandlers        "<<BTry2>>"
-## CHECK:  TryBoundary      is_entry:true is_exit:false
-
-## CHECK:  name             "<<BExit1Enter2>>"
-## CHECK:  predecessors     "<<BTry1>>"
-## CHECK:  successors       "<<BTry2>>"
-## CHECK:  xhandlers        "<<BTry2>>" "<<BTry1>>"
-## CHECK:  TryBoundary      is_entry:true is_exit:true
-
-## CHECK:  name             "<<BExit2>>"
-## CHECK:  predecessors     "<<BTry2>>"
-## CHECK:  successors       "<<BReturn>>"
-## CHECK:  xhandlers        "<<BTry1>>"
-## CHECK:  TryBoundary      is_entry:false is_exit:true
-
-.method public static testHandlerEdge2(III)I
-    .registers 4
-
-    :try_start_1
-    :catch_all_1
-    div-int/2addr p0, p1
-    :try_end_1
-    .catchall {:try_start_1 .. :try_end_1} :catch_all_2
-
-    :try_start_2
-    :catch_all_2
-    div-int/2addr p0, p2
-    :try_end_2
-    .catchall {:try_start_2 .. :try_end_2} :catch_all_1
-
-    return p0
-.end method
-
-# Test that a MOVE_RESULT instruction is placed into the same block as the
-# INVOKE it follows, even if there is a try boundary between them.
-
-## CHECK-START: int Builder.testMoveResult_Invoke(int, int, int) builder (after)
-
-## CHECK:       <<Res:i\d+>> InvokeStaticOrDirect
-## CHECK-NEXT:  StoreLocal   [v0,<<Res>>]
-
-.method public static testMoveResult_Invoke(III)I
-    .registers 3
-
-    :try_start
-    invoke-static {p0, p1, p2}, LBuilder;->testCatchLoop(III)I
-    :try_end
-    .catchall {:try_start .. :try_end} :catch_all
-
-    move-result p0
-
-    :return
-    return p0
-
-    :catch_all
-    const/4 p0, -0x1
-    goto :return
-.end method
-
-# Test that a MOVE_RESULT instruction is placed into the same block as the
-# FILLED_NEW_ARRAY it follows, even if there is a try boundary between them.
-
-## CHECK-START: int[] Builder.testMoveResult_FilledNewArray(int, int, int) builder (after)
-
-## CHECK:      <<Res:l\d+>>  NewArray
-## CHECK-NEXT:               Temporary
-## CHECK-NEXT:               StoreLocal [v0,<<Res>>]
-## CHECK:                    ArraySet [<<Res>>,{{i\d+}},{{i\d+}}]
-## CHECK:                    ArraySet [<<Res>>,{{i\d+}},{{i\d+}}]
-## CHECK:                    ArraySet [<<Res>>,{{i\d+}},{{i\d+}}]
-
-.method public static testMoveResult_FilledNewArray(III)[I
-    .registers 3
-
-    :try_start
-    filled-new-array {p0, p1, p2}, [I
-    :try_end
-    .catchall {:try_start .. :try_end} :catch_all
-
-    move-result-object p0
-
-    :return
-    return-object p0
-
-    :catch_all
-    const/4 p0, 0x0
-    goto :return
-.end method
-
-# Test case for ReturnVoid inside a try block. Builder needs to move it outside
-# the try block so as to not split the ReturnVoid-Exit edge.
-# This invariant is enforced by GraphChecker.
-
-.method public static testReturnVoidInTry(II)V
-    .registers 2
-
-    :catch_all
-    :try_start
-    return-void
-    :try_end
-    .catchall {:try_start .. :try_end} :catch_all
-
-.end method
-
-# Test case for Return inside a try block. Builder needs to move it outside the
-# try block so as to not split the Return-Exit edge.
-# This invariant is enforced by GraphChecker.
-
-.method public static testReturnInTry(II)I
-    .registers 2
-
-    :try_start
-    div-int/2addr p0, p1
-    return p0
-    :try_end
-    .catchall {:try_start .. :try_end} :catch_all
-
-    :catch_all
-    const/4 v0, 0x0
-    return v0
-.end method
-
-# Test a (dead) try block which flows out of the method. The block will be
-# removed by DCE but needs to pass post-builder GraphChecker.
-
-## CHECK-START: int Builder.testDeadEndTry(int) builder (after)
-## CHECK-NOT:     TryBoundary is_exit:true
-
-.method public static testDeadEndTry(I)I
-    .registers 1
-
-    return p0
-
-    :catch_all
-    nop
-
-    :try_start
-    nop
-    :try_end
-    .catchall {:try_start .. :try_end} :catch_all
-.end method
diff --git a/test/510-checker-try-catch/src/Main.java b/test/510-checker-try-catch/src/Main.java
deleted file mode 100644
index ae78ba0..0000000
--- a/test/510-checker-try-catch/src/Main.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-public class Main {
-
-  // Workaround for b/18051191.
-  class InnerClass {}
-
-  public static void main(String[] args) {}
-}