diff options
Diffstat (limited to 'compiler/optimizing/licm.cc')
| -rw-r--r-- | compiler/optimizing/licm.cc | 28 |
1 files changed, 14 insertions, 14 deletions
diff --git a/compiler/optimizing/licm.cc b/compiler/optimizing/licm.cc index 7543cd6c54..f0086fb202 100644 --- a/compiler/optimizing/licm.cc +++ b/compiler/optimizing/licm.cc @@ -15,6 +15,7 @@ */ #include "licm.h" + #include "side_effects_analysis.h" namespace art { @@ -30,8 +31,8 @@ static bool IsPhiOf(HInstruction* instruction, HBasicBlock* block) { static bool InputsAreDefinedBeforeLoop(HInstruction* instruction) { DCHECK(instruction->IsInLoop()); HLoopInformation* info = instruction->GetBlock()->GetLoopInformation(); - for (HInputIterator it(instruction); !it.Done(); it.Advance()) { - HLoopInformation* input_loop = it.Current()->GetBlock()->GetLoopInformation(); + for (const HInstruction* input : instruction->GetInputs()) { + HLoopInformation* input_loop = input->GetBlock()->GetLoopInformation(); // We only need to check whether the input is defined in the loop. If it is not // it is defined before the loop. if (input_loop != nullptr && input_loop->IsIn(*info)) { @@ -90,8 +91,7 @@ void LICM::Run() { } // Post order visit to visit inner loops before outer loops. - for (HPostOrderIterator it(*graph_); !it.Done(); it.Advance()) { - HBasicBlock* block = it.Current(); + for (HBasicBlock* block : graph_->GetPostOrder()) { if (!block->IsLoopHeader()) { // Only visit the loop when we reach the header. continue; @@ -120,17 +120,17 @@ void LICM::Run() { } DCHECK(!loop_info->IsIrreducible()); - // We can move an instruction that can throw only if it is the first - // throwing instruction in the loop. Note that the first potentially - // throwing instruction encountered that is not hoisted stops this - // optimization. Non-throwing instruction can still be hoisted. - bool found_first_non_hoisted_throwing_instruction_in_loop = !inner->IsLoopHeader(); + // We can move an instruction that can throw only as long as it is the first visible + // instruction (throw or write) in the loop. Note that the first potentially visible + // instruction that is not hoisted stops this optimization. Non-throwing instructions, + // on the other hand, can still be hoisted. + bool found_first_non_hoisted_visible_instruction_in_loop = !inner->IsLoopHeader(); for (HInstructionIterator inst_it(inner->GetInstructions()); !inst_it.Done(); inst_it.Advance()) { HInstruction* instruction = inst_it.Current(); if (instruction->CanBeMoved() - && (!instruction->CanThrow() || !found_first_non_hoisted_throwing_instruction_in_loop) + && (!instruction->CanThrow() || !found_first_non_hoisted_visible_instruction_in_loop) && !instruction->GetSideEffects().MayDependOn(loop_effects) && InputsAreDefinedBeforeLoop(instruction)) { // We need to update the environment if the instruction has a loop header @@ -142,10 +142,10 @@ void LICM::Run() { } instruction->MoveBefore(pre_header->GetLastInstruction()); MaybeRecordStat(MethodCompilationStat::kLoopInvariantMoved); - } else if (instruction->CanThrow()) { - // If `instruction` can throw, we cannot move further instructions - // that can throw as well. - found_first_non_hoisted_throwing_instruction_in_loop = true; + } else if (instruction->CanThrow() || instruction->DoesAnyWrite()) { + // If `instruction` can do something visible (throw or write), + // we cannot move further instructions that can throw. + found_first_non_hoisted_visible_instruction_in_loop = true; } } } |