diff options
Diffstat (limited to 'compiler/optimizing')
-rw-r--r-- | compiler/optimizing/code_generator_mips64.cc | 11 | ||||
-rw-r--r-- | compiler/optimizing/ssa_builder.cc | 57 | ||||
-rw-r--r-- | compiler/optimizing/ssa_builder.h | 25 |
3 files changed, 60 insertions, 33 deletions
diff --git a/compiler/optimizing/code_generator_mips64.cc b/compiler/optimizing/code_generator_mips64.cc index 4722e42694..f4f53d5f32 100644 --- a/compiler/optimizing/code_generator_mips64.cc +++ b/compiler/optimizing/code_generator_mips64.cc @@ -971,11 +971,11 @@ size_t CodeGeneratorMIPS64::RestoreFloatingPointRegister(size_t stack_index, uin } void CodeGeneratorMIPS64::DumpCoreRegister(std::ostream& stream, int reg) const { - stream << Mips64ManagedRegister::FromGpuRegister(GpuRegister(reg)); + stream << GpuRegister(reg); } void CodeGeneratorMIPS64::DumpFloatingPointRegister(std::ostream& stream, int reg) const { - stream << Mips64ManagedRegister::FromFpuRegister(FpuRegister(reg)); + stream << FpuRegister(reg); } void CodeGeneratorMIPS64::InvokeRuntime(QuickEntrypointEnum entrypoint, @@ -1444,12 +1444,11 @@ void InstructionCodeGeneratorMIPS64::VisitArrayLength(HArrayLength* instruction) } void LocationsBuilderMIPS64::VisitArraySet(HArraySet* instruction) { - Primitive::Type value_type = instruction->GetComponentType(); - bool is_object = value_type == Primitive::kPrimNot; + bool needs_runtime_call = instruction->NeedsTypeCheck(); LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary( instruction, - is_object ? LocationSummary::kCall : LocationSummary::kNoCall); - if (is_object) { + needs_runtime_call ? LocationSummary::kCall : LocationSummary::kNoCall); + if (needs_runtime_call) { InvokeRuntimeCallingConvention calling_convention; locations->SetInAt(0, Location::RegisterLocation(calling_convention.GetRegisterAt(0))); locations->SetInAt(1, Location::RegisterLocation(calling_convention.GetRegisterAt(1))); diff --git a/compiler/optimizing/ssa_builder.cc b/compiler/optimizing/ssa_builder.cc index 6f71ea3d6b..0ef86d80ed 100644 --- a/compiler/optimizing/ssa_builder.cc +++ b/compiler/optimizing/ssa_builder.cc @@ -57,8 +57,13 @@ class DeadPhiHandling : public ValueObject { }; bool DeadPhiHandling::UpdateType(HPhi* phi) { + if (phi->IsDead()) { + // Phi was rendered dead while waiting in the worklist because it was replaced + // with an equivalent. + return false; + } + Primitive::Type existing = phi->GetType(); - DCHECK(phi->IsLive()); bool conflict = false; Primitive::Type new_type = existing; @@ -112,11 +117,26 @@ bool DeadPhiHandling::UpdateType(HPhi* phi) { phi->SetType(Primitive::kPrimVoid); phi->SetDead(); return true; - } else { - DCHECK(phi->IsLive()); - phi->SetType(new_type); - return existing != new_type; + } else if (existing == new_type) { + return false; + } + + DCHECK(phi->IsLive()); + phi->SetType(new_type); + + // There might exist a `new_type` equivalent of `phi` already. In that case, + // we replace the equivalent with the, now live, `phi`. + HPhi* equivalent = phi->GetNextEquivalentPhiWithSameType(); + if (equivalent != nullptr) { + // There cannot be more than two equivalents with the same type. + DCHECK(equivalent->GetNextEquivalentPhiWithSameType() == nullptr); + // If doing fix-point iteration, the equivalent might be in `worklist_`. + // Setting it dead will make UpdateType skip it. + equivalent->SetDead(); + equivalent->ReplaceWith(phi); } + + return true; } void DeadPhiHandling::VisitBasicBlock(HBasicBlock* block) { @@ -345,6 +365,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()); diff --git a/compiler/optimizing/ssa_builder.h b/compiler/optimizing/ssa_builder.h index 804296f7ba..79f1a28ac8 100644 --- a/compiler/optimizing/ssa_builder.h +++ b/compiler/optimizing/ssa_builder.h @@ -61,28 +61,9 @@ class SsaBuilder : public HGraphVisitor { void BuildSsa(); - 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(); - 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)[i] = phi; - } - } - } - return locals; - } - + // Returns locals vector for `block`. If it is a catch block, the vector will be + // prepopulated with catch phis for vregs which are defined in `current_locals_`. + ArenaVector<HInstruction*>* GetLocalsFor(HBasicBlock* block); HInstruction* ValueOfLocal(HBasicBlock* block, size_t local); void VisitBasicBlock(HBasicBlock* block); |