Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(276)

Side by Side Diff: runtime/vm/flow_graph_optimizer.cc

Issue 14740005: Initial support for polymorphic inlining. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Incorporated review comments. Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/flow_graph_optimizer.h ('k') | runtime/vm/flow_graph_type_propagator.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_optimizer.h ('k') | runtime/vm/flow_graph_type_propagator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698