Run LSA as a part of the LSE pass.

Make LSA a helper class, not an optimization pass. Move all
its allocations to ScopedArenaAllocator to reduce the peak
memory usage a little bit.

Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Change-Id: I7fc634abe732d22c99005921ffecac5207bcf05f
diff --git a/compiler/optimizing/load_store_analysis.h b/compiler/optimizing/load_store_analysis.h
index 08d9309..15e7045 100644
--- a/compiler/optimizing/load_store_analysis.h
+++ b/compiler/optimizing/load_store_analysis.h
@@ -17,6 +17,8 @@
 #ifndef ART_COMPILER_OPTIMIZING_LOAD_STORE_ANALYSIS_H_
 #define ART_COMPILER_OPTIMIZING_LOAD_STORE_ANALYSIS_H_
 
+#include "base/bit_vector-inl.h"
+#include "base/scoped_arena_containers.h"
 #include "escape.h"
 #include "nodes.h"
 #include "optimization.h"
@@ -192,17 +194,20 @@
   // aliasing matrix of 8 heap locations.
   static constexpr uint32_t kInitialAliasingMatrixBitVectorSize = 32;
 
-  explicit HeapLocationCollector(HGraph* graph)
+  explicit HeapLocationCollector(HGraph* graph, ScopedArenaAllocator* allocator)
       : HGraphVisitor(graph),
