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

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

Issue 10830339: Propagate class ids using existing type propagation framework. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 4 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/il_printer.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) 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 731 matching lines...) Expand 10 before | Expand all | Expand 10 after
742 for (intptr_t i = 0; i < join_entry->phis()->length(); ++i) { 742 for (intptr_t i = 0; i < join_entry->phis()->length(); ++i) {
743 PhiInstr* phi = (*join_entry->phis())[i]; 743 PhiInstr* phi = (*join_entry->phis())[i];
744 if (phi != NULL) { 744 if (phi != NULL) {
745 VisitPhi(phi); 745 VisitPhi(phi);
746 } 746 }
747 } 747 }
748 } 748 }
749 } 749 }
750 750
751 751
752 // TODO(srdjan): Investigate if the propagated cid should be more specific.
753 void FlowGraphTypePropagator::VisitPushArgument(PushArgumentInstr* push) {
754 if (!push->has_propagated_cid()) push->SetPropagatedCid(kDynamicCid);
755 }
756
757
752 void FlowGraphTypePropagator::VisitBind(BindInstr* bind) { 758 void FlowGraphTypePropagator::VisitBind(BindInstr* bind) {
753 // No need to propagate the input types of the bound computation, as long as 759 // No need to propagate the input types of the bound computation, as long as
754 // PhiInstr's are handled as part of JoinEntryInstr. 760 // PhiInstr's are handled as part of JoinEntryInstr.
755 // Visit computation and possibly eliminate type check. 761 // Visit computation and possibly eliminate type check.
756 bind->computation()->Accept(this, bind); 762 bind->computation()->Accept(this, bind);
757 // The current bind may have been removed from the graph. 763 // The current bind may have been removed from the graph.
758 if (current_iterator()->Current() == bind) { 764 if (current_iterator()->Current() == bind) {
759 // Current bind was not removed. 765 // Current bind was not removed.
760 // Cache propagated computation type. 766 // Cache propagated computation type.
761 AbstractType& computation_type = 767 AbstractType& computation_type =
762 AbstractType::Handle(bind->computation()->CompileType()); 768 AbstractType::Handle(bind->computation()->CompileType());
763 bool changed = bind->SetPropagatedType(computation_type); 769 bool changed = bind->SetPropagatedType(computation_type);
764 if (changed) { 770 if (changed) {
765 still_changing_ = true; 771 still_changing_ = true;
766 } 772 }
773 // Propagate class ids.
774 intptr_t cid = bind->computation()->ResultCid();
775 changed = bind->SetPropagatedCid(cid);
776 if (changed) {
777 still_changing_ = true;
778 }
767 } 779 }
768 } 780 }
769 781
770 782
771 void FlowGraphTypePropagator::VisitPhi(PhiInstr* phi) { 783 void FlowGraphTypePropagator::VisitPhi(PhiInstr* phi) {
772 // We could set the propagated type of the phi to the least upper bound of its 784 // We could set the propagated type of the phi to the least upper bound of its
773 // input propagated types. However, keeping all propagated types allows us to 785 // input propagated types. However, keeping all propagated types allows us to
774 // optimize method dispatch. 786 // optimize method dispatch.
775 // TODO(regis): Support a set of propagated types. For now, we compute the 787 // TODO(regis): Support a set of propagated types. For now, we compute the
776 // least specific of the input propagated types. 788 // least specific of the input propagated types.
777 AbstractType& type = AbstractType::Handle(phi->LeastSpecificInputType()); 789 AbstractType& type = AbstractType::Handle(phi->LeastSpecificInputType());
778 bool changed = phi->SetPropagatedType(type); 790 bool changed = phi->SetPropagatedType(type);
779 if (changed) { 791 if (changed) {
780 still_changing_ = true; 792 still_changing_ = true;
781 } 793 }
794
795 // Merge class ids: if any two inputs have different class ids then result
796 // is kDynamicCid.
797 intptr_t merged_cid = kIllegalCid;
798 for (intptr_t i = 0; i < phi->InputCount(); i++) {
799 // Result cid of UseVal can be kIllegalCid if the referred definition
800 // has not been visited yet.
801 intptr_t cid = phi->InputAt(i)->ResultCid();
802 if (cid == kIllegalCid) {
803 still_changing_ = true;
804 continue;
805 }
806 if (merged_cid == kIllegalCid) {
807 // First time set.
808 merged_cid = cid;
809 } else if (merged_cid != cid) {
810 merged_cid = kDynamicCid;
811 }
812 }
813 if (merged_cid == kIllegalCid) {
814 merged_cid = kDynamicCid;
815 }
816 changed = phi->SetPropagatedCid(merged_cid);
817 if (changed) {
818 still_changing_ = true;
819 }
782 } 820 }
783 821
784 822
785 void FlowGraphTypePropagator::VisitParameter(ParameterInstr* param) { 823 void FlowGraphTypePropagator::VisitParameter(ParameterInstr* param) {
786 // TODO(regis): Once we inline functions, the propagated type of the formal 824 // TODO(regis): Once we inline functions, the propagated type of the formal
787 // parameter will reflect the compile type of the passed-in argument. 825 // parameter will reflect the compile type of the passed-in argument.
788 // For now, we do not know anything about the argument type and therefore set 826 // For now, we do not know anything about the argument type and therefore set
789 // it to the DynamicType, unless the argument is a compiler generated value, 827 // it to the DynamicType, unless the argument is a compiler generated value,
790 // i.e. the receiver argument or the constructor phase argument. 828 // i.e. the receiver argument or the constructor phase argument.
791 AbstractType& param_type = AbstractType::Handle(Type::DynamicType()); 829 AbstractType& param_type = AbstractType::Handle(Type::DynamicType());
792 if (param->index() < 2) { 830 if (param->index() < 2) {
793 const Function& function = parsed_function().function(); 831 const Function& function = parsed_function().function();
794 if (((param->index() == 0) && function.IsDynamicFunction()) || 832 if (((param->index() == 0) && function.IsDynamicFunction()) ||
795 ((param->index() == 1) && function.IsConstructor())) { 833 ((param->index() == 1) && function.IsConstructor())) {
796 // Parameter is the receiver or the constructor phase. 834 // Parameter is the receiver or the constructor phase.
797 LocalScope* scope = parsed_function().node_sequence()->scope(); 835 LocalScope* scope = parsed_function().node_sequence()->scope();
798 param_type = scope->VariableAt(param->index())->type().raw(); 836 param_type = scope->VariableAt(param->index())->type().raw();
799 } 837 }
800 } 838 }
801 bool changed = param->SetPropagatedType(param_type); 839 bool changed = param->SetPropagatedType(param_type);
802 if (changed) { 840 if (changed) {
803 still_changing_ = true; 841 still_changing_ = true;
804 } 842 }
843 param->SetPropagatedCid(kDynamicCid);
805 } 844 }
806 845
807 846
808 void FlowGraphTypePropagator::PropagateTypes() { 847 void FlowGraphTypePropagator::PropagateTypes() {
809 // TODO(regis): Is there a way to make this more efficient, e.g. by visiting 848 // TODO(regis): Is there a way to make this more efficient, e.g. by visiting
810 // only blocks depending on blocks that have changed and not the whole graph. 849 // only blocks depending on blocks that have changed and not the whole graph.
811 do { 850 do {
812 still_changing_ = false; 851 still_changing_ = false;
813 VisitBlocks(); 852 VisitBlocks();
814 } while (still_changing_); 853 } while (still_changing_);
815 } 854 }
816 855
817 856
818 void FlowGraphAnalyzer::Analyze() { 857 void FlowGraphAnalyzer::Analyze() {
819 is_leaf_ = true; 858 is_leaf_ = true;
820 for (intptr_t i = 0; i < blocks_.length(); ++i) { 859 for (intptr_t i = 0; i < blocks_.length(); ++i) {
821 BlockEntryInstr* entry = blocks_[i]; 860 BlockEntryInstr* entry = blocks_[i];
822 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) { 861 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) {
823 LocationSummary* locs = it.Current()->locs(); 862 LocationSummary* locs = it.Current()->locs();
824 if ((locs != NULL) && locs->can_call()) { 863 if ((locs != NULL) && locs->can_call()) {
825 is_leaf_ = false; 864 is_leaf_ = false;
826 return; 865 return;
827 } 866 }
828 } 867 }
829 } 868 }
830 } 869 }
831 870
832 } // namespace dart 871 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_optimizer.h ('k') | runtime/vm/il_printer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698