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

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

Issue 9471010: Expand the instruction visitor to visit computations and values. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 9 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
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_builder.h" 5 #include "vm/flow_graph_builder.h"
6 6
7 #include "vm/flags.h" 7 #include "vm/flags.h"
8 #include "vm/intermediate_language.h" 8 #include "vm/intermediate_language.h"
9 #include "vm/longjump.h" 9 #include "vm/longjump.h"
10 #include "vm/os.h" 10 #include "vm/os.h"
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
163 const RawFunction::Kind kind = owner()->parsed_function().function().kind(); 163 const RawFunction::Kind kind = owner()->parsed_function().function().kind();
164 // Implicit getters do not need a type check at return. 164 // Implicit getters do not need a type check at return.
165 if ((kind != RawFunction::kImplicitGetter) && 165 if ((kind != RawFunction::kImplicitGetter) &&
166 (kind != RawFunction::kConstImplicitGetter)) { 166 (kind != RawFunction::kConstImplicitGetter)) {
167 const AbstractType& type = 167 const AbstractType& type =
168 AbstractType::ZoneHandle( 168 AbstractType::ZoneHandle(
169 owner()->parsed_function().function().result_type()); 169 owner()->parsed_function().function().result_type());
170 AssertAssignableComp* assert = 170 AssertAssignableComp* assert =
171 new AssertAssignableComp(return_value, type); 171 new AssertAssignableComp(return_value, type);
172 AddInstruction(new BindInstr(temp_index(), assert)); 172 AddInstruction(new BindInstr(temp_index(), assert));
173 return_value = new TempValue(temp_index()); 173 return_value = new TempVal(temp_index());
174 } 174 }
175 } 175 }
176 176
177 AddInstruction(new ReturnInstr(return_value)); 177 AddInstruction(new ReturnInstr(return_value));
178 CloseFragment(); 178 CloseFragment();
179 } 179 }
180 180
181 void ValueGraphVisitor::VisitReturnNode(ReturnNode* node) { UNREACHABLE(); } 181 void ValueGraphVisitor::VisitReturnNode(ReturnNode* node) { UNREACHABLE(); }
182 void TestGraphVisitor::VisitReturnNode(ReturnNode* node) { UNREACHABLE(); } 182 void TestGraphVisitor::VisitReturnNode(ReturnNode* node) { UNREACHABLE(); }
183 183
184 184
185 // <Expression> ::= Literal { literal: Instance } 185 // <Expression> ::= Literal { literal: Instance }
186 void EffectGraphVisitor::VisitLiteralNode(LiteralNode* node) { 186 void EffectGraphVisitor::VisitLiteralNode(LiteralNode* node) {
187 return; 187 return;
188 } 188 }
189 189
190 void ValueGraphVisitor::VisitLiteralNode(LiteralNode* node) { 190 void ValueGraphVisitor::VisitLiteralNode(LiteralNode* node) {
191 ReturnValue(new ConstantValue(node->literal())); 191 ReturnValue(new ConstantVal(node->literal()));
192 } 192 }
193 193
194 void TestGraphVisitor::VisitLiteralNode(LiteralNode* node) { 194 void TestGraphVisitor::VisitLiteralNode(LiteralNode* node) {
195 BranchOnValue(new ConstantValue(node->literal())); 195 BranchOnValue(new ConstantVal(node->literal()));
196 } 196 }
197 197
198 198
199 // Type nodes only occur as the right-hand side of instanceof comparisons, 199 // Type nodes only occur as the right-hand side of instanceof comparisons,
200 // and they are handled specially in that context. 200 // and they are handled specially in that context.
201 void EffectGraphVisitor::VisitTypeNode(TypeNode* node) { UNREACHABLE(); } 201 void EffectGraphVisitor::VisitTypeNode(TypeNode* node) { UNREACHABLE(); }
202 void ValueGraphVisitor::VisitTypeNode(TypeNode* node) { UNREACHABLE(); } 202 void ValueGraphVisitor::VisitTypeNode(TypeNode* node) { UNREACHABLE(); }
203 void TestGraphVisitor::VisitTypeNode(TypeNode* node) { UNREACHABLE(); } 203 void TestGraphVisitor::VisitTypeNode(TypeNode* node) { UNREACHABLE(); }
204 204
205 205
(...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after
600 int index = temp_index(); 600 int index = temp_index();
601 for (intptr_t i = 0; i < node.length(); ++i) { 601 for (intptr_t i = 0; i < node.length(); ++i) {
602 ValueGraphVisitor for_value(owner(), index); 602 ValueGraphVisitor for_value(owner(), index);
603 node.NodeAt(i)->Visit(&for_value); 603 node.NodeAt(i)->Visit(&for_value);
604 Append(for_value); 604 Append(for_value);
605 CHECK_ALIVE(return); 605 CHECK_ALIVE(return);
606 Value* argument_value = for_value.value(); 606 Value* argument_value = for_value.value();
607 index = for_value.temp_index(); 607 index = for_value.temp_index();
608 if (argument_value->IsConstant()) { 608 if (argument_value->IsConstant()) {
609 AddInstruction(new BindInstr(index, argument_value)); 609 AddInstruction(new BindInstr(index, argument_value));
610 argument_value = new TempValue(index++); 610 argument_value = new TempVal(index++);
611 } 611 }
612 values->Add(argument_value); 612 values->Add(argument_value);
613 } 613 }
614 } 614 }
615 615
616 // <Expression> ::= StaticCall { function: Function 616 // <Expression> ::= StaticCall { function: Function
617 // arguments: <ArgumentList> } 617 // arguments: <ArgumentList> }
618 StaticCallComp* EffectGraphVisitor::TranslateStaticCall( 618 StaticCallComp* EffectGraphVisitor::TranslateStaticCall(
619 const StaticCallNode& node) { 619 const StaticCallNode& node) {
620 int length = node.arguments()->length(); 620 int length = node.arguments()->length();
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after
917 } 917 }
918 void ValueGraphVisitor::VisitInlinedFinallyNode(InlinedFinallyNode* node) { 918 void ValueGraphVisitor::VisitInlinedFinallyNode(InlinedFinallyNode* node) {
919 Bailout("ValueGraphVisitor::VisitInlinedFinallyNode"); 919 Bailout("ValueGraphVisitor::VisitInlinedFinallyNode");
920 } 920 }
921 void TestGraphVisitor::VisitInlinedFinallyNode(InlinedFinallyNode* node) { 921 void TestGraphVisitor::VisitInlinedFinallyNode(InlinedFinallyNode* node) {
922 Bailout("TestGraphVisitor::VisitInlinedFinallyNode"); 922 Bailout("TestGraphVisitor::VisitInlinedFinallyNode");
923 } 923 }
924 924
925 925
926 // Graph printing. 926 // Graph printing.
927 class FlowGraphPrinter : public InstructionVisitor { 927 class FlowGraphPrinter : public FlowGraphVisitor {
928 public: 928 public:
929 explicit FlowGraphPrinter(const Function& function) : function_(function) { } 929 explicit FlowGraphPrinter(const Function& function) : function_(function) { }
930 930
931 virtual ~FlowGraphPrinter() {} 931 virtual ~FlowGraphPrinter() {}
932 932
933 // Print the instructions in a block terminated by newlines. Add "goto N" 933 // Print the instructions in a block terminated by newlines. Add "goto N"
934 // to the end of the block if it ends with an unconditional jump to 934 // to the end of the block if it ends with an unconditional jump to
935 // another block and that block is not next in reverse postorder. 935 // another block and that block is not next in reverse postorder.
936 void VisitBlocks(const GrowableArray<BlockEntryInstr*>& block_order); 936 void VisitBlocks(const GrowableArray<BlockEntryInstr*>& block_order);
937 937
938 // Each visit function prints an instruction with a four space 938 // Visiting a computation prints it with no indentation or newline.
939 // indent and no trailing newline. Basic block entries are labeled 939 #define DECLARE_VISIT_COMPUTATION(ShortName, ClassName) \
940 // with their block number. 940 virtual void Visit##ShortName(ClassName* comp);
941 #define DECLARE_VISIT(type) \ 941
942 // Visiting an intstruction prints it with a four space indent and no
943 // trailing newline. Basic block entries are labeled with their block
944 // number.
945 #define DECLARE_VISIT_INSTRUCTION(type) \
942 virtual void Visit##type(type##Instr* instr); 946 virtual void Visit##type(type##Instr* instr);
943 FOR_EACH_INSTRUCTION(DECLARE_VISIT) 947
944 #undef DECLARE_VISIT 948 FOR_EACH_COMPUTATION(DECLARE_VISIT_COMPUTATION)
949 FOR_EACH_INSTRUCTION(DECLARE_VISIT_INSTRUCTION)
950
951 #undef DECLARE_VISIT_COMPUTATION
952 #undef DECLARE_VISIT_INSTRUCTION
945 953
946 private: 954 private:
947 const Function& function_; 955 const Function& function_;
948 956
949 DISALLOW_COPY_AND_ASSIGN(FlowGraphPrinter); 957 DISALLOW_COPY_AND_ASSIGN(FlowGraphPrinter);
950 }; 958 };
951 959
952 960
953 void FlowGraphPrinter::VisitBlocks( 961 void FlowGraphPrinter::VisitBlocks(
954 const GrowableArray<BlockEntryInstr*>& block_order) { 962 const GrowableArray<BlockEntryInstr*>& block_order) {
955 OS::Print("==== %s\n", function_.ToFullyQualifiedCString()); 963 OS::Print("==== %s\n", function_.ToFullyQualifiedCString());
956 964
957 for (intptr_t i = block_order.length() - 1; i >= 0; --i) { 965 for (intptr_t i = block_order.length() - 1; i >= 0; --i) {
958 // Print the block entry. 966 // Print the block entry.
959 Instruction* current = block_order[i]->Accept(this); 967 Instruction* current = block_order[i]->Accept(this);
960 // And all the successors until an exit, branch, or a block entry. 968 // And all the successors until an exit, branch, or a block entry.
961 while ((current != NULL) && !current->IsBlockEntry()) { 969 while ((current != NULL) && !current->IsBlockEntry()) {
962 OS::Print("\n"); 970 OS::Print("\n");
963 current = current->Accept(this); 971 current = current->Accept(this);
964 } 972 }
965 if ((current != NULL) && current->IsBlockEntry()) { 973 if ((current != NULL) && current->IsBlockEntry()) {
966 OS::Print(" goto %d", BlockEntryInstr::cast(current)->block_number()); 974 OS::Print(" goto %d", BlockEntryInstr::cast(current)->block_number());
967 } 975 }
968 OS::Print("\n"); 976 OS::Print("\n");
969 } 977 }
970 } 978 }
971 979
972 980
981 void FlowGraphPrinter::VisitTemp(TempVal* val) {
982 OS::Print("t%d", val->index());
983 }
984
985
986 void FlowGraphPrinter::VisitConstant(ConstantVal* val) {
987 OS::Print("#%s", val->instance().ToCString());
988 }
989
990
991 void FlowGraphPrinter::VisitAssertAssignable(AssertAssignableComp* comp) {
992 OS::Print("AssertAssignable(");
993 comp->value()->Accept(this);
994 OS::Print(", %s)", comp->type().ToCString());
995 }
996
997
998 void FlowGraphPrinter::VisitInstanceCall(InstanceCallComp* comp) {
999 OS::Print("InstanceCall(%s", comp->name());
1000 for (int i = 0; i < comp->ArgumentCount(); ++i) {
1001 OS::Print(", ");
1002 comp->ArgumentAt(i)->Accept(this);
1003 }
1004 OS::Print(")");
1005 }
1006
1007
1008 void FlowGraphPrinter::VisitStrictCompare(StrictCompareComp* comp) {
1009 OS::Print("StrictCompare(%s, ", Token::Str(comp->kind()));
1010 comp->left()->Accept(this);
1011 OS::Print(", ");
1012 comp->right()->Accept(this);
1013 OS::Print(")");
1014 }
1015
1016
1017
1018 void FlowGraphPrinter::VisitStaticCall(StaticCallComp* comp) {
1019 OS::Print("StaticCall(%s",
1020 String::Handle(comp->function().name()).ToCString());
1021 for (int i = 0; i < comp->ArgumentCount(); ++i) {
1022 OS::Print(", ");
1023 comp->ArgumentAt(i)->Accept(this);
1024 }
1025 OS::Print(")");
1026 }
1027
1028
1029 void FlowGraphPrinter::VisitLoadLocal(LoadLocalComp* comp) {
1030 OS::Print("LoadLocal(%s)", comp->local().name().ToCString());
1031 }
1032
1033
1034 void FlowGraphPrinter::VisitStoreLocal(StoreLocalComp* comp) {
1035 OS::Print("StoreLocal(%s, ", comp->local().name().ToCString());
1036 comp->value()->Accept(this);
1037 OS::Print(")");
1038 }
1039
1040
973 void FlowGraphPrinter::VisitJoinEntry(JoinEntryInstr* instr) { 1041 void FlowGraphPrinter::VisitJoinEntry(JoinEntryInstr* instr) {
974 OS::Print("%2d: [join]", instr->block_number()); 1042 OS::Print("%2d: [join]", instr->block_number());
975 } 1043 }
976 1044
977 1045
978 void FlowGraphPrinter::VisitTargetEntry(TargetEntryInstr* instr) { 1046 void FlowGraphPrinter::VisitTargetEntry(TargetEntryInstr* instr) {
979 OS::Print("%2d: [target]", instr->block_number()); 1047 OS::Print("%2d: [target]", instr->block_number());
980 } 1048 }
981 1049
982 1050
983 void FlowGraphPrinter::VisitDo(DoInstr* instr) { 1051 void FlowGraphPrinter::VisitDo(DoInstr* instr) {
984 OS::Print(" "); 1052 OS::Print(" ");
985 instr->computation()->Print(); 1053 instr->computation()->Accept(this);
986 } 1054 }
987 1055
988 1056
989 void FlowGraphPrinter::VisitBind(BindInstr* instr) { 1057 void FlowGraphPrinter::VisitBind(BindInstr* instr) {
990 OS::Print(" t%d <-", instr->temp_index()); 1058 OS::Print(" t%d <-", instr->temp_index());
991 instr->computation()->Print(); 1059 instr->computation()->Accept(this);
992 } 1060 }
993 1061
994 1062
995 void FlowGraphPrinter::VisitReturn(ReturnInstr* instr) { 1063 void FlowGraphPrinter::VisitReturn(ReturnInstr* instr) {
996 OS::Print(" return "); 1064 OS::Print(" return ");
997 instr->value()->Print(); 1065 instr->value()->Accept(this);
998 } 1066 }
999 1067
1000 1068
1001 void FlowGraphPrinter::VisitBranch(BranchInstr* instr) { 1069 void FlowGraphPrinter::VisitBranch(BranchInstr* instr) {
1002 OS::Print(" if "); 1070 OS::Print(" if ");
1003 instr->value()->Print(); 1071 instr->value()->Accept(this);
1004 OS::Print(" goto(%d, %d)", instr->true_successor()->block_number(), 1072 OS::Print(" goto(%d, %d)", instr->true_successor()->block_number(),
1005 instr->false_successor()->block_number()); 1073 instr->false_successor()->block_number());
1006 } 1074 }
1007 1075
1008 1076
1009 void FlowGraphBuilder::BuildGraph() { 1077 void FlowGraphBuilder::BuildGraph() {
1010 EffectGraphVisitor for_effect(this, 0); 1078 EffectGraphVisitor for_effect(this, 0);
1011 for_effect.AddInstruction(new TargetEntryInstr()); 1079 for_effect.AddInstruction(new TargetEntryInstr());
1012 parsed_function().node_sequence()->Visit(&for_effect); 1080 parsed_function().node_sequence()->Visit(&for_effect);
1013 if (for_effect.entry() != NULL) { 1081 if (for_effect.entry() != NULL) {
(...skipping 18 matching lines...) Expand all
1032 char* chars = reinterpret_cast<char*>( 1100 char* chars = reinterpret_cast<char*>(
1033 Isolate::Current()->current_zone()->Allocate(len)); 1101 Isolate::Current()->current_zone()->Allocate(len));
1034 OS::SNPrint(chars, len, kFormat, reason); 1102 OS::SNPrint(chars, len, kFormat, reason);
1035 const Error& error = Error::Handle( 1103 const Error& error = Error::Handle(
1036 LanguageError::New(String::Handle(String::New(chars)))); 1104 LanguageError::New(String::Handle(String::New(chars))));
1037 Isolate::Current()->long_jump_base()->Jump(1, error); 1105 Isolate::Current()->long_jump_base()->Jump(1, error);
1038 } 1106 }
1039 1107
1040 1108
1041 } // namespace dart 1109 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698