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();
bool UpdateType(HPhi* phi);
HGraph* const graph_;
- GrowableArray<HPhi*> worklist_;
+ ArenaVector<HPhi*> worklist_;
static constexpr size_t kDefaultWorklistSize = 8;
}
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.
void DeadPhiHandling::AddToWorklist(HPhi* instruction) {
DCHECK(instruction->IsLive());
- worklist_.Add(instruction);
+ worklist_.push_back(instruction);
}
void DeadPhiHandling::AddDependentInstructionsToWorklist(HPhi* instruction) {
}
// 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()) {
}
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) {
// 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);
block->AddPhi(phi);
value = phi;
}
- current_locals_->Put(local, value);
+ (*current_locals_)[local] = value;
}
}
}
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) {
}
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);
}
if (instruction->NeedsEnvironment()) {
HEnvironment* environment = new (GetGraph()->GetArena()) HEnvironment(
GetGraph()->GetArena(),
- current_locals_->Size(),
+ current_locals_->size(),
GetGraph()->GetDexFile(),
GetGraph()->GetMethodIdx(),
instruction->GetDexPc(),
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);
}
}
}
#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"
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;
}
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);
};