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/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc
index 4568a46..aeb1ae2 100644
--- a/compiler/optimizing/optimizing_compiler.cc
+++ b/compiler/optimizing/optimizing_compiler.cc
@@ -132,7 +132,7 @@
   void StartPass(const char* pass_name) {
     // Dump graph first, then start timer.
     if (visualizer_enabled_) {
-      visualizer_.DumpGraph(pass_name, /* is_after_pass */ false);
+      visualizer_.DumpGraph(pass_name, /* is_after_pass */ false, graph_in_bad_state_);
     }
     if (timing_logger_enabled_) {
       timing_logger_.StartTiming(pass_name);
@@ -145,7 +145,7 @@
       timing_logger_.EndTiming();
     }
     if (visualizer_enabled_) {
-      visualizer_.DumpGraph(pass_name, /* is_after_pass */ true);
+      visualizer_.DumpGraph(pass_name, /* is_after_pass */ true, graph_in_bad_state_);
     }
 
     // Validate the HGraph if running in debug mode.
@@ -628,7 +628,7 @@
   // or the debuggable flag). If it is set, we can run baseline. Otherwise, we fall back
   // to Quick.
   bool can_use_baseline = !run_optimizations_ && builder.CanUseBaselineForStringInit();
-  if (run_optimizations_ && can_optimize && can_allocate_registers) {
+  if (run_optimizations_ && can_allocate_registers) {
     VLOG(compiler) << "Optimizing " << method_name;
 
     {
@@ -637,16 +637,21 @@
         // We could not transform the graph to SSA, bailout.
         LOG(INFO) << "Skipping compilation of " << method_name << ": it contains a non natural loop";
         MaybeRecordStat(MethodCompilationStat::kNotCompiledCannotBuildSSA);
+        pass_observer.SetGraphInBadState();
         return nullptr;
       }
     }
 
-    return CompileOptimized(graph,
-                            codegen.get(),
-                            compiler_driver,
-                            dex_compilation_unit,
-                            &pass_observer);
-  } else if (shouldOptimize && can_allocate_registers) {
+    if (can_optimize) {
+      return CompileOptimized(graph,
+                              codegen.get(),
+                              compiler_driver,
+                              dex_compilation_unit,
+                              &pass_observer);
+    }
+  }
+
+  if (shouldOptimize && can_allocate_registers) {
     LOG(FATAL) << "Could not allocate registers in optimizing compiler";
     UNREACHABLE();
   } else if (can_use_baseline) {