Treat SSA transformation special, as we may have to bailout.

We forgot to bailout when we found a non-natural loop (on which
our optimizations don't work).

Change-Id: I11976b5af4c98f4f29267a74c74d34b5ad81e20c
diff --git a/compiler/optimizing/find_loops_test.cc b/compiler/optimizing/find_loops_test.cc
index c36b143..82fe03c 100644
--- a/compiler/optimizing/find_loops_test.cc
+++ b/compiler/optimizing/find_loops_test.cc
@@ -32,7 +32,7 @@
   const DexFile::CodeItem* item = reinterpret_cast<const DexFile::CodeItem*>(data);
   HGraph* graph = builder.BuildGraph(*item);
   graph->BuildDominatorTree();
-  graph->FindNaturalLoops();
+  graph->AnalyzeNaturalLoops();
   return graph;
 }
 
diff --git a/compiler/optimizing/gvn_test.cc b/compiler/optimizing/gvn_test.cc
index ad6e338..a6a68ca 100644
--- a/compiler/optimizing/gvn_test.cc
+++ b/compiler/optimizing/gvn_test.cc
@@ -175,7 +175,7 @@
 
   graph->BuildDominatorTree();
   graph->TransformToSSA();
-  graph->FindNaturalLoops();
+  graph->AnalyzeNaturalLoops();
   GlobalValueNumberer(&allocator, graph).Run();
 
   // Check that all field get instructions are still there.
@@ -239,7 +239,7 @@
 
   graph->BuildDominatorTree();
   graph->TransformToSSA();
-  graph->FindNaturalLoops();
+  graph->AnalyzeNaturalLoops();
 
   ASSERT_TRUE(inner_loop_header->GetLoopInformation()->IsIn(
       *outer_loop_header->GetLoopInformation()));
diff --git a/compiler/optimizing/linearize_test.cc b/compiler/optimizing/linearize_test.cc
index c49cf7e..28ca5e8 100644
--- a/compiler/optimizing/linearize_test.cc
+++ b/compiler/optimizing/linearize_test.cc
@@ -44,7 +44,7 @@
 
   graph->BuildDominatorTree();
   graph->TransformToSSA();
-  graph->FindNaturalLoops();
+  graph->AnalyzeNaturalLoops();
 
   x86::CodeGeneratorX86 codegen(graph);
   SsaLivenessAnalysis liveness(*graph, &codegen);
diff --git a/compiler/optimizing/live_ranges_test.cc b/compiler/optimizing/live_ranges_test.cc
index e3c6fec..5c7e6f0 100644
--- a/compiler/optimizing/live_ranges_test.cc
+++ b/compiler/optimizing/live_ranges_test.cc
@@ -38,7 +38,7 @@
   RemoveSuspendChecks(graph);
   graph->BuildDominatorTree();
   graph->TransformToSSA();
-  graph->FindNaturalLoops();
+  graph->AnalyzeNaturalLoops();
   // `Inline` conditions into ifs.
   PrepareForRegisterAllocation(graph).Run();
   return graph;
diff --git a/compiler/optimizing/liveness_test.cc b/compiler/optimizing/liveness_test.cc
index 246e7ef..4b69e57 100644
--- a/compiler/optimizing/liveness_test.cc
+++ b/compiler/optimizing/liveness_test.cc
@@ -50,7 +50,7 @@
   ASSERT_NE(graph, nullptr);
   graph->BuildDominatorTree();
   graph->TransformToSSA();
-  graph->FindNaturalLoops();
+  graph->AnalyzeNaturalLoops();
   // `Inline` conditions into ifs.
   PrepareForRegisterAllocation(graph).Run();
   x86::CodeGeneratorX86 codegen(graph);
diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc
index 8cb2ef6..7584f1b 100644
--- a/compiler/optimizing/nodes.cc
+++ b/compiler/optimizing/nodes.cc
@@ -237,7 +237,7 @@
   }
 }
 
