Skip loop optimization if there is no loop in the graph.

LinearizeGraph() does quite some allocations.
Also add some comments on the possible false positives of
some flags.

Test: m test-art-host
Change-Id: I80ef89a2dc031d601e7621d0b22060cd8c17fae3
diff --git a/compiler/optimizing/loop_optimization.cc b/compiler/optimizing/loop_optimization.cc
index 9583838..26c9ab8 100644
--- a/compiler/optimizing/loop_optimization.cc
+++ b/compiler/optimizing/loop_optimization.cc
@@ -71,7 +71,7 @@
 void HLoopOptimization::Run() {
   // Well-behaved loops only.
   // TODO: make this less of a sledgehammer.
-  if (graph_->HasTryCatch() || graph_->HasIrreducibleLoops()) {
+  if (!graph_->HasLoops() || graph_->HasTryCatch() || graph_->HasIrreducibleLoops()) {
     return;
   }
 
@@ -84,6 +84,10 @@
   // Perform loop optimizations.
   LocalRun();
 
+  if (top_loop_ == nullptr) {
+    graph_->SetHasLoops(false);
+  }
+
   // Detach.
   loop_allocator_ = nullptr;
   last_loop_ = top_loop_ = nullptr;
diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc
index 71a26eb..62c8910 100644
--- a/compiler/optimizing/nodes.cc
+++ b/compiler/optimizing/nodes.cc
@@ -688,6 +688,7 @@
     contains_irreducible_loop_ = true;
     graph->SetHasIrreducibleLoops(true);
   }
+  graph->SetHasLoops(true);
 }
 
 HBasicBlock* HLoopInformation::GetPreHeader() const {
@@ -2032,9 +2033,19 @@
     }
   }
   outer_graph->UpdateMaximumNumberOfOutVRegs(GetMaximumNumberOfOutVRegs());
+
   if (HasBoundsChecks()) {
     outer_graph->SetHasBoundsChecks(true);
   }
+  if (HasLoops()) {
+    outer_graph->SetHasLoops(true);
+  }
+  if (HasIrreducibleLoops()) {
+    outer_graph->SetHasIrreducibleLoops(true);
+  }
+  if (HasTryCatch()) {
+    outer_graph->SetHasTryCatch(true);
+  }
 
   HInstruction* return_value = nullptr;
   if (GetBlocks().size() == 3) {
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index 96f9aba..2f258db 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -323,6 +323,7 @@
         temporaries_vreg_slots_(0),
         has_bounds_checks_(false),
         has_try_catch_(false),
+        has_loops_(false),
         has_irreducible_loops_(false),
         debuggable_(debuggable),
         current_instruction_id_(start_instruction_id),
@@ -559,6 +560,9 @@
   bool HasTryCatch() const { return has_try_catch_; }
   void SetHasTryCatch(bool value) { has_try_catch_ = value; }
 
+  bool HasLoops() const { return has_loops_; }
+  void SetHasLoops(bool value) { has_loops_ = value; }
+
   bool HasIrreducibleLoops() const { return has_irreducible_loops_; }
   void SetHasIrreducibleLoops(bool value) { has_irreducible_loops_ = value; }
 
@@ -637,14 +641,26 @@
   // Number of vreg size slots that the temporaries use (used in baseline compiler).
   size_t temporaries_vreg_slots_;
 
-  // Has bounds checks. We can totally skip BCE if it's false.
+  // Flag whether there are bounds checks in the graph. We can skip
+  // BCE if it's false. It's only best effort to keep it up to date in
+  // the presence of code elimination so there might be false positives.
   bool has_bounds_checks_;
 
-  // Flag whether there are any try/catch blocks in the graph. We will skip
-  // try/catch-related passes if false.
+  // Flag whether there are try/catch blocks in the graph. We will skip
+  // try/catch-related passes if it's false. It's only best effort to keep
+  // it up to date in the presence of code elimination so there might be
+  // false positives.
   bool has_try_catch_;
 
-  // Flag whether there are any irreducible loops in the graph.
+  // Flag whether there are any loops in the graph. We can skip loop
+  // optimization if it's false. It's only best effort to keep it up
+  // to date in the presence of code elimination so there might be false
+  // positives.
+  bool has_loops_;
+
+  // Flag whether there are any irreducible loops in the graph. It's only
+  // best effort to keep it up to date in the presence of code elimination
+  // so there might be false positives.
   bool has_irreducible_loops_;
 
   // Indicates whether the graph should be compiled in a way that