Chromium Code Reviews| 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" | 10 #include "vm/parser.h" |
| (...skipping 643 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 654 for (intptr_t i = 0; i < join_entry->phis()->length(); ++i) { | 654 for (intptr_t i = 0; i < join_entry->phis()->length(); ++i) { |
| 655 PhiInstr* phi = (*join_entry->phis())[i]; | 655 PhiInstr* phi = (*join_entry->phis())[i]; |
| 656 if (phi != NULL) { | 656 if (phi != NULL) { |
| 657 VisitPhi(phi); | 657 VisitPhi(phi); |
| 658 } | 658 } |
| 659 } | 659 } |
| 660 } | 660 } |
| 661 } | 661 } |
| 662 | 662 |
| 663 | 663 |
| 664 // TODO(srdjan): Investigate if the propagated cid should be more specific. | |
| 665 void FlowGraphTypePropagator::VisitPushArgument(PushArgumentInstr* bind) { | |
| 666 if (!bind->has_propagated_cid()) bind->SetPropagatedCid(kDynamicCid); | |
|
regis
2012/08/16 01:07:44
I do not understand why you have to do this.
Is th
srdjan
2012/08/16 01:21:28
s/bind/push/
PushArgumentInstr is in the instructi
| |
| 667 } | |
| 668 | |
| 669 | |
| 664 void FlowGraphTypePropagator::VisitBind(BindInstr* bind) { | 670 void FlowGraphTypePropagator::VisitBind(BindInstr* bind) { |
| 665 // No need to propagate the input types of the bound computation, as long as | 671 // No need to propagate the input types of the bound computation, as long as |
| 666 // PhiInstr's are handled as part of JoinEntryInstr. | 672 // PhiInstr's are handled as part of JoinEntryInstr. |
| 667 // Visit computation and possibly eliminate type check. | 673 // Visit computation and possibly eliminate type check. |
| 668 bind->computation()->Accept(this, bind); | 674 bind->computation()->Accept(this, bind); |
| 669 // Cache propagated computation type. | 675 // Cache propagated computation type. |
| 670 AbstractType& type = AbstractType::Handle(bind->computation()->CompileType()); | 676 AbstractType& type = AbstractType::Handle(bind->computation()->CompileType()); |
| 671 bool changed = bind->SetPropagatedType(type); | 677 bool changed = bind->SetPropagatedType(type); |
| 672 if (changed) { | 678 if (changed) { |
| 673 still_changing_ = true; | 679 still_changing_ = true; |
| 674 } | 680 } |
| 681 // Propagate class ids. | |
| 682 intptr_t cid = bind->computation()->ResultCid(); | |
| 683 changed = bind->SetPropagatedCid(cid); | |
| 684 if (changed) { | |
| 685 still_changing_ = true; | |
| 686 } | |
| 675 } | 687 } |
| 676 | 688 |
| 677 | 689 |
| 678 void FlowGraphTypePropagator::VisitPhi(PhiInstr* phi) { | 690 void FlowGraphTypePropagator::VisitPhi(PhiInstr* phi) { |
| 679 // We could set the propagated type of the phi to the least upper bound of its | 691 // We could set the propagated type of the phi to the least upper bound of its |
| 680 // input propagated types. However, keeping all propagated types allows us to | 692 // input propagated types. However, keeping all propagated types allows us to |
| 681 // optimize method dispatch. | 693 // optimize method dispatch. |
| 682 // TODO(regis): Support a set of propagated types. For now, we compute the | 694 // TODO(regis): Support a set of propagated types. For now, we compute the |
| 683 // least specific of the input propagated types. | 695 // least specific of the input propagated types. |
| 684 AbstractType& type = AbstractType::Handle(phi->LeastSpecificInputType()); | 696 AbstractType& type = AbstractType::Handle(phi->LeastSpecificInputType()); |
| 685 bool changed = phi->SetPropagatedType(type); | 697 bool changed = phi->SetPropagatedType(type); |
| 686 if (changed) { | 698 if (changed) { |
| 687 still_changing_ = true; | 699 still_changing_ = true; |
| 688 } | 700 } |
| 701 | |
| 702 // Merge class ids: if any two inputs have different class ids then result | |
| 703 // is kDynamicCid. | |
| 704 intptr_t merged_cid = kIllegalCid; | |
| 705 for (intptr_t i = 0; i < phi->InputCount(); i++) { | |
| 706 // Result cid of UseVal can be kIllegalCid if the referred definition | |
| 707 // has not been visited yet. | |
| 708 intptr_t cid = phi->InputAt(i)->ResultCid(); | |
| 709 if (cid == kIllegalCid) { | |
| 710 still_changing_ = true; | |
| 711 continue; | |
| 712 } | |
| 713 if (merged_cid == kIllegalCid) { | |
| 714 // First time set. | |
| 715 merged_cid = cid; | |
| 716 } else if (merged_cid != cid) { | |
| 717 merged_cid = kDynamicCid; | |
| 718 } | |
| 719 } | |
| 720 if (merged_cid == kIllegalCid) { | |
|
regis
2012/08/16 01:07:44
I do not think this can happen. This would mean th
srdjan
2012/08/16 01:21:28
I think it is theoretically possible to order the
| |
| 721 merged_cid = kDynamicCid; | |
| 722 } | |
| 723 changed = phi->SetPropagatedCid(merged_cid); | |
| 724 if (changed) { | |
| 725 still_changing_ = true; | |
| 726 } | |
| 689 } | 727 } |
| 690 | 728 |
| 691 | 729 |
| 692 void FlowGraphTypePropagator::VisitParameter(ParameterInstr* param) { | 730 void FlowGraphTypePropagator::VisitParameter(ParameterInstr* param) { |
| 693 // TODO(regis): Once we inline functions, the propagated type of the formal | 731 // TODO(regis): Once we inline functions, the propagated type of the formal |
| 694 // parameter will reflect the compile type of the passed-in argument. | 732 // parameter will reflect the compile type of the passed-in argument. |
| 695 // For now, we do not know anything about the argument type and therefore set | 733 // For now, we do not know anything about the argument type and therefore set |
| 696 // it to the DynamicType, unless the argument is a compiler generated value, | 734 // it to the DynamicType, unless the argument is a compiler generated value, |
| 697 // i.e. the receiver argument or the constructor phase argument. | 735 // i.e. the receiver argument or the constructor phase argument. |
| 698 AbstractType& param_type = AbstractType::Handle(Type::DynamicType()); | 736 AbstractType& param_type = AbstractType::Handle(Type::DynamicType()); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 730 LocationSummary* locs = it.Current()->locs(); | 768 LocationSummary* locs = it.Current()->locs(); |
| 731 if ((locs != NULL) && locs->can_call()) { | 769 if ((locs != NULL) && locs->can_call()) { |
| 732 is_leaf_ = false; | 770 is_leaf_ = false; |
| 733 return; | 771 return; |
| 734 } | 772 } |
| 735 } | 773 } |
| 736 } | 774 } |
| 737 } | 775 } |
| 738 | 776 |
| 739 } // namespace dart | 777 } // namespace dart |
| OLD | NEW |