OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/flow_graph_optimizer.h" | 5 #include "vm/flow_graph_optimizer.h" |
6 | 6 |
7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
8 #include "vm/cha.h" | 8 #include "vm/cha.h" |
9 #include "vm/flow_graph_builder.h" | 9 #include "vm/flow_graph_builder.h" |
10 #include "vm/flow_graph_compiler.h" | 10 #include "vm/flow_graph_compiler.h" |
(...skipping 3220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3231 if (pre_header == NULL) continue; | 3231 if (pre_header == NULL) continue; |
3232 | 3232 |
3233 for (BitVector::Iterator loop_it(header->loop_info()); | 3233 for (BitVector::Iterator loop_it(header->loop_info()); |
3234 !loop_it.Done(); | 3234 !loop_it.Done(); |
3235 loop_it.Advance()) { | 3235 loop_it.Advance()) { |
3236 BlockEntryInstr* block = flow_graph()->preorder()[loop_it.Current()]; | 3236 BlockEntryInstr* block = flow_graph()->preorder()[loop_it.Current()]; |
3237 for (ForwardInstructionIterator it(block); | 3237 for (ForwardInstructionIterator it(block); |
3238 !it.Done(); | 3238 !it.Done(); |
3239 it.Advance()) { | 3239 it.Advance()) { |
3240 Instruction* current = it.Current(); | 3240 Instruction* current = it.Current(); |
3241 if (!current->IsPushArgument() && | 3241 if (current->AllowsCSE() && |
3242 current->AllowsCSE() && | |
3243 flow_graph()->block_effects()->CanBeMovedTo(current, pre_header)) { | 3242 flow_graph()->block_effects()->CanBeMovedTo(current, pre_header)) { |
3244 bool inputs_loop_invariant = true; | 3243 bool inputs_loop_invariant = true; |
3245 for (int i = 0; i < current->InputCount(); ++i) { | 3244 for (int i = 0; i < current->InputCount(); ++i) { |
3246 Definition* input_def = current->InputAt(i)->definition(); | 3245 Definition* input_def = current->InputAt(i)->definition(); |
3247 if (!input_def->GetBlock()->Dominates(pre_header)) { | 3246 if (!input_def->GetBlock()->Dominates(pre_header)) { |
3248 inputs_loop_invariant = false; | 3247 inputs_loop_invariant = false; |
3249 break; | 3248 break; |
3250 } | 3249 } |
3251 } | 3250 } |
3252 if (inputs_loop_invariant && | 3251 if (inputs_loop_invariant && |
(...skipping 1270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4523 if (reachable_->Contains( | 4522 if (reachable_->Contains( |
4524 block->PredecessorAt(pred_idx)->preorder_number())) { | 4523 block->PredecessorAt(pred_idx)->preorder_number())) { |
4525 Join(&value, | 4524 Join(&value, |
4526 instr->InputAt(pred_idx)->definition()->constant_value()); | 4525 instr->InputAt(pred_idx)->definition()->constant_value()); |
4527 } | 4526 } |
4528 } | 4527 } |
4529 SetValue(instr, value); | 4528 SetValue(instr, value); |
4530 } | 4529 } |
4531 | 4530 |
4532 | 4531 |
| 4532 void ConstantPropagator::VisitRedefinition(RedefinitionInstr* instr) { |
| 4533 SetValue(instr, instr->value()->definition()->constant_value()); |
| 4534 } |
| 4535 |
| 4536 |
4533 void ConstantPropagator::VisitParameter(ParameterInstr* instr) { | 4537 void ConstantPropagator::VisitParameter(ParameterInstr* instr) { |
4534 SetValue(instr, non_constant_); | 4538 SetValue(instr, non_constant_); |
4535 } | 4539 } |
4536 | 4540 |
4537 | 4541 |
4538 void ConstantPropagator::VisitPushArgument(PushArgumentInstr* instr) { | 4542 void ConstantPropagator::VisitPushArgument(PushArgumentInstr* instr) { |
4539 SetValue(instr, instr->value()->definition()->constant_value()); | 4543 SetValue(instr, instr->value()->definition()->constant_value()); |
4540 } | 4544 } |
4541 | 4545 |
4542 | 4546 |
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4797 AllocateObjectWithBoundsCheckInstr* instr) { | 4801 AllocateObjectWithBoundsCheckInstr* instr) { |
4798 SetValue(instr, non_constant_); | 4802 SetValue(instr, non_constant_); |
4799 } | 4803 } |
4800 | 4804 |
4801 | 4805 |
4802 void ConstantPropagator::VisitLoadUntagged(LoadUntaggedInstr* instr) { | 4806 void ConstantPropagator::VisitLoadUntagged(LoadUntaggedInstr* instr) { |
4803 SetValue(instr, non_constant_); | 4807 SetValue(instr, non_constant_); |
4804 } | 4808 } |
4805 | 4809 |
4806 | 4810 |
| 4811 void ConstantPropagator::VisitLoadClassId(LoadClassIdInstr* instr) { |
| 4812 SetValue(instr, non_constant_); |
| 4813 } |
| 4814 |
| 4815 |
4807 void ConstantPropagator::VisitLoadField(LoadFieldInstr* instr) { | 4816 void ConstantPropagator::VisitLoadField(LoadFieldInstr* instr) { |
4808 if ((instr->recognized_kind() == MethodRecognizer::kObjectArrayLength) && | 4817 if ((instr->recognized_kind() == MethodRecognizer::kObjectArrayLength) && |
4809 (instr->instance()->definition()->IsCreateArray())) { | 4818 (instr->instance()->definition()->IsCreateArray())) { |
4810 const intptr_t length = | 4819 const intptr_t length = |
4811 instr->instance()->definition()->AsCreateArray()->num_elements(); | 4820 instr->instance()->definition()->AsCreateArray()->num_elements(); |
4812 const Object& result = Smi::ZoneHandle(Smi::New(length)); | 4821 const Object& result = Smi::ZoneHandle(Smi::New(length)); |
4813 SetValue(instr, result); | 4822 SetValue(instr, result); |
4814 return; | 4823 return; |
4815 } | 4824 } |
4816 | 4825 |
(...skipping 754 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5571 | 5580 |
5572 // Insert a copy of the constant in all the predecessors. | 5581 // Insert a copy of the constant in all the predecessors. |
5573 ConstantInstr* new_constant = CloneConstant(flow_graph, constant); | 5582 ConstantInstr* new_constant = CloneConstant(flow_graph, constant); |
5574 new_constant->InsertBefore(old_goto); | 5583 new_constant->InsertBefore(old_goto); |
5575 | 5584 |
5576 // Replace the goto in each predecessor with a rewritten branch, | 5585 // Replace the goto in each predecessor with a rewritten branch, |
5577 // rewritten to use the corresponding phi input instead of the phi. | 5586 // rewritten to use the corresponding phi input instead of the phi. |
5578 Value* new_left = phi->InputAt(i)->Copy(); | 5587 Value* new_left = phi->InputAt(i)->Copy(); |
5579 Value* new_right = new Value(new_constant); | 5588 Value* new_right = new Value(new_constant); |
5580 BranchInstr* new_branch = CloneBranch(branch, new_left, new_right); | 5589 BranchInstr* new_branch = CloneBranch(branch, new_left, new_right); |
5581 new_branch->InheritDeoptTarget(old_goto); | 5590 if (branch->env() == NULL) { |
| 5591 new_branch->InheritDeoptTarget(old_goto); |
| 5592 } else { |
| 5593 // Take the environment from the branch if it has one. |
| 5594 new_branch->InheritDeoptTarget(branch); |
| 5595 // InheritDeoptTarget gave the new branch's comparison the same |
| 5596 // deopt id that it gave the new branch. The id should be the |
| 5597 // deopt id of the original comparison. |
| 5598 new_branch->comparison()->SetDeoptId(comparison->GetDeoptId()); |
| 5599 // The phi and constant can be used in the branch's environment. |
| 5600 // Rename such uses. |
| 5601 for (Environment::DeepIterator it(new_branch->env()); |
| 5602 !it.Done(); |
| 5603 it.Advance()) { |
| 5604 Value* use = it.CurrentValue(); |
| 5605 Definition* replacement = NULL; |
| 5606 if (use->definition() == phi) { |
| 5607 replacement = phi->InputAt(i)->definition(); |
| 5608 } else if (use->definition() == constant) { |
| 5609 replacement = new_constant; |
| 5610 } |
| 5611 if (replacement != NULL) { |
| 5612 use->RemoveFromUseList(); |
| 5613 use->set_definition(replacement); |
| 5614 replacement->AddEnvUse(use); |
| 5615 } |
| 5616 } |
| 5617 } |
| 5618 |
5582 new_branch->InsertBefore(old_goto); | 5619 new_branch->InsertBefore(old_goto); |
5583 new_branch->set_next(NULL); // Detaching the goto from the graph. | 5620 new_branch->set_next(NULL); // Detaching the goto from the graph. |
5584 old_goto->UnuseAllInputs(); | 5621 old_goto->UnuseAllInputs(); |
5585 | 5622 |
5586 // Update the predecessor block. We may have created another | 5623 // Update the predecessor block. We may have created another |
5587 // instance of the pattern so add it to the worklist if necessary. | 5624 // instance of the pattern so add it to the worklist if necessary. |
5588 BlockEntryInstr* branch_block = new_branch->GetBlock(); | 5625 BlockEntryInstr* branch_block = new_branch->GetBlock(); |
5589 branch_block->set_last_instruction(new_branch); | 5626 branch_block->set_last_instruction(new_branch); |
5590 if (branch_block->IsJoinEntry()) worklist.Add(branch_block); | 5627 if (branch_block->IsJoinEntry()) worklist.Add(branch_block); |
5591 | 5628 |
(...skipping 17 matching lines...) Expand all Loading... |
5609 GotoInstr* goto_false = new GotoInstr(join_false); | 5646 GotoInstr* goto_false = new GotoInstr(join_false); |
5610 goto_false->InheritDeoptTarget(join_false); | 5647 goto_false->InheritDeoptTarget(join_false); |
5611 false_target->LinkTo(goto_false); | 5648 false_target->LinkTo(goto_false); |
5612 false_target->set_last_instruction(goto_false); | 5649 false_target->set_last_instruction(goto_false); |
5613 } | 5650 } |
5614 // When all predecessors have been rewritten, the original block is | 5651 // When all predecessors have been rewritten, the original block is |
5615 // unreachable from the graph. | 5652 // unreachable from the graph. |
5616 phi->UnuseAllInputs(); | 5653 phi->UnuseAllInputs(); |
5617 branch->UnuseAllInputs(); | 5654 branch->UnuseAllInputs(); |
5618 block->UnuseAllInputs(); | 5655 block->UnuseAllInputs(); |
| 5656 ASSERT(!phi->HasUses()); |
| 5657 ASSERT(!constant->HasUses()); |
5619 } | 5658 } |
5620 } | 5659 } |
5621 | 5660 |
5622 if (changed) { | 5661 if (changed) { |
5623 // We may have changed the block order and the dominator tree. | 5662 // We may have changed the block order and the dominator tree. |
5624 flow_graph->DiscoverBlocks(); | 5663 flow_graph->DiscoverBlocks(); |
5625 GrowableArray<BitVector*> dominance_frontier; | 5664 GrowableArray<BitVector*> dominance_frontier; |
5626 flow_graph->ComputeDominators(&dominance_frontier); | 5665 flow_graph->ComputeDominators(&dominance_frontier); |
5627 } | 5666 } |
5628 } | 5667 } |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5751 if (changed) { | 5790 if (changed) { |
5752 // We may have changed the block order and the dominator tree. | 5791 // We may have changed the block order and the dominator tree. |
5753 flow_graph->DiscoverBlocks(); | 5792 flow_graph->DiscoverBlocks(); |
5754 GrowableArray<BitVector*> dominance_frontier; | 5793 GrowableArray<BitVector*> dominance_frontier; |
5755 flow_graph->ComputeDominators(&dominance_frontier); | 5794 flow_graph->ComputeDominators(&dominance_frontier); |
5756 } | 5795 } |
5757 } | 5796 } |
5758 | 5797 |
5759 | 5798 |
5760 } // namespace dart | 5799 } // namespace dart |
OLD | NEW |