Refactoring of graph linearization and linear order.
Rationale:
Ownership of graph's linear order and iterators was
a bit unclear now that other phases are using it.
New approach allows phases to compute their own
order, while ssa_liveness is sole owner for graph
(since it is not mutated afterwards).
Also shortens lifetime of loop's arena.
Test: test-art-host
Change-Id: Ib7137d1203a1e0a12db49868f4117d48a4277f30
diff --git a/compiler/optimizing/loop_optimization.cc b/compiler/optimizing/loop_optimization.cc
index b12a7f7..4acf3ac 100644
--- a/compiler/optimizing/loop_optimization.cc
+++ b/compiler/optimizing/loop_optimization.cc
@@ -16,10 +16,7 @@
#include "loop_optimization.h"
-#include "base/arena_containers.h"
-#include "induction_var_range.h"
-#include "ssa_liveness_analysis.h"
-#include "nodes.h"
+#include "linear_order.h"
namespace art {
@@ -126,14 +123,9 @@
HLoopOptimization::HLoopOptimization(HGraph* graph,
HInductionVarAnalysis* induction_analysis)
- : HLoopOptimization(graph, induction_analysis, nullptr) {}
-
-HLoopOptimization::HLoopOptimization(HGraph* graph,
- HInductionVarAnalysis* induction_analysis,
- ArenaAllocator* allocator)
: HOptimization(graph, kLoopOptimizationPassName),
induction_range_(induction_analysis),
- loop_allocator_(allocator),
+ loop_allocator_(nullptr),
top_loop_(nullptr),
last_loop_(nullptr) {
}
@@ -141,32 +133,39 @@
void HLoopOptimization::Run() {
// Well-behaved loops only.
// TODO: make this less of a sledgehammer.
- if (graph_-> HasTryCatch() || graph_->HasIrreducibleLoops()) {
+ if (graph_->HasTryCatch() || graph_->HasIrreducibleLoops()) {
return;
}
+ // Phase-local allocator that draws from the global pool. Since the allocator
+ // itself resides on the stack, it is destructed on exiting Run(), which
+ // implies its underlying memory is released immediately.
ArenaAllocator allocator(graph_->GetArena()->GetArenaPool());
- if (loop_allocator_ == nullptr) {
- loop_allocator_ = &allocator;
- }
+ 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();
+ // Perform loop optimizations.
+ LocalRun();
+
+ // Detach.
+ loop_allocator_ = nullptr;
+ last_loop_ = top_loop_ = nullptr;
+}
+
+void HLoopOptimization::LocalRun() {
+ // Build the linear order using the phase-local allocator. This step enables building
+ // a loop hierarchy that properly reflects the outer-inner and previous-next relation.
+ ArenaVector<HBasicBlock*> linear_order(loop_allocator_->Adapter(kArenaAllocLinearOrder));
+ LinearizeGraph(graph_, loop_allocator_, &linear_order);
+
// Build the loop hierarchy.
- for (HLinearOrderIterator it_graph(*graph_); !it_graph.Done(); it_graph.Advance()) {
- HBasicBlock* block = it_graph.Current();
+ for (HBasicBlock* block : linear_order) {
if (block->IsLoopHeader()) {
AddLoop(block->GetLoopInformation());
}
}
- if (top_loop_ != nullptr) {
- // Traverse the loop hierarchy inner-to-outer and optimize.
- TraverseLoopsInnerToOuter(top_loop_);
- }
- if (loop_allocator_ == &allocator) {
- loop_allocator_ = nullptr;
- }
+
+ // Traverse the loop hierarchy inner-to-outer and optimize.
+ TraverseLoopsInnerToOuter(top_loop_);
}
void HLoopOptimization::AddLoop(HLoopInformation* loop_info) {