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);