Optimizing: Tag arena allocations in SsaBuilder.
Replace GrowableArray with ArenaVector in SsaBuilder and
tag allocations with a new arena allocation type.
Change-Id: I27312c51d7be9d2ad02a974cce93b365c65c5fc4
diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc
index 570ce2e..54f4071 100644
--- a/compiler/optimizing/nodes.cc
+++ b/compiler/optimizing/nodes.cc
@@ -668,9 +668,9 @@
}
}
-void HEnvironment::CopyFrom(const GrowableArray<HInstruction*>& locals) {
- for (size_t i = 0; i < locals.Size(); i++) {
- HInstruction* instruction = locals.Get(i);
+void HEnvironment::CopyFrom(const ArenaVector<HInstruction*>& locals) {
+ for (size_t i = 0; i < locals.size(); i++) {
+ HInstruction* instruction = locals[i];
SetRawEnvAt(i, instruction);
if (instruction != nullptr) {
instruction->AddEnvUseAt(this, i);
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index 993cc37..70002ad 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -1544,7 +1544,7 @@
}
}
- void CopyFrom(const GrowableArray<HInstruction*>& locals);
+ void CopyFrom(const ArenaVector<HInstruction*>& locals);
void CopyFrom(HEnvironment* environment);
// Copy from `env`. If it's a loop phi for `loop_header`, copy the first
diff --git a/compiler/optimizing/nodes_test.cc b/compiler/optimizing/nodes_test.cc
index fef77aa..8eeac56 100644
--- a/compiler/optimizing/nodes_test.cc
+++ b/compiler/optimizing/nodes_test.cc
@@ -133,8 +133,8 @@
HEnvironment* environment = new (&allocator) HEnvironment(
&allocator, 1, graph->GetDexFile(), graph->GetMethodIdx(), 0, kStatic, with_environment);
- GrowableArray<HInstruction*> array(&allocator, 1);
- array.Add(parameter1);
+ ArenaVector<HInstruction*> array(allocator.Adapter());
+ array.push_back(parameter1);
environment->CopyFrom(array);
with_environment->SetRawEnvironment(environment);
diff --git a/compiler/optimizing/ssa_builder.cc b/compiler/optimizing/ssa_builder.cc
index e6209b9..9dcbea0 100644
--- a/compiler/optimizing/ssa_builder.cc
+++ b/compiler/optimizing/ssa_builder.cc
@@ -35,7 +35,9 @@
class DeadPhiHandling : public ValueObject {
public:
explicit DeadPhiHandling(HGraph* graph)
- : graph_(graph), worklist_(graph->GetArena(), kDefaultWorklistSize) {}
+ : graph_(graph), worklist_(graph->GetArena()->Adapter(kArenaAllocSsaBuilder)) {
+ worklist_.reserve(kDefaultWorklistSize);
+ }
void Run();
@@ -47,7 +49,7 @@
bool UpdateType(HPhi* phi);
HGraph* const graph_;
- GrowableArray<HPhi*> worklist_;
+ ArenaVector<HPhi*> worklist_;
static constexpr size_t kDefaultWorklistSize = 8;
@@ -136,8 +138,9 @@
}
void DeadPhiHandling::ProcessWorklist() {
- while (!worklist_.IsEmpty()) {
- HPhi* instruction = worklist_.Pop();
+ while (!worklist_.empty()) {
+ HPhi* instruction = worklist_.back();
+ worklist_.pop_back();
// Note that the same equivalent phi can be added multiple times in the work list, if
// used by multiple phis. The first call to `UpdateType` will know whether the phi is
// dead or live.
@@ -149,7 +152,7 @@
void DeadPhiHandling::AddToWorklist(HPhi* instruction) {
DCHECK(instruction->IsLive());
- worklist_.Add(instruction);
+ worklist_.push_back(instruction);
}
void DeadPhiHandling::AddDependentInstructionsToWorklist(HPhi* instruction) {
@@ -237,8 +240,7 @@
}
// 2) Set inputs of loop phis.
- for (size_t i = 0; i < loop_headers_.Size(); i++) {
- HBasicBlock* block = loop_headers_.Get(i);
+ for (HBasicBlock* block : loop_headers_) {
for (HInstructionIterator it(block->GetPhis()); !it.Done(); it.Advance()) {
HPhi* phi = it.Current()->AsPhi();
for (HBasicBlock* predecessor : block->GetPredecessors()) {
@@ -344,7 +346,9 @@
}
HInstruction* SsaBuilder::ValueOfLocal(HBasicBlock* block, size_t local) {
- return GetLocalsFor(block)->Get(local);
+ ArenaVector<HInstruction*>* locals = GetLocalsFor(block);
+ DCHECK_LT(local, locals->size());
+ return (*locals)[local];
}
void SsaBuilder::VisitBasicBlock(HBasicBlock* block) {
@@ -357,22 +361,22 @@
// because we are visiting in reverse post order. We create phis for all initialized
// locals from the pre header. Their inputs will be populated at the end of
// the analysis.
- for (size_t local = 0; local < current_locals_->Size(); local++) {
+ for (size_t local = 0; local < current_locals_->size(); ++local) {
HInstruction* incoming = ValueOfLocal(block->GetLoopInformation()->GetPreHeader(), local);
if (incoming != nullptr) {
HPhi* phi = new (GetGraph()->GetArena()) HPhi(
GetGraph()->GetArena(), local, 0, Primitive::kPrimVoid);
block->AddPhi(phi);
- current_locals_->Put(local, phi);
+ (*current_locals_)[local] = phi;
}
}
// Save the loop header so that the last phase of the analysis knows which
// blocks need to be updated.
- loop_headers_.Add(block);
+ loop_headers_.push_back(block);
} else if (block->GetPredecessors().size() > 0) {
// All predecessors have already been visited because we are visiting in reverse post order.
// We merge the values of all locals, creating phis if those values differ.
- for (size_t local = 0; local < current_locals_->Size(); local++) {
+ for (size_t local = 0; local < current_locals_->size(); ++local) {
bool one_predecessor_has_no_value = false;
bool is_different = false;
HInstruction* value = ValueOfLocal(block->GetPredecessor(0), local);
@@ -403,7 +407,7 @@
block->AddPhi(phi);
value = phi;
}
- current_locals_->Put(local, value);
+ (*current_locals_)[local] = value;
}
}
@@ -534,7 +538,8 @@
}
void SsaBuilder::VisitLoadLocal(HLoadLocal* load) {
- HInstruction* value = current_locals_->Get(load->GetLocal()->GetRegNumber());
+ DCHECK_LT(load->GetLocal()->GetRegNumber(), current_locals_->size());
+ HInstruction* value = (*current_locals_)[load->GetLocal()->GetRegNumber()];
// If the operation requests a specific type, we make sure its input is of that type.
if (load->GetType() != value->GetType()) {
if (load->GetType() == Primitive::kPrimFloat || load->GetType() == Primitive::kPrimDouble) {
@@ -548,7 +553,8 @@
}
void SsaBuilder::VisitStoreLocal(HStoreLocal* store) {
- current_locals_->Put(store->GetLocal()->GetRegNumber(), store->InputAt(1));
+ DCHECK_LT(store->GetLocal()->GetRegNumber(), current_locals_->size());
+ (*current_locals_)[store->GetLocal()->GetRegNumber()] = store->InputAt(1);
store->GetBlock()->RemoveInstruction(store);
}
@@ -556,7 +562,7 @@
if (instruction->NeedsEnvironment()) {
HEnvironment* environment = new (GetGraph()->GetArena()) HEnvironment(
GetGraph()->GetArena(),
- current_locals_->Size(),
+ current_locals_->size(),
GetGraph()->GetDexFile(),
GetGraph()->GetMethodIdx(),
instruction->GetDexPc(),
@@ -571,11 +577,12 @@
const HTryBoundary& try_entry =
instruction->GetBlock()->GetTryCatchInformation()->GetTryEntry();
for (HExceptionHandlerIterator it(try_entry); !it.Done(); it.Advance()) {
- GrowableArray<HInstruction*>* handler_locals = GetLocalsFor(it.Current());
- for (size_t i = 0, e = current_locals_->Size(); i < e; ++i) {
- HInstruction* local_value = current_locals_->Get(i);
+ ArenaVector<HInstruction*>* handler_locals = GetLocalsFor(it.Current());
+ DCHECK_EQ(handler_locals->size(), current_locals_->size());
+ for (size_t i = 0, e = current_locals_->size(); i < e; ++i) {
+ HInstruction* local_value = (*current_locals_)[i];
if (local_value != nullptr) {
- handler_locals->Get(i)->AsPhi()->AddInput(local_value);
+ (*handler_locals)[i]->AsPhi()->AddInput(local_value);
}
}
}
diff --git a/compiler/optimizing/ssa_builder.h b/compiler/optimizing/ssa_builder.h
index dc76177..804296f 100644
--- a/compiler/optimizing/ssa_builder.h
+++ b/compiler/optimizing/ssa_builder.h
@@ -17,6 +17,7 @@
#ifndef ART_COMPILER_OPTIMIZING_SSA_BUILDER_H_
#define ART_COMPILER_OPTIMIZING_SSA_BUILDER_H_
+#include "base/arena_containers.h"
#include "nodes.h"
#include "optimization.h"
@@ -51,33 +52,33 @@
explicit SsaBuilder(HGraph* graph)
: HGraphVisitor(graph),
current_locals_(nullptr),
- loop_headers_(graph->GetArena(), kDefaultNumberOfLoops),
- locals_for_(graph->GetArena(), graph->GetBlocks().size()) {
- locals_for_.SetSize(graph->GetBlocks().size());
+ loop_headers_(graph->GetArena()->Adapter(kArenaAllocSsaBuilder)),
+ locals_for_(graph->GetBlocks().size(),
+ ArenaVector<HInstruction*>(graph->GetArena()->Adapter(kArenaAllocSsaBuilder)),
+ graph->GetArena()->Adapter(kArenaAllocSsaBuilder)) {
+ loop_headers_.reserve(kDefaultNumberOfLoops);
}
void BuildSsa();
- GrowableArray<HInstruction*>* GetLocalsFor(HBasicBlock* block) {
- GrowableArray<HInstruction*>* locals = locals_for_.Get(block->GetBlockId());
- if (locals == nullptr) {
+ ArenaVector<HInstruction*>* GetLocalsFor(HBasicBlock* block) {
+ DCHECK_LT(block->GetBlockId(), locals_for_.size());
+ ArenaVector<HInstruction*>* locals = &locals_for_[block->GetBlockId()];
+ if (locals->empty() && GetGraph()->GetNumberOfVRegs() != 0u) {
const size_t vregs = GetGraph()->GetNumberOfVRegs();
- ArenaAllocator* arena = GetGraph()->GetArena();
- locals = new (arena) GrowableArray<HInstruction*>(arena, vregs);
- locals->SetSize(vregs);
+ locals->resize(vregs, nullptr);
if (block->IsCatchBlock()) {
// We record incoming inputs of catch phis at throwing instructions and
// must therefore eagerly create the phis. Unused phis will be removed
// in the dead phi analysis.
+ ArenaAllocator* arena = GetGraph()->GetArena();
for (size_t i = 0; i < vregs; ++i) {
HPhi* phi = new (arena) HPhi(arena, i, 0, Primitive::kPrimVoid);
block->AddPhi(phi);
- locals->Put(i, phi);
+ (*locals)[i] = phi;
}
}
-
- locals_for_.Put(block->GetBlockId(), locals);
}
return locals;
}
@@ -107,14 +108,14 @@
static HPhi* GetFloatDoubleOrReferenceEquivalentOfPhi(HPhi* phi, Primitive::Type type);
// Locals for the current block being visited.
- GrowableArray<HInstruction*>* current_locals_;
+ ArenaVector<HInstruction*>* current_locals_;
// Keep track of loop headers found. The last phase of the analysis iterates
// over these blocks to set the inputs of their phis.
- GrowableArray<HBasicBlock*> loop_headers_;
+ ArenaVector<HBasicBlock*> loop_headers_;
// HEnvironment for each block.
- GrowableArray<GrowableArray<HInstruction*>*> locals_for_;
+ ArenaVector<ArenaVector<HInstruction*>> locals_for_;
DISALLOW_COPY_AND_ASSIGN(SsaBuilder);
};
diff --git a/runtime/base/arena_allocator.cc b/runtime/base/arena_allocator.cc
index 337df38..4e51f55 100644
--- a/runtime/base/arena_allocator.cc
+++ b/runtime/base/arena_allocator.cc
@@ -74,6 +74,7 @@
"Environment ",
"EnvVRegs ",
"EnvLocations ",
+ "SsaBuilder ",
"MoveOperands ",
"CodeBuffer ",
"StackMaps ",
diff --git a/runtime/base/arena_allocator.h b/runtime/base/arena_allocator.h
index 8104978..c5eb741 100644
--- a/runtime/base/arena_allocator.h
+++ b/runtime/base/arena_allocator.h
@@ -84,6 +84,7 @@
kArenaAllocEnvironment,
kArenaAllocEnvironmentVRegs,
kArenaAllocEnvironmentLocations,
+ kArenaAllocSsaBuilder,
kArenaAllocMoveOperands,
kArenaAllocCodeBuffer,
kArenaAllocStackMaps,