diff options
Diffstat (limited to 'compiler/optimizing')
-rw-r--r-- | compiler/optimizing/loop_optimization.cc | 20 | ||||
-rw-r--r-- | compiler/optimizing/nodes.cc | 32 | ||||
-rw-r--r-- | compiler/optimizing/nodes.h | 4 | ||||
-rw-r--r-- | compiler/optimizing/prepare_for_register_allocation.cc | 4 |
4 files changed, 57 insertions, 3 deletions
diff --git a/compiler/optimizing/loop_optimization.cc b/compiler/optimizing/loop_optimization.cc index 274f065084..0ef7dcdb59 100644 --- a/compiler/optimizing/loop_optimization.cc +++ b/compiler/optimizing/loop_optimization.cc @@ -40,6 +40,8 @@ static void RemoveFromCycle(HInstruction* instruction) { instruction->RemoveAsUserOfAllInputs(); instruction->RemoveEnvironmentUsers(); instruction->GetBlock()->RemoveInstructionOrPhi(instruction, /*ensure_safety=*/ false); + RemoveEnvironmentUses(instruction); + ResetEnvironmentInputRecords(instruction); } // Detect a goto block and sets succ to the single successor. @@ -267,6 +269,21 @@ static HInstruction* Insert(HBasicBlock* block, HInstruction* instruction) { return instruction; } +// Check that instructions from the induction sets are fully removed: have no uses +// and no other instructions use them. +static bool CheckInductionSetFullyRemoved(ArenaSet<HInstruction*>* iset) { + for (HInstruction* instr : *iset) { + if (instr->GetBlock() != nullptr || + !instr->GetUses().empty() || + !instr->GetEnvUses().empty() || + HasEnvironmentUsedByOthers(instr)) { + return false; + } + } + + return true; +} + // // Class methods. // @@ -448,6 +465,9 @@ void HLoopOptimization::SimplifyInduction(LoopNode* node) { for (HInstruction* i : *iset_) { RemoveFromCycle(i); } + + // Check that there are no records of the deleted instructions. + DCHECK(CheckInductionSetFullyRemoved(iset_)); simplified_ = true; } } diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc index ca48e08a7c..3a1864b2ae 100644 --- a/compiler/optimizing/nodes.cc +++ b/compiler/optimizing/nodes.cc @@ -90,7 +90,8 @@ void HGraph::FindBackEdges(ArenaBitVector* visited) { } } -static void RemoveEnvironmentUses(HInstruction* instruction) { +// Remove the environment use records of the instruction for users. +void RemoveEnvironmentUses(HInstruction* instruction) { for (HEnvironment* environment = instruction->GetEnvironment(); environment != nullptr; environment = environment->GetParent()) { @@ -102,6 +103,35 @@ static void RemoveEnvironmentUses(HInstruction* instruction) { } } +// Return whether the instruction has an environment and it's used by others. +bool HasEnvironmentUsedByOthers(HInstruction* instruction) { + for (HEnvironment* environment = instruction->GetEnvironment(); + environment != nullptr; + environment = environment->GetParent()) { + for (size_t i = 0, e = environment->Size(); i < e; ++i) { + HInstruction* user = environment->GetInstructionAt(i); + if (user != nullptr) { + return true; + } + } + } + return false; +} + +// Reset environment records of the instruction itself. +void ResetEnvironmentInputRecords(HInstruction* instruction) { + for (HEnvironment* environment = instruction->GetEnvironment(); + environment != nullptr; + environment = environment->GetParent()) { + for (size_t i = 0, e = environment->Size(); i < e; ++i) { + DCHECK(environment->GetHolder() == instruction); + if (environment->GetInstructionAt(i) != nullptr) { + environment->SetRawEnvAt(i, nullptr); + } + } + } +} + static void RemoveAsUser(HInstruction* instruction) { instruction->RemoveAsUserOfAllInputs(); RemoveEnvironmentUses(instruction); diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index fa29378e42..e4431422b2 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -7059,6 +7059,10 @@ inline HInstruction* HuntForDeclaration(HInstruction* instruction) { return instruction; } +void RemoveEnvironmentUses(HInstruction* instruction); +bool HasEnvironmentUsedByOthers(HInstruction* instruction); +void ResetEnvironmentInputRecords(HInstruction* instruction); + } // namespace art #endif // ART_COMPILER_OPTIMIZING_NODES_H_ diff --git a/compiler/optimizing/prepare_for_register_allocation.cc b/compiler/optimizing/prepare_for_register_allocation.cc index aa42fd647b..7c6b69fb2f 100644 --- a/compiler/optimizing/prepare_for_register_allocation.cc +++ b/compiler/optimizing/prepare_for_register_allocation.cc @@ -208,8 +208,8 @@ void PrepareForRegisterAllocation::VisitConstructorFence(HConstructorFence* cons void PrepareForRegisterAllocation::VisitInvokeStaticOrDirect(HInvokeStaticOrDirect* invoke) { if (invoke->IsStaticWithExplicitClinitCheck()) { - HLoadClass* last_input = invoke->GetInputs().back()->AsLoadClass(); - DCHECK(last_input != nullptr) + HInstruction* last_input = invoke->GetInputs().back(); + DCHECK(last_input->IsLoadClass()) << "Last input is not HLoadClass. It is " << last_input->DebugName(); // Detach the explicit class initialization check from the invoke. |