diff options
| author | 2015-09-21 14:30:38 +0000 | |
|---|---|---|
| committer | 2015-09-21 14:30:38 +0000 | |
| commit | 7b87ff905ada1815d9b24843cf13b6ff54240e34 (patch) | |
| tree | 63a071bad49006cf09cba94cf9cd0439e2fb83cc /compiler/optimizing/ssa_builder.cc | |
| parent | 47d89c7376090a3a4b8eb114e2c861afe27d01d0 (diff) | |
| parent | eead0711984ee20a3bba7c2e2415593a520e40b3 (diff) | |
Merge "ART: Optimize catch phi creation to save memory."
Diffstat (limited to 'compiler/optimizing/ssa_builder.cc')
| -rw-r--r-- | compiler/optimizing/ssa_builder.cc | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/compiler/optimizing/ssa_builder.cc b/compiler/optimizing/ssa_builder.cc index 6f71ea3d6b..f511603abd 100644 --- a/compiler/optimizing/ssa_builder.cc +++ b/compiler/optimizing/ssa_builder.cc @@ -345,6 +345,33 @@ void SsaBuilder::BuildSsa() { } } +ArenaVector<HInstruction*>* SsaBuilder::GetLocalsFor(HBasicBlock* block) { + DCHECK_LT(block->GetBlockId(), locals_for_.size()); + ArenaVector<HInstruction*>* locals = &locals_for_[block->GetBlockId()]; + const size_t vregs = GetGraph()->GetNumberOfVRegs(); + if (locals->empty() && vregs != 0u) { + locals->resize(vregs, nullptr); + + if (block->IsCatchBlock()) { + ArenaAllocator* arena = GetGraph()->GetArena(); + // We record incoming inputs of catch phis at throwing instructions and + // must therefore eagerly create the phis. Phis for undefined vregs will + // be deleted when the first throwing instruction with the vreg undefined + // is encountered. Unused phis will be removed by dead phi analysis. + for (size_t i = 0; i < vregs; ++i) { + // No point in creating the catch phi if it is already undefined at + // the first throwing instruction. + if ((*current_locals_)[i] != nullptr) { + HPhi* phi = new (arena) HPhi(arena, i, 0, Primitive::kPrimVoid); + block->AddPhi(phi); + (*locals)[i] = phi; + } + } + } + } + return locals; +} + HInstruction* SsaBuilder::ValueOfLocal(HBasicBlock* block, size_t local) { ArenaVector<HInstruction*>* locals = GetLocalsFor(block); DCHECK_LT(local, locals->size()); |