-        ref_info_array_(graph->GetAllocator()->Adapter(kArenaAllocLSA)),
-        heap_locations_(graph->GetAllocator()->Adapter(kArenaAllocLSA)),
-        aliasing_matrix_(graph->GetAllocator(),
+        allocator_(allocator),
+        ref_info_array_(allocator->Adapter(kArenaAllocLSA)),
+        heap_locations_(allocator->Adapter(kArenaAllocLSA)),
+        aliasing_matrix_(allocator,
                          kInitialAliasingMatrixBitVectorSize,
                          true,
                          kArenaAllocLSA),
         has_heap_stores_(false),
         has_volatile_(false),
-        has_monitor_operations_(false) {}
+        has_monitor_operations_(false) {
+    aliasing_matrix_.ClearAllBits();
+  }
 
   void CleanUp() {
     heap_locations_.clear();
@@ -432,7 +437,7 @@
     ReferenceInfo* ref_info = FindReferenceInfoOf(instruction);
     if (ref_info == nullptr) {
       size_t pos = ref_info_array_.size();
-      ref_info = new (GetGraph()->GetAllocator()) ReferenceInfo(instruction, pos);
+      ref_info = new (allocator_) ReferenceInfo(instruction, pos);
       ref_info_array_.push_back(ref_info);
     }
     return ref_info;
@@ -457,7 +462,7 @@
     size_t heap_location_idx = FindHeapLocationIndex(
         ref_info, type, offset, index, vector_length, declaring_class_def_index);
     if (heap_location_idx == kHeapLocationNotFound) {
-      HeapLocation* heap_loc = new (GetGraph()->GetAllocator())
+      HeapLocation* heap_loc = new (allocator_)
           HeapLocation(ref_info, type, offset, index, vector_length, declaring_class_def_index);
       heap_locations_.push_back(heap_loc);
       return heap_loc;
@@ -584,8 +589,9 @@
     has_monitor_operations_ = true;
   }
 
-  ArenaVector<ReferenceInfo*> ref_info_array_;   // All references used for heap accesses.
-  ArenaVector<HeapLocation*> heap_locations_;    // All heap locations.
+  ScopedArenaAllocator* allocator_;
+  ScopedArenaVector<ReferenceInfo*> ref_info_array_;   // All references used for heap accesses.
+  ScopedArenaVector<HeapLocation*> heap_locations_;    // All heap locations.
   ArenaBitVector aliasing_matrix_;    // aliasing info between each pair of locations.
   bool has_heap_stores_;    // If there is no heap stores, LSE acts as GVN with better
                             // alias analysis and won't be as effective.
@@ -595,21 +601,20 @@
   DISALLOW_COPY_AND_ASSIGN(HeapLocationCollector);
 };
 
-class LoadStoreAnalysis : public HOptimization {
+class LoadStoreAnalysis {
  public:
-  explicit LoadStoreAnalysis(HGraph* graph, const char* name = kLoadStoreAnalysisPassName)
-    : HOptimization(graph, name),
-      heap_location_collector_(graph) {}
+  explicit LoadStoreAnalysis(HGraph* graph, ScopedArenaAllocator* local_allocator)
+    : graph_(graph),
+      heap_location_collector_(graph, local_allocator) {}
 
   const HeapLocationCollector& GetHeapLocationCollector() const {
     return heap_location_collector_;
   }
 
-  bool Run() override;
-
-  static constexpr const char* kLoadStoreAnalysisPassName = "load_store_analysis";
+  bool Run();
 
  private:
+  HGraph* graph_;
   HeapLocationCollector heap_location_collector_;
 
   DISALLOW_COPY_AND_ASSIGN(LoadStoreAnalysis);
diff --git a/compiler/optimizing/load_store_analysis_test.cc b/compiler/optimizing/load_store_analysis_test.cc
index d725aba..c518f03 100644
--- a/compiler/optimizing/load_store_analysis_test.cc
+++ b/compiler/optimizing/load_store_analysis_test.cc
@@ -66,7 +66,8 @@
 
   // Test HeapLocationCollector initialization.
   // Should be no heap locations, no operations on the heap.
-  HeapLocationCollector heap_location_collector(graph_);
+  ScopedArenaAllocator allocator(graph_->GetArenaStack());
+  HeapLocationCollector heap_location_collector(graph_, &allocator);
   ASSERT_EQ(heap_location_collector.GetNumberOfHeapLocations(), 0U);
   ASSERT_FALSE(heap_location_collector.HasHeapStores());
 
@@ -162,7 +163,8 @@
 
   // Test HeapLocationCollector initialization.
   // Should be no heap locations, no operations on the heap.
-  HeapLocationCollector heap_location_collector(graph_);
+  ScopedArenaAllocator allocator(graph_->GetArenaStack());
+  HeapLocationCollector heap_location_collector(graph_, &allocator);
   ASSERT_EQ(heap_location_collector.GetNumberOfHeapLocations(), 0U);
   ASSERT_FALSE(heap_location_collector.HasHeapStores());
 
@@ -241,7 +243,8 @@
   entry->AddInstruction(arr_set7);  // array[1-i] = c0
   entry->AddInstruction(arr_set8);  // array[i-(-1)] = c0
 
-  LoadStoreAnalysis lsa(graph_);
+  ScopedArenaAllocator allocator(graph_->GetArenaStack());
+  LoadStoreAnalysis lsa(graph_, &allocator);
   lsa.Run();
   const HeapLocationCollector& heap_location_collector = lsa.GetHeapLocationCollector();
 
@@ -407,7 +410,8 @@
   entry->AddInstruction(vstore_i_add8);
   entry->AddInstruction(vstore_i_add6_vlen2);
 
-  LoadStoreAnalysis lsa(graph_);
+  ScopedArenaAllocator allocator(graph_->GetArenaStack());
+  LoadStoreAnalysis lsa(graph_, &allocator);
   lsa.Run();
   const HeapLocationCollector& heap_location_collector = lsa.GetHeapLocationCollector();
 
@@ -565,7 +569,8 @@
   entry->AddInstruction(arr_set_7);
   entry->AddInstruction(arr_set_8);
 
-  LoadStoreAnalysis lsa(graph_);
+  ScopedArenaAllocator allocator(graph_->GetArenaStack());
+  LoadStoreAnalysis lsa(graph_, &allocator);
   lsa.Run();
   const HeapLocationCollector& heap_location_collector = lsa.GetHeapLocationCollector();
 
@@ -654,7 +659,8 @@
   entry->AddInstruction(inter_addr);
   entry->AddInstruction(array_get4);
 
-  HeapLocationCollector heap_location_collector(graph_);
+  ScopedArenaAllocator allocator(graph_->GetArenaStack());
+  HeapLocationCollector heap_location_collector(graph_, &allocator);
   heap_location_collector.VisitBasicBlock(entry);
 
   // Test that the HeapLocationCollector should be able to tell
diff --git a/compiler/optimizing/load_store_elimination.cc b/compiler/optimizing/load_store_elimination.cc
index 24041e9..86e84bd 100644
--- a/compiler/optimizing/load_store_elimination.cc
+++ b/compiler/optimizing/load_store_elimination.cc
@@ -930,7 +930,10 @@
     // Skip this optimization.
     return false;
   }
-  const HeapLocationCollector& heap_location_collector = lsa_.GetHeapLocationCollector();
+  ScopedArenaAllocator allocator(graph_->GetArenaStack());
+  LoadStoreAnalysis lsa(graph_, &allocator);
+  lsa.Run();
+  const HeapLocationCollector& heap_location_collector = lsa.GetHeapLocationCollector();
   if (heap_location_collector.GetNumberOfHeapLocations() == 0) {
     // No HeapLocation information from LSA, skip this optimization.
     return false;
diff --git a/compiler/optimizing/load_store_elimination.h b/compiler/optimizing/load_store_elimination.h
index f7ba41a..7765cc2 100644
--- a/compiler/optimizing/load_store_elimination.h
+++ b/compiler/optimizing/load_store_elimination.h
@@ -22,18 +22,15 @@
 namespace art {
 
 class SideEffectsAnalysis;
-class LoadStoreAnalysis;
 
 class LoadStoreElimination : public HOptimization {
  public:
   LoadStoreElimination(HGraph* graph,
                        const SideEffectsAnalysis& side_effects,
-                       const LoadStoreAnalysis& lsa,
                        OptimizingCompilerStats* stats,
                        const char* name = kLoadStoreEliminationPassName)
       : HOptimization(graph, name, stats),
-        side_effects_(side_effects),
-        lsa_(lsa) {}
+        side_effects_(side_effects) {}
 
   bool Run() override;
 
@@ -41,7 +38,6 @@
 
  private:
   const SideEffectsAnalysis& side_effects_;
-  const LoadStoreAnalysis& lsa_;
 
   DISALLOW_COPY_AND_ASSIGN(LoadStoreElimination);
 };
diff --git a/compiler/optimizing/load_store_elimination_test.cc b/compiler/optimizing/load_store_elimination_test.cc
index 02cb633..462e6a9 100644
--- a/compiler/optimizing/load_store_elimination_test.cc
+++ b/compiler/optimizing/load_store_elimination_test.cc
@@ -32,9 +32,7 @@
     graph_->BuildDominatorTree();
     SideEffectsAnalysis side_effects(graph_);
     side_effects.Run();
-    LoadStoreAnalysis lsa(graph_);
-    lsa.Run();
-    LoadStoreElimination lse(graph_, side_effects, lsa, nullptr);
+    LoadStoreElimination lse(graph_, side_effects, /*stats=*/ nullptr);
     lse.Run();
     EXPECT_TRUE(CheckGraphSkipRefTypeInfoChecks());
   }
diff --git a/compiler/optimizing/optimization.cc b/compiler/optimizing/optimization.cc
index 7483190..ec3b8c4 100644
--- a/compiler/optimizing/optimization.cc
+++ b/compiler/optimizing/optimization.cc
@@ -48,7 +48,6 @@
 #include "instruction_simplifier.h"
 #include "intrinsics.h"
 #include "licm.h"
-#include "load_store_analysis.h"
 #include "load_store_elimination.h"
 #include "loop_optimization.h"
 #include "scheduler.h"
@@ -66,8 +65,6 @@
       return SideEffectsAnalysis::kSideEffectsAnalysisPassName;
     case OptimizationPass::kInductionVarAnalysis:
       return HInductionVarAnalysis::kInductionPassName;
-    case OptimizationPass::kLoadStoreAnalysis:
-      return LoadStoreAnalysis::kLoadStoreAnalysisPassName;
     case OptimizationPass::kGlobalValueNumbering:
       return GVNOptimization::kGlobalValueNumberingPassName;
     case OptimizationPass::kInvariantCodeMotion:
@@ -138,7 +135,6 @@
   X(OptimizationPass::kInliner);
   X(OptimizationPass::kInstructionSimplifier);
   X(OptimizationPass::kInvariantCodeMotion);
-  X(OptimizationPass::kLoadStoreAnalysis);
   X(OptimizationPass::kLoadStoreElimination);
   X(OptimizationPass::kLoopOptimization);
   X(OptimizationPass::kScheduling);
@@ -175,7 +171,6 @@
   // name list or fails fatally if no such analysis can be found.
   SideEffectsAnalysis* most_recent_side_effects = nullptr;
   HInductionVarAnalysis* most_recent_induction = nullptr;
-  LoadStoreAnalysis* most_recent_lsa = nullptr;
 
   // Loop over the requested optimizations.
   for (size_t i = 0; i < length; i++) {
@@ -196,9 +191,6 @@
       case OptimizationPass::kInductionVarAnalysis:
         opt = most_recent_induction = new (allocator) HInductionVarAnalysis(graph, pass_name);
         break;
-      case OptimizationPass::kLoadStoreAnalysis:
-        opt = most_recent_lsa = new (allocator) LoadStoreAnalysis(graph, pass_name);
-        break;
       //
       // Passes that need prior analysis.
       //
@@ -223,7 +215,7 @@
       case OptimizationPass::kLoadStoreElimination:
         CHECK(most_recent_side_effects != nullptr && most_recent_induction != nullptr);
         opt = new (allocator) LoadStoreElimination(
-            graph, *most_recent_side_effects, *most_recent_lsa, stats, pass_name);
+            graph, *most_recent_side_effects, stats, pass_name);
         break;
       //
       // Regular passes.
diff --git a/compiler/optimizing/optimization.h b/compiler/optimizing/optimization.h
index 5ed3762..4a515bc 100644
--- a/compiler/optimizing/optimization.h
+++ b/compiler/optimizing/optimization.h
@@ -77,7 +77,6 @@
   kInliner,
   kInstructionSimplifier,
   kInvariantCodeMotion,
-  kLoadStoreAnalysis,
   kLoadStoreElimination,
   kLoopOptimization,
   kScheduling,
diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc
index 2d5216a..02751cb 100644
--- a/compiler/optimizing/optimizing_compiler.cc
+++ b/compiler/optimizing/optimizing_compiler.cc
@@ -646,7 +646,6 @@
     // Other high-level optimizations.
     OptDef(OptimizationPass::kSideEffectsAnalysis,
            "side_effects$before_lse"),
-    OptDef(OptimizationPass::kLoadStoreAnalysis),
     OptDef(OptimizationPass::kLoadStoreElimination),
     OptDef(OptimizationPass::kCHAGuardOptimization),
     OptDef(OptimizationPass::kDeadCodeElimination,
diff --git a/compiler/optimizing/scheduler.cc b/compiler/optimizing/scheduler.cc
index f722cf9..ea5a13a 100644
--- a/compiler/optimizing/scheduler.cc
+++ b/compiler/optimizing/scheduler.cc
@@ -559,7 +559,8 @@
   // We run lsa here instead of in a separate pass to better control whether we
   // should run the analysis or not.
   const HeapLocationCollector* heap_location_collector = nullptr;
-  LoadStoreAnalysis lsa(graph);
+  ScopedArenaAllocator allocator(graph->GetArenaStack());
+  LoadStoreAnalysis lsa(graph, &allocator);
   if (!only_optimize_loop_blocks_ || graph->HasLoops()) {
     lsa.Run();
     heap_location_collector = &lsa.GetHeapLocationCollector();
diff --git a/compiler/optimizing/scheduler_test.cc b/compiler/optimizing/scheduler_test.cc
index b5ec93e..94f1599 100644
--- a/compiler/optimizing/scheduler_test.cc
+++ b/compiler/optimizing/scheduler_test.cc
@@ -273,7 +273,7 @@
       entry->AddInstruction(instr);
     }
 
-    HeapLocationCollector heap_location_collector(graph_);
+    HeapLocationCollector heap_location_collector(graph_, GetScopedAllocator());
     heap_location_collector.VisitBasicBlock(entry);
     heap_location_collector.BuildAliasingMatrix();
     TestSchedulingGraph scheduling_graph(GetScopedAllocator(), &heap_location_collector);