ART: Build SSA form when try/catch is present

This patch implements support for try/catch in the SsaBuilder.
Values of locals are propagated from throwing sites inside try
blocks to their respective catch blocks and phis ("catch phis")
are created when necessary.

Change-Id: I0736565c2c4ff3f9f0924b6e3a785a50023f875a
diff --git a/compiler/optimizing/ssa_builder.h b/compiler/optimizing/ssa_builder.h
index 1c83c4b..64600db 100644
--- a/compiler/optimizing/ssa_builder.h
+++ b/compiler/optimizing/ssa_builder.h
@@ -61,9 +61,22 @@
   GrowableArray<HInstruction*>* GetLocalsFor(HBasicBlock* block) {
     GrowableArray<HInstruction*>* locals = locals_for_.Get(block->GetBlockId());
     if (locals == nullptr) {
-      locals = new (GetGraph()->GetArena()) GrowableArray<HInstruction*>(
-          GetGraph()->GetArena(), GetGraph()->GetNumberOfVRegs());
-      locals->SetSize(GetGraph()->GetNumberOfVRegs());
+      const size_t vregs = GetGraph()->GetNumberOfVRegs();
+      ArenaAllocator* arena = GetGraph()->GetArena();
+      locals = new (arena) GrowableArray<HInstruction*>(arena, vregs);
+      locals->SetSize(vregs);
+
+      if (block->IsCatchBlock()) {
+        // We record incoming inputs of catch phis at throwing instructions and
+        // must therefore eagerly create the phis. Unused phis will be removed
+        // in the dead phi analysis.
+        for (size_t i = 0; i < vregs; ++i) {
+          HPhi* phi = new (arena) HPhi(arena, i, 0, Primitive::kPrimVoid);
+          block->AddPhi(phi);
+          locals->Put(i, phi);
+        }
+      }
+
       locals_for_.Put(block->GetBlockId(), locals);
     }
     return locals;