-bool HGraph::FindNaturalLoops() const {
+bool HGraph::AnalyzeNaturalLoops() const {
   for (size_t i = 0; i < blocks_.Size(); ++i) {
     HBasicBlock* block = blocks_.Get(i);
     if (block->IsLoopHeader()) {
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index 28496e4..9d0b4a9 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -112,10 +112,10 @@
   void TransformToSSA();
   void SimplifyCFG();
 
-  // Find all natural loops in this graph. Aborts computation and returns false
-  // if one loop is not natural, that is the header does not dominate the back
-  // edge.
-  bool FindNaturalLoops() const;
+  // Analyze all natural loops in this graph. Returns false if one
+  // loop is not natural, that is the header does not dominate the
+  // back edge.
+  bool AnalyzeNaturalLoops() const;
 
   void SplitCriticalEdge(HBasicBlock* block, HBasicBlock* successor);
   void SimplifyLoop(HBasicBlock* header);
diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc
index 34485a3..6c9f3fc 100644
--- a/compiler/optimizing/optimizing_compiler.cc
+++ b/compiler/optimizing/optimizing_compiler.cc
@@ -192,7 +192,6 @@
 }
 
 static void RunOptimizations(HGraph* graph, const HGraphVisualizer& visualizer) {
-  TransformToSsa ssa(graph);
   HDeadCodeElimination opt1(graph);
   HConstantFolding opt2(graph);
   SsaRedundantPhiElimination opt3(graph);
@@ -202,7 +201,6 @@
   InstructionSimplifier opt7(graph);
 
   HOptimization* optimizations[] = {
-    &ssa,
     &opt1,
     &opt2,
     &opt3,
@@ -220,6 +218,23 @@
   }
 }
 
+static bool TryBuildingSsa(HGraph* graph,
+                           const DexCompilationUnit& dex_compilation_unit,
+                           const HGraphVisualizer& visualizer) {
+  graph->BuildDominatorTree();
+  graph->TransformToSSA();
+
+  if (!graph->AnalyzeNaturalLoops()) {
+    LOG(INFO) << "Skipping compilation of "
+              << PrettyMethod(dex_compilation_unit.GetDexMethodIndex(),
+                              *dex_compilation_unit.GetDexFile())
+              << ": it contains a non natural loop";
+    return false;
+  }
+  visualizer.DumpGraph("ssa transform");
+  return true;
+}
+
 CompiledMethod* OptimizingCompiler::Compile(const DexFile::CodeItem* code_item,
                                             uint32_t access_flags,
                                             InvokeType invoke_type,
@@ -282,6 +297,10 @@
       && CanOptimize(*code_item)
       && RegisterAllocator::CanAllocateRegistersFor(*graph, instruction_set)) {
     optimized_compiled_methods_++;
+    if (!TryBuildingSsa(graph, dex_compilation_unit, visualizer)) {
+      // We could not transform the graph to SSA, bailout.
+      return nullptr;
+    }
     RunOptimizations(graph, visualizer);
 
     PrepareForRegisterAllocation(graph).Run();
diff --git a/compiler/optimizing/register_allocator_test.cc b/compiler/optimizing/register_allocator_test.cc
index ba4be34..8d75db9 100644
--- a/compiler/optimizing/register_allocator_test.cc
+++ b/compiler/optimizing/register_allocator_test.cc
@@ -41,7 +41,7 @@
   HGraph* graph = builder.BuildGraph(*item);
   graph->BuildDominatorTree();
   graph->TransformToSSA();
-  graph->FindNaturalLoops();
+  graph->AnalyzeNaturalLoops();
   x86::CodeGeneratorX86 codegen(graph);
   SsaLivenessAnalysis liveness(*graph, &codegen);
   liveness.Analyze();
@@ -255,7 +255,7 @@
   HGraph* graph = builder.BuildGraph(*item);
   graph->BuildDominatorTree();
   graph->TransformToSSA();
-  graph->FindNaturalLoops();
+  graph->AnalyzeNaturalLoops();
   return graph;
 }
 
@@ -494,7 +494,7 @@
   (*phi)->AddInput(*input2);
 
   graph->BuildDominatorTree();
-  graph->FindNaturalLoops();
+  graph->AnalyzeNaturalLoops();
   return graph;
 }
 
diff --git a/compiler/optimizing/ssa_builder.h b/compiler/optimizing/ssa_builder.h
index 5ab328f..2cbd51a 100644
--- a/compiler/optimizing/ssa_builder.h
+++ b/compiler/optimizing/ssa_builder.h
@@ -22,20 +22,6 @@
 
 namespace art {
 
-class TransformToSsa : public HOptimization {
- public:
-  explicit TransformToSsa(HGraph* graph) : HOptimization(graph, true, "ssa transform") {}
-
-  void Run() OVERRIDE {
-    graph_->BuildDominatorTree();
-    graph_->TransformToSSA();
-    graph_->FindNaturalLoops();
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(TransformToSsa);
-};
-
 static constexpr int kDefaultNumberOfLoops = 2;
 
 class SsaBuilder : public HGraphVisitor {