Merge "Properly scope HLoopOptimization's allocator."
diff --git a/compiler/optimizing/loop_optimization.cc b/compiler/optimizing/loop_optimization.cc
index 7dfa4f1..383a027 100644
--- a/compiler/optimizing/loop_optimization.cc
+++ b/compiler/optimizing/loop_optimization.cc
@@ -128,7 +128,7 @@
                                      HInductionVarAnalysis* induction_analysis)
     : HOptimization(graph, kLoopOptimizationPassName),
       induction_range_(induction_analysis),
-      loop_allocator_(graph_->GetArena()->GetArenaPool()),  // phase-local allocator on global pool
+      loop_allocator_(nullptr),
       top_loop_(nullptr),
       last_loop_(nullptr) {
 }
@@ -140,6 +140,9 @@
     return;
   }
 
+  ArenaAllocator allocator(graph_->GetArena()->GetArenaPool());
+  loop_allocator_ = &allocator;
+
   // Build the linear order. This step enables building a loop hierarchy that
   // properly reflects the outer-inner and previous-next relation.
   graph_->Linearize();
@@ -150,16 +153,16 @@
       AddLoop(block->GetLoopInformation());
     }
   }
-  if (top_loop_ == nullptr) {
-    return;  // no loops
+  if (top_loop_ != nullptr) {
+    // Traverse the loop hierarchy inner-to-outer and optimize.
+    TraverseLoopsInnerToOuter(top_loop_);
   }
-  // Traverse the loop hierarchy inner-to-outer and optimize.
-  TraverseLoopsInnerToOuter(top_loop_);
+  loop_allocator_ = nullptr;
 }
 
 void HLoopOptimization::AddLoop(HLoopInformation* loop_info) {
   DCHECK(loop_info != nullptr);
-  LoopNode* node = new (&loop_allocator_) LoopNode(loop_info);  // phase-local allocator
+  LoopNode* node = new (loop_allocator_) LoopNode(loop_info);  // phase-local allocator
   if (last_loop_ == nullptr) {
     // First loop.
     DCHECK(top_loop_ == nullptr);
diff --git a/compiler/optimizing/loop_optimization.h b/compiler/optimizing/loop_optimization.h
index e7980ce..d12fe5e 100644
--- a/compiler/optimizing/loop_optimization.h
+++ b/compiler/optimizing/loop_optimization.h
@@ -72,7 +72,7 @@
 
   // Phase-local heap memory allocator for the loop optimizer. Storage obtained
   // through this allocator is released when the loop optimizer is done.
-  ArenaAllocator loop_allocator_;
+  ArenaAllocator* loop_allocator_;
 
   // Entries into the loop hierarchy representation.
   LoopNode* top_loop_;
diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc
index c2fe1b1..52d6e0b 100644
--- a/compiler/optimizing/optimizing_compiler.cc
+++ b/compiler/optimizing/optimizing_compiler.cc
@@ -488,6 +488,8 @@
     return new (arena) LoadStoreElimination(graph, *most_recent_side_effects);
   } else if (opt_name == SideEffectsAnalysis::kSideEffectsAnalysisPassName) {
     return new (arena) SideEffectsAnalysis(graph);
+  } else if (opt_name == HLoopOptimization::kLoopOptimizationPassName) {
+    return new (arena) HLoopOptimization(graph, most_recent_induction);
 #ifdef ART_ENABLE_CODEGEN_arm
   } else if (opt_name == arm::DexCacheArrayFixups::kDexCacheArrayFixupsArmPassName) {
     return new (arena) arm::DexCacheArrayFixups(graph, codegen, stats);