Revert "Revert "ART: Register allocation and runtime support for try/catch""

The original CL triggered b/24084144 which has been fixed
by Ib72e12a018437c404e82f7ad414554c66a4c6f8c.

This reverts commit 659562aaf133c41b8d90ec9216c07646f0f14362.

Change-Id: Id8980436172457d0fcb276349c4405f7c4110a55
diff --git a/compiler/optimizing/ssa_liveness_analysis.cc b/compiler/optimizing/ssa_liveness_analysis.cc
index 0c1831b..63635f3 100644
--- a/compiler/optimizing/ssa_liveness_analysis.cc
+++ b/compiler/optimizing/ssa_liveness_analysis.cc
@@ -186,14 +186,25 @@
     // as live_in.
     for (HBasicBlock* successor : block->GetSuccessors()) {
       live_in->Union(GetLiveInSet(*successor));
-      size_t phi_input_index = successor->GetPredecessorIndexOf(block);
-      for (HInstructionIterator inst_it(successor->GetPhis()); !inst_it.Done(); inst_it.Advance()) {
-        HInstruction* phi = inst_it.Current();
-        HInstruction* input = phi->InputAt(phi_input_index);
-        input->GetLiveInterval()->AddPhiUse(phi, phi_input_index, block);
-        // A phi input whose last user is the phi dies at the end of the predecessor block,
-        // and not at the phi's lifetime position.
-        live_in->SetBit(input->GetSsaIndex());
+      if (successor->IsCatchBlock()) {
+        // Inputs of catch phis will be kept alive through their environment
+        // uses, allowing the runtime to copy their values to the corresponding
+        // catch phi spill slots when an exception is thrown.
+        // The only instructions which may not be recorded in the environments
+        // are constants created by the SSA builder as typed equivalents of
+        // untyped constants from the bytecode, or phis with only such constants
+        // as inputs (verified by SSAChecker). Their raw binary value must
+        // therefore be the same and we only need to keep alive one.
+      } else {
+        size_t phi_input_index = successor->GetPredecessorIndexOf(block);
+        for (HInstructionIterator phi_it(successor->GetPhis()); !phi_it.Done(); phi_it.Advance()) {
+          HInstruction* phi = phi_it.Current();
+          HInstruction* input = phi->InputAt(phi_input_index);
+          input->GetLiveInterval()->AddPhiUse(phi, phi_input_index, block);
+          // A phi input whose last user is the phi dies at the end of the predecessor block,
+          // and not at the phi's lifetime position.
+          live_in->SetBit(input->GetSsaIndex());
+        }
       }
     }