| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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/flow_graph_builder.h" | 7 #include "vm/flow_graph_builder.h" |
| 8 #include "vm/il_printer.h" | 8 #include "vm/il_printer.h" |
| 9 #include "vm/object_store.h" | 9 #include "vm/object_store.h" |
| 10 #include "vm/parser.h" |
| 11 #include "vm/scopes.h" |
| 10 | 12 |
| 11 namespace dart { | 13 namespace dart { |
| 12 | 14 |
| 13 DECLARE_FLAG(bool, eliminate_type_checks); | 15 DECLARE_FLAG(bool, eliminate_type_checks); |
| 14 DECLARE_FLAG(bool, enable_type_checks); | 16 DECLARE_FLAG(bool, enable_type_checks); |
| 15 DEFINE_FLAG(bool, trace_optimization, false, "Print optimization details."); | 17 DEFINE_FLAG(bool, trace_optimization, false, "Print optimization details."); |
| 16 DECLARE_FLAG(bool, trace_type_check_elimination); | 18 DECLARE_FLAG(bool, trace_type_check_elimination); |
| 17 | 19 |
| 18 void FlowGraphOptimizer::ApplyICData() { | 20 void FlowGraphOptimizer::ApplyICData() { |
| 19 VisitBlocks(); | 21 VisitBlocks(); |
| (...skipping 572 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 592 void FlowGraphTypePropagator::VisitGraphEntry(GraphEntryInstr* graph_entry) { | 594 void FlowGraphTypePropagator::VisitGraphEntry(GraphEntryInstr* graph_entry) { |
| 593 if (graph_entry->start_env() == NULL) { | 595 if (graph_entry->start_env() == NULL) { |
| 594 return; | 596 return; |
| 595 } | 597 } |
| 596 // Visit incoming parameters. | 598 // Visit incoming parameters. |
| 597 for (intptr_t i = 0; i < graph_entry->start_env()->values().length(); i++) { | 599 for (intptr_t i = 0; i < graph_entry->start_env()->values().length(); i++) { |
| 598 Value* val = graph_entry->start_env()->values()[i]; | 600 Value* val = graph_entry->start_env()->values()[i]; |
| 599 if (val->IsUse()) { | 601 if (val->IsUse()) { |
| 600 ParameterInstr* param = val->AsUse()->definition()->AsParameter(); | 602 ParameterInstr* param = val->AsUse()->definition()->AsParameter(); |
| 601 if (param != NULL) { | 603 if (param != NULL) { |
| 604 ASSERT(param->index() == i); |
| 602 VisitParameter(param); | 605 VisitParameter(param); |
| 603 } | 606 } |
| 604 } | 607 } |
| 605 } | 608 } |
| 606 } | 609 } |
| 607 | 610 |
| 608 | 611 |
| 609 void FlowGraphTypePropagator::VisitJoinEntry(JoinEntryInstr* join_entry) { | 612 void FlowGraphTypePropagator::VisitJoinEntry(JoinEntryInstr* join_entry) { |
| 610 if (join_entry->phis() != NULL) { | 613 if (join_entry->phis() != NULL) { |
| 611 for (intptr_t i = 0; i < join_entry->phis()->length(); ++i) { | 614 for (intptr_t i = 0; i < join_entry->phis()->length(); ++i) { |
| (...skipping 30 matching lines...) Expand all Loading... |
| 642 bool changed = phi->SetPropagatedType(type); | 645 bool changed = phi->SetPropagatedType(type); |
| 643 if (changed) { | 646 if (changed) { |
| 644 still_changing_ = true; | 647 still_changing_ = true; |
| 645 } | 648 } |
| 646 } | 649 } |
| 647 | 650 |
| 648 | 651 |
| 649 void FlowGraphTypePropagator::VisitParameter(ParameterInstr* param) { | 652 void FlowGraphTypePropagator::VisitParameter(ParameterInstr* param) { |
| 650 // TODO(regis): Once we inline functions, the propagated type of the formal | 653 // TODO(regis): Once we inline functions, the propagated type of the formal |
| 651 // parameter will reflect the compile type of the passed-in argument. | 654 // parameter will reflect the compile type of the passed-in argument. |
| 652 // For now, we do not known anything about this type and therefore set it to | 655 // For now, we do not know anything about the argument type and therefore set |
| 653 // the DynamicType. | 656 // it to the DynamicType, unless the argument is a compiler generated value, |
| 654 bool changed = param->SetPropagatedType(Type::Handle(Type::DynamicType())); | 657 // i.e. the receiver argument or the constructor phase argument. |
| 658 AbstractType& param_type = AbstractType::Handle(Type::DynamicType()); |
| 659 if (param->index() < 2) { |
| 660 const Function& function = parsed_function().function(); |
| 661 if (((param->index() == 0) && function.IsDynamicFunction()) || |
| 662 ((param->index() == 1) && function.IsConstructor())) { |
| 663 // Parameter is the receiver or the constructor phase. |
| 664 LocalScope* scope = parsed_function().node_sequence()->scope(); |
| 665 param_type = scope->VariableAt(param->index())->type().raw(); |
| 666 } |
| 667 } |
| 668 bool changed = param->SetPropagatedType(param_type); |
| 655 if (changed) { | 669 if (changed) { |
| 656 still_changing_ = true; | 670 still_changing_ = true; |
| 657 } | 671 } |
| 658 } | 672 } |
| 659 | 673 |
| 660 | 674 |
| 661 void FlowGraphTypePropagator::PropagateTypes() { | 675 void FlowGraphTypePropagator::PropagateTypes() { |
| 662 // TODO(regis): Is there a way to make this more efficient, e.g. by visiting | 676 // TODO(regis): Is there a way to make this more efficient, e.g. by visiting |
| 663 // only blocks depending on blocks that have changed and not the whole graph. | 677 // only blocks depending on blocks that have changed and not the whole graph. |
| 664 do { | 678 do { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 676 LocationSummary* locs = it.Current()->locs(); | 690 LocationSummary* locs = it.Current()->locs(); |
| 677 if ((locs != NULL) && locs->is_call()) { | 691 if ((locs != NULL) && locs->is_call()) { |
| 678 is_leaf_ = false; | 692 is_leaf_ = false; |
| 679 return; | 693 return; |
| 680 } | 694 } |
| 681 } | 695 } |
| 682 } | 696 } |
| 683 } | 697 } |
| 684 | 698 |
| 685 } // namespace dart | 699 } // namespace dart |
| OLD | NEW |