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

Side by Side Diff: vm/flow_graph_builder.cc

Issue 10693048: Revert r9253 because of dartium test failures (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/runtime/
Patch Set: Created 8 years, 5 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 | « vm/flow_graph_builder.h ('k') | vm/flow_graph_compiler.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_builder.h" 5 #include "vm/flow_graph_builder.h"
6 6
7 #include "vm/ast_printer.h" 7 #include "vm/ast_printer.h"
8 #include "vm/bit_vector.h" 8 #include "vm/bit_vector.h"
9 #include "vm/code_descriptors.h" 9 #include "vm/code_descriptors.h"
10 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
44 } 44 }
45 45
46 46
47 void EffectGraphVisitor::Append(const EffectGraphVisitor& other_fragment) { 47 void EffectGraphVisitor::Append(const EffectGraphVisitor& other_fragment) {
48 ASSERT(is_open()); 48 ASSERT(is_open());
49 if (other_fragment.is_empty()) return; 49 if (other_fragment.is_empty()) return;
50 if (is_empty()) { 50 if (is_empty()) {
51 entry_ = other_fragment.entry(); 51 entry_ = other_fragment.entry();
52 exit_ = other_fragment.exit(); 52 exit_ = other_fragment.exit();
53 } else { 53 } else {
54 Instruction* successor = other_fragment.entry(); 54 exit()->SetSuccessor(other_fragment.entry());
55 exit()->SetSuccessor(successor->IsBlockEntry()
56 ? new GotoInstr(successor->AsBlockEntry())
57 : successor);
58 exit_ = other_fragment.exit(); 55 exit_ = other_fragment.exit();
59 } 56 }
60 temp_index_ = other_fragment.temp_index(); 57 temp_index_ = other_fragment.temp_index();
61 } 58 }
62 59
63 60
64 void EffectGraphVisitor::AddInstruction(Instruction* instruction) { 61 void EffectGraphVisitor::AddInstruction(Instruction* instruction) {
65 ASSERT(is_open()); 62 ASSERT(is_open());
66 ASSERT(!instruction->IsBlockEntry());
67 DeallocateTempIndex(instruction->InputCount()); 63 DeallocateTempIndex(instruction->InputCount());
68 if (instruction->IsDefinition()) { 64 if (instruction->IsDefinition()) {
69 instruction->AsDefinition()->set_temp_index(AllocateTempIndex()); 65 instruction->AsDefinition()->set_temp_index(AllocateTempIndex());
70 } 66 }
71 if (is_empty()) { 67 if (is_empty()) {
72 entry_ = exit_ = instruction; 68 entry_ = exit_ = instruction;
73 } else { 69 } else {
74 exit()->SetSuccessor(instruction); 70 exit()->SetSuccessor(instruction);
75 exit_ = instruction; 71 exit_ = instruction;
76 } 72 }
77 } 73 }
78 74
79 75
80 void EffectGraphVisitor::AddBlockEntry(BlockEntryInstr* instruction) {
81 ASSERT(is_open());
82 if (is_empty()) {
83 entry_ = exit_ = instruction;
84 } else {
85 ASSERT(exit()->IsGraphEntry() ||
86 exit()->IsGoto());
87 exit()->SetSuccessor(instruction);
88 exit_ = instruction;
89 }
90 }
91
92
93 void EffectGraphVisitor::Join(const TestGraphVisitor& test_fragment, 76 void EffectGraphVisitor::Join(const TestGraphVisitor& test_fragment,
94 const EffectGraphVisitor& true_fragment, 77 const EffectGraphVisitor& true_fragment,
95 const EffectGraphVisitor& false_fragment) { 78 const EffectGraphVisitor& false_fragment) {
96 // We have: a test graph fragment with zero, one, or two available exits; 79 // We have: a test graph fragment with zero, one, or two available exits;
97 // and a pair of effect graph fragments with zero or one available exits. 80 // and a pair of effect graph fragments with zero or one available exits.
98 // We want to append the branch and (if necessary) a join node to this 81 // We want to append the branch and (if necessary) a join node to this
99 // graph fragment. 82 // graph fragment.
100 ASSERT(is_open()); 83 ASSERT(is_open());
101 84
102 // 1. Connect the test to this graph. 85 // 1. Connect the test to this graph.
(...skipping 15 matching lines...) Expand all
118 101
119 // 3. Add a join or select one (or neither) of the arms as exit. 102 // 3. Add a join or select one (or neither) of the arms as exit.
120 if (true_exit == NULL) { 103 if (true_exit == NULL) {
121 exit_ = false_exit; // May be NULL. 104 exit_ = false_exit; // May be NULL.
122 if (false_exit != NULL) temp_index_ = false_fragment.temp_index(); 105 if (false_exit != NULL) temp_index_ = false_fragment.temp_index();
123 } else if (false_exit == NULL) { 106 } else if (false_exit == NULL) {
124 exit_ = true_exit; 107 exit_ = true_exit;
125 temp_index_ = true_fragment.temp_index(); 108 temp_index_ = true_fragment.temp_index();
126 } else { 109 } else {
127 exit_ = new JoinEntryInstr(); 110 exit_ = new JoinEntryInstr();
128 true_exit->SetSuccessor(new GotoInstr(exit_->AsBlockEntry())); 111 true_exit->SetSuccessor(exit_);
129 false_exit->SetSuccessor(new GotoInstr(exit_->AsBlockEntry())); 112 false_exit->SetSuccessor(exit_);
130 ASSERT(true_fragment.temp_index() == false_fragment.temp_index()); 113 ASSERT(true_fragment.temp_index() == false_fragment.temp_index());
131 temp_index_ = true_fragment.temp_index(); 114 temp_index_ = true_fragment.temp_index();
132 } 115 }
133 } 116 }
134 117
135 118
136 void EffectGraphVisitor::TieLoop(const TestGraphVisitor& test_fragment, 119 void EffectGraphVisitor::TieLoop(const TestGraphVisitor& test_fragment,
137 const EffectGraphVisitor& body_fragment) { 120 const EffectGraphVisitor& body_fragment) {
138 // We have: a test graph fragment with zero, one, or two available exits; 121 // We have: a test graph fragment with zero, one, or two available exits;
139 // and an effect graph fragment with zero or one available exits. We want 122 // and an effect graph fragment with zero or one available exits. We want
140 // to append the 'while loop' consisting of the test graph fragment as 123 // to append the 'while loop' consisting of the test graph fragment as
141 // condition and the effect graph fragment as body. 124 // condition and the effect graph fragment as body.
142 ASSERT(is_open()); 125 ASSERT(is_open());
143 126
144 // 1. Connect the body to the test if it is reachable, and if so record 127 // 1. Connect the body to the test if it is reachable, and if so record
145 // its exit (if any). 128 // its exit (if any).
146 Instruction* body_exit = NULL; 129 Instruction* body_exit = NULL;
147 TargetEntryInstr* body_entry = new TargetEntryInstr(); 130 TargetEntryInstr* body_entry = new TargetEntryInstr();
148 *test_fragment.true_successor_address() = body_entry; 131 *test_fragment.true_successor_address() = body_entry;
149 body_entry->SetSuccessor(body_fragment.entry()); 132 body_entry->SetSuccessor(body_fragment.entry());
150 body_exit = body_fragment.is_empty() ? body_entry : body_fragment.exit(); 133 body_exit = body_fragment.is_empty() ? body_entry : body_fragment.exit();
151 134
152 // 2. Connect the test to this graph, including the body if reachable and 135 // 2. Connect the test to this graph, including the body if reachable and
153 // using a fresh join node if the body is reachable and has an open exit. 136 // using a fresh join node if the body is reachable and has an open exit.
154 if (body_exit == NULL) { 137 if (body_exit == NULL) {
155 Append(test_fragment); 138 Append(test_fragment);
156 } else { 139 } else {
157 JoinEntryInstr* join = new JoinEntryInstr(); 140 JoinEntryInstr* join = new JoinEntryInstr();
158 AddInstruction(new GotoInstr(join)); 141 AddInstruction(join);
159 AddBlockEntry(join);
160 join->SetSuccessor(test_fragment.entry()); 142 join->SetSuccessor(test_fragment.entry());
161 body_exit->SetSuccessor(new GotoInstr(join)); 143 body_exit->SetSuccessor(join);
162 } 144 }
163 145
164 // 3. Set the exit to the graph to be the false successor of the test, a 146 // 3. Set the exit to the graph to be the false successor of the test, a
165 // fresh target node 147 // fresh target node
166 exit_ = *test_fragment.false_successor_address() = new TargetEntryInstr(); 148 exit_ = *test_fragment.false_successor_address() = new TargetEntryInstr();
167 } 149 }
168 150
169 151
170 Computation* EffectGraphVisitor::BuildStoreLocal( 152 Computation* EffectGraphVisitor::BuildStoreLocal(
171 const LocalVariable& local, Value* value) { 153 const LocalVariable& local, Value* value) {
(...skipping 802 matching lines...) Expand 10 before | Expand all | Expand 10 after
974 Join(for_test, for_true, for_false); 956 Join(for_test, for_true, for_false);
975 } 957 }
976 958
977 959
978 void EffectGraphVisitor::VisitSwitchNode(SwitchNode* node) { 960 void EffectGraphVisitor::VisitSwitchNode(SwitchNode* node) {
979 EffectGraphVisitor switch_body(owner(), temp_index()); 961 EffectGraphVisitor switch_body(owner(), temp_index());
980 node->body()->Visit(&switch_body); 962 node->body()->Visit(&switch_body);
981 Append(switch_body); 963 Append(switch_body);
982 if ((node->label() != NULL) && (node->label()->join_for_break() != NULL)) { 964 if ((node->label() != NULL) && (node->label()->join_for_break() != NULL)) {
983 if (is_open()) { 965 if (is_open()) {
984 AddInstruction(new GotoInstr(node->label()->join_for_break())); 966 AddInstruction(node->label()->join_for_break());
985 AddBlockEntry(node->label()->join_for_break());
986 } else { 967 } else {
987 exit_ = node->label()->join_for_break(); 968 exit_ = node->label()->join_for_break();
988 } 969 }
989 } 970 }
990 // No continue label allowed. 971 // No continue label allowed.
991 ASSERT((node->label() == NULL) || 972 ASSERT((node->label() == NULL) ||
992 (node->label()->join_for_continue() == NULL)); 973 (node->label()->join_for_continue() == NULL));
993 } 974 }
994 975
995 976
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1027 // allocate JoinNode here and use it as statement start. 1008 // allocate JoinNode here and use it as statement start.
1028 if (node->label()->join_for_continue() == NULL) { 1009 if (node->label()->join_for_continue() == NULL) {
1029 node->label()->set_join_for_continue(new JoinEntryInstr()); 1010 node->label()->set_join_for_continue(new JoinEntryInstr());
1030 } 1011 }
1031 statement_start = node->label()->join_for_continue(); 1012 statement_start = node->label()->join_for_continue();
1032 } else if (needs_join_at_statement_entry) { 1013 } else if (needs_join_at_statement_entry) {
1033 statement_start = new JoinEntryInstr(); 1014 statement_start = new JoinEntryInstr();
1034 } else { 1015 } else {
1035 statement_start = new TargetEntryInstr(); 1016 statement_start = new TargetEntryInstr();
1036 } 1017 }
1037 for_case_statements.AddBlockEntry(statement_start); 1018 for_case_statements.AddInstruction(statement_start);
1038 node->statements()->Visit(&for_case_statements); 1019 node->statements()->Visit(&for_case_statements);
1039 if (is_open() && (len == 0)) { 1020 if (is_open() && (len == 0)) {
1040 ASSERT(node->contains_default()); 1021 ASSERT(node->contains_default());
1041 // Default only case node. 1022 // Default only case node.
1042 Append(for_case_statements); 1023 Append(for_case_statements);
1043 return; 1024 return;
1044 } 1025 }
1045 1026
1046 // Generate instructions for all case expressions and collect data to 1027 // Generate instructions for all case expressions and collect data to
1047 // connect them. 1028 // connect them.
1048 GrowableArray<TargetEntryInstr**> case_true_addresses; 1029 GrowableArray<TargetEntryInstr**> case_true_addresses;
1049 GrowableArray<TargetEntryInstr**> case_false_addresses; 1030 GrowableArray<TargetEntryInstr**> case_false_addresses;
1050 GrowableArray<TargetEntryInstr*> case_entries; 1031 GrowableArray<TargetEntryInstr*> case_entries;
1051 for (intptr_t i = 0; i < len; i++) { 1032 for (intptr_t i = 0; i < len; i++) {
1052 AstNode* case_expr = node->case_expressions()->NodeAt(i); 1033 AstNode* case_expr = node->case_expressions()->NodeAt(i);
1053 TestGraphVisitor for_case_expression(owner(), 1034 TestGraphVisitor for_case_expression(owner(),
1054 temp_index(), 1035 temp_index(),
1055 case_expr->token_pos()); 1036 case_expr->token_pos());
1056 if (i == 0) { 1037 if (i == 0) {
1057 case_entries.Add(NULL); // Not to be used 1038 case_entries.Add(NULL); // Not to be used
1058 case_expr->Visit(&for_case_expression); 1039 case_expr->Visit(&for_case_expression);
1059 // Append only the first one, everything else is connected from it. 1040 // Append only the first one, everything else is connected from it.
1060 Append(for_case_expression); 1041 Append(for_case_expression);
1061 } else { 1042 } else {
1062 TargetEntryInstr* case_entry_target = new TargetEntryInstr(); 1043 TargetEntryInstr* case_entry_target = new TargetEntryInstr();
1063 case_entries.Add(case_entry_target); 1044 case_entries.Add(case_entry_target);
1064 for_case_expression.AddBlockEntry(case_entry_target); 1045 for_case_expression.AddInstruction(case_entry_target);
1065 case_expr->Visit(&for_case_expression); 1046 case_expr->Visit(&for_case_expression);
1066 } 1047 }
1067 case_true_addresses.Add(for_case_expression.true_successor_address()); 1048 case_true_addresses.Add(for_case_expression.true_successor_address());
1068 case_false_addresses.Add(for_case_expression.false_successor_address()); 1049 case_false_addresses.Add(for_case_expression.false_successor_address());
1069 } 1050 }
1070 1051
1071 // Once a test fragment has been added, this fragment is closed. 1052 // Once a test fragment has been added, this fragment is closed.
1072 ASSERT(!is_open()); 1053 ASSERT(!is_open());
1073 1054
1074 // Connect all test cases except the last one. 1055 // Connect all test cases except the last one.
1075 for (intptr_t i = 0; i < (len - 1); i++) { 1056 for (intptr_t i = 0; i < (len - 1); i++) {
1076 ASSERT(needs_join_at_statement_entry); 1057 ASSERT(needs_join_at_statement_entry);
1077 *case_false_addresses[i] = case_entries[i + 1]; 1058 *case_false_addresses[i] = case_entries[i + 1];
1078 TargetEntryInstr* true_target = new TargetEntryInstr(); 1059 TargetEntryInstr* true_target = new TargetEntryInstr();
1079 *case_true_addresses[i] = true_target; 1060 *case_true_addresses[i] = true_target;
1080 true_target->SetSuccessor(new GotoInstr(statement_start)); 1061 true_target->SetSuccessor(statement_start);
1081 } 1062 }
1082 1063
1083 BlockEntryInstr* exit_instruction = NULL; 1064 BlockEntryInstr* exit_instruction = NULL;
1084 // Handle last (or only) case: false goes to exit or to statement if this 1065 // Handle last (or only) case: false goes to exit or to statement if this
1085 // node contains default. 1066 // node contains default.
1086 if (len > 0) { 1067 if (len > 0) {
1087 if (statement_start->IsTargetEntry()) { 1068 if (statement_start->IsTargetEntry()) {
1088 *case_true_addresses[len - 1] = statement_start->AsTargetEntry(); 1069 *case_true_addresses[len - 1] = statement_start->AsTargetEntry();
1089 } else { 1070 } else {
1090 TargetEntryInstr* true_target = new TargetEntryInstr(); 1071 TargetEntryInstr* true_target = new TargetEntryInstr();
1091 *case_true_addresses[len - 1] = true_target; 1072 *case_true_addresses[len - 1] = true_target;
1092 true_target->SetSuccessor(new GotoInstr(statement_start)); 1073 true_target->SetSuccessor(statement_start);
1093 } 1074 }
1094 TargetEntryInstr* false_target = new TargetEntryInstr(); 1075 TargetEntryInstr* false_target = new TargetEntryInstr();
1095 *case_false_addresses[len - 1] = false_target; 1076 *case_false_addresses[len - 1] = false_target;
1096 if (node->contains_default()) { 1077 if (node->contains_default()) {
1097 // True and false go to statement start. 1078 // True and false go to statement start.
1098 false_target->SetSuccessor(new GotoInstr(statement_start)); 1079 false_target->SetSuccessor(statement_start);
1099 if (for_case_statements.is_open()) { 1080 if (for_case_statements.is_open()) {
1100 exit_instruction = new TargetEntryInstr(); 1081 exit_instruction = new TargetEntryInstr();
1101 for_case_statements.exit()->SetSuccessor( 1082 for_case_statements.exit()->SetSuccessor(exit_instruction);
1102 new GotoInstr(exit_instruction));
1103 } 1083 }
1104 } else { 1084 } else {
1105 if (for_case_statements.is_open()) { 1085 if (for_case_statements.is_open()) {
1106 exit_instruction = new JoinEntryInstr(); 1086 exit_instruction = new JoinEntryInstr();
1107 for_case_statements.exit()->SetSuccessor( 1087 for_case_statements.exit()->SetSuccessor(exit_instruction);
1108 new GotoInstr(exit_instruction));
1109 } else { 1088 } else {
1110 exit_instruction = new TargetEntryInstr(); 1089 exit_instruction = new TargetEntryInstr();
1111 } 1090 }
1112 false_target->SetSuccessor(new GotoInstr(exit_instruction)); 1091 false_target->SetSuccessor(exit_instruction);
1113 } 1092 }
1114 } else { 1093 } else {
1115 // A CaseNode without case expressions must contain default. 1094 // A CaseNode without case expressions must contain default.
1116 ASSERT(node->contains_default()); 1095 ASSERT(node->contains_default());
1117 AddInstruction(new GotoInstr(statement_start)); 1096 AddInstruction(statement_start);
1118 AddBlockEntry(statement_start);
1119 } 1097 }
1120 1098
1121 ASSERT(!is_open()); 1099 ASSERT(!is_open());
1122 exit_ = exit_instruction; 1100 exit_ = exit_instruction;
1123 } 1101 }
1124 1102
1125 1103
1126 // <Statement> ::= While { label: SourceLabel 1104 // <Statement> ::= While { label: SourceLabel
1127 // condition: <Expression> 1105 // condition: <Expression>
1128 // body: <Sequence> } 1106 // body: <Sequence> }
(...skipping 15 matching lines...) Expand all
1144 EffectGraphVisitor for_body(owner(), temp_index()); 1122 EffectGraphVisitor for_body(owner(), temp_index());
1145 CheckStackOverflowComp* comp = 1123 CheckStackOverflowComp* comp =
1146 new CheckStackOverflowComp(node->token_pos(), owner()->try_index()); 1124 new CheckStackOverflowComp(node->token_pos(), owner()->try_index());
1147 for_body.AddInstruction(new DoInstr(comp)); 1125 for_body.AddInstruction(new DoInstr(comp));
1148 node->body()->Visit(&for_body); 1126 node->body()->Visit(&for_body);
1149 1127
1150 // Labels are set after body traversal. 1128 // Labels are set after body traversal.
1151 SourceLabel* lbl = node->label(); 1129 SourceLabel* lbl = node->label();
1152 ASSERT(lbl != NULL); 1130 ASSERT(lbl != NULL);
1153 if (lbl->join_for_continue() != NULL) { 1131 if (lbl->join_for_continue() != NULL) {
1154 AddInstruction(new GotoInstr(lbl->join_for_continue())); 1132 AddInstruction(lbl->join_for_continue());
1155 AddBlockEntry(lbl->join_for_continue());
1156 } 1133 }
1157 TieLoop(for_test, for_body); 1134 TieLoop(for_test, for_body);
1158 if (lbl->join_for_break() != NULL) { 1135 if (lbl->join_for_break() != NULL) {
1159 AddInstruction(new GotoInstr(lbl->join_for_break())); 1136 AddInstruction(lbl->join_for_break());
1160 AddBlockEntry(lbl->join_for_break());
1161 } 1137 }
1162 } 1138 }
1163 1139
1164 1140
1165 // The fragment is composed as follows: 1141 // The fragment is composed as follows:
1166 // a) body-entry-join 1142 // a) body-entry-join
1167 // b) [ body ] 1143 // b) [ body ]
1168 // c) test-entry (continue-join or body-exit-target) 1144 // c) test-entry (continue-join or body-exit-target)
1169 // d) [ test-entry ] -> (back-target, loop-exit-target) 1145 // d) [ test-entry ] -> (back-target, loop-exit-target)
1170 // e) back-target -> (body-entry-join) 1146 // e) back-target -> (body-entry-join)
1171 // f) loop-exit-target 1147 // f) loop-exit-target
1172 // g) break-join 1148 // g) break-join
1173 void EffectGraphVisitor::VisitDoWhileNode(DoWhileNode* node) { 1149 void EffectGraphVisitor::VisitDoWhileNode(DoWhileNode* node) {
1174 // Traverse body first in order to generate continue and break labels. 1150 // Traverse body first in order to generate continue and break labels.
1175 EffectGraphVisitor for_body(owner(), temp_index()); 1151 EffectGraphVisitor for_body(owner(), temp_index());
1176 CheckStackOverflowComp* comp = 1152 CheckStackOverflowComp* comp =
1177 new CheckStackOverflowComp(node->token_pos(), owner()->try_index()); 1153 new CheckStackOverflowComp(node->token_pos(), owner()->try_index());
1178 for_body.AddInstruction(new DoInstr(comp)); 1154 for_body.AddInstruction(new DoInstr(comp));
1179 node->body()->Visit(&for_body); 1155 node->body()->Visit(&for_body);
1180 1156
1181 TestGraphVisitor for_test(owner(), 1157 TestGraphVisitor for_test(owner(),
1182 temp_index(), 1158 temp_index(),
1183 node->condition()->token_pos()); 1159 node->condition()->token_pos());
1184 node->condition()->Visit(&for_test); 1160 node->condition()->Visit(&for_test);
1185 ASSERT(is_open()); 1161 ASSERT(is_open());
1186 1162
1187 // Tie do-while loop (test is after the body). 1163 // Tie do-while loop (test is after the body).
1188 JoinEntryInstr* body_entry_join = new JoinEntryInstr(); 1164 JoinEntryInstr* body_entry_join = new JoinEntryInstr();
1189 AddInstruction(new GotoInstr(body_entry_join)); 1165 AddInstruction(body_entry_join);
1190 AddBlockEntry(body_entry_join);
1191 body_entry_join->SetSuccessor(for_body.entry()); 1166 body_entry_join->SetSuccessor(for_body.entry());
1192 Instruction* body_exit = 1167 Instruction* body_exit =
1193 for_body.is_empty() ? body_entry_join : for_body.exit(); 1168 for_body.is_empty() ? body_entry_join : for_body.exit();
1194 1169
1195 if (for_body.is_open() || (node->label()->join_for_continue() != NULL)) { 1170 if (for_body.is_open() || (node->label()->join_for_continue() != NULL)) {
1196 BlockEntryInstr* test_entry = NULL; 1171 BlockEntryInstr* test_entry = NULL;
1197 if (node->label()->join_for_continue() == NULL) { 1172 if (node->label()->join_for_continue() == NULL) {
1198 test_entry = new TargetEntryInstr(); 1173 test_entry = new TargetEntryInstr();
1199 } else { 1174 } else {
1200 test_entry = node->label()->join_for_continue(); 1175 test_entry = node->label()->join_for_continue();
1201 } 1176 }
1202 test_entry->SetSuccessor(for_test.entry()); 1177 test_entry->SetSuccessor(for_test.entry());
1203 if (body_exit != NULL) { 1178 if (body_exit != NULL) {
1204 body_exit->SetSuccessor(new GotoInstr(test_entry)); 1179 body_exit->SetSuccessor(test_entry);
1205 } 1180 }
1206 } 1181 }
1207 1182
1208 TargetEntryInstr* back_target_entry = new TargetEntryInstr(); 1183 TargetEntryInstr* back_target_entry = new TargetEntryInstr();
1209 *for_test.true_successor_address() = back_target_entry; 1184 *for_test.true_successor_address() = back_target_entry;
1210 back_target_entry->SetSuccessor(new GotoInstr(body_entry_join)); 1185 back_target_entry->SetSuccessor(body_entry_join);
1211 TargetEntryInstr* loop_exit_target = new TargetEntryInstr(); 1186 TargetEntryInstr* loop_exit_target = new TargetEntryInstr();
1212 *for_test.false_successor_address() = loop_exit_target; 1187 *for_test.false_successor_address() = loop_exit_target;
1213 if (node->label()->join_for_break() == NULL) { 1188 if (node->label()->join_for_break() == NULL) {
1214 exit_ = loop_exit_target; 1189 exit_ = loop_exit_target;
1215 } else { 1190 } else {
1216 loop_exit_target->SetSuccessor( 1191 loop_exit_target->SetSuccessor(node->label()->join_for_break());
1217 new GotoInstr(node->label()->join_for_break()));
1218 exit_ = node->label()->join_for_break(); 1192 exit_ = node->label()->join_for_break();
1219 } 1193 }
1220 } 1194 }
1221 1195
1222 1196
1223 // A ForNode can contain break and continue jumps. 'break' joins to 1197 // A ForNode can contain break and continue jumps. 'break' joins to
1224 // ForNode exit, 'continue' joins at increment entry. The fragment is composed 1198 // ForNode exit, 'continue' joins at increment entry. The fragment is composed
1225 // as follows: 1199 // as follows:
1226 // a) [ initializer ] 1200 // a) [ initializer ]
1227 // b) loop-join 1201 // b) loop-join
1228 // c) [ test ] -> (body-entry-target, loop-exit-target) 1202 // c) [ test ] -> (body-entry-target, loop-exit-target)
1229 // d) body-entry-target 1203 // d) body-entry-target
1230 // e) [ body ] 1204 // e) [ body ]
1231 // f) continue-join (optional) 1205 // f) continue-join (optional)
1232 // g) [ increment ] -> (loop-join) 1206 // g) [ increment ] -> (loop-join)
1233 // h) loop-exit-target 1207 // h) loop-exit-target
1234 // i) break-join 1208 // i) break-join
1235 void EffectGraphVisitor::VisitForNode(ForNode* node) { 1209 void EffectGraphVisitor::VisitForNode(ForNode* node) {
1236 EffectGraphVisitor for_initializer(owner(), temp_index()); 1210 EffectGraphVisitor for_initializer(owner(), temp_index());
1237 node->initializer()->Visit(&for_initializer); 1211 node->initializer()->Visit(&for_initializer);
1238 Append(for_initializer); 1212 Append(for_initializer);
1239 ASSERT(is_open()); 1213 ASSERT(is_open());
1240 1214
1241 // Compose body to set any jump labels. 1215 // Compose body to set any jump labels.
1242 EffectGraphVisitor for_body(owner(), temp_index()); 1216 EffectGraphVisitor for_body(owner(), temp_index());
1243 TargetEntryInstr* body_entry = new TargetEntryInstr(); 1217 TargetEntryInstr* body_entry = new TargetEntryInstr();
1244 for_body.AddBlockEntry(body_entry); 1218 for_body.AddInstruction(body_entry);
1245 CheckStackOverflowComp* comp = 1219 CheckStackOverflowComp* comp =
1246 new CheckStackOverflowComp(node->token_pos(), owner()->try_index()); 1220 new CheckStackOverflowComp(node->token_pos(), owner()->try_index());
1247 for_body.AddInstruction(new DoInstr(comp)); 1221 for_body.AddInstruction(new DoInstr(comp));
1248 node->body()->Visit(&for_body); 1222 node->body()->Visit(&for_body);
1249 1223
1250 // Join loop body, increment and compute their end instruction. 1224 // Join loop body, increment and compute their end instruction.
1251 ASSERT(!for_body.is_empty()); 1225 ASSERT(!for_body.is_empty());
1252 Instruction* loop_increment_end = NULL; 1226 Instruction* loop_increment_end = NULL;
1253 EffectGraphVisitor for_increment(owner(), temp_index()); 1227 EffectGraphVisitor for_increment(owner(), temp_index());
1254 if ((node->label()->join_for_continue() == NULL) && for_body.is_open()) { 1228 if ((node->label()->join_for_continue() == NULL) && for_body.is_open()) {
1255 // Do not insert an extra basic block. 1229 // Do not insert an extra basic block.
1256 node->increment()->Visit(&for_increment); 1230 node->increment()->Visit(&for_increment);
1257 for_body.Append(for_increment); 1231 for_body.Append(for_increment);
1258 loop_increment_end = for_body.exit(); 1232 loop_increment_end = for_body.exit();
1259 // 'for_body' contains at least the TargetInstruction 'body_entry'. 1233 // 'for_body' contains at least the TargetInstruction 'body_entry'.
1260 ASSERT(loop_increment_end != NULL); 1234 ASSERT(loop_increment_end != NULL);
1261 } else if (node->label()->join_for_continue() != NULL) { 1235 } else if (node->label()->join_for_continue() != NULL) {
1262 // Insert join between body and increment. 1236 // Insert join between body and increment.
1263 if (for_body.is_open()) { 1237 if (for_body.is_open()) {
1264 for_body.exit()->SetSuccessor( 1238 for_body.exit()->SetSuccessor(node->label()->join_for_continue());
1265 new GotoInstr(node->label()->join_for_continue()));
1266 } 1239 }
1267 for_increment.AddBlockEntry(node->label()->join_for_continue()); 1240 for_increment.AddInstruction(node->label()->join_for_continue());
1268 node->increment()->Visit(&for_increment); 1241 node->increment()->Visit(&for_increment);
1269 loop_increment_end = for_increment.exit(); 1242 loop_increment_end = for_increment.exit();
1270 ASSERT(loop_increment_end != NULL); 1243 ASSERT(loop_increment_end != NULL);
1271 } else { 1244 } else {
1272 loop_increment_end = NULL; 1245 loop_increment_end = NULL;
1273 ASSERT(!for_body.is_open() && node->label()->join_for_continue() == NULL); 1246 ASSERT(!for_body.is_open() && node->label()->join_for_continue() == NULL);
1274 } 1247 }
1275 1248
1276 // 'loop_increment_end' is NULL only if there is no join for continue and the 1249 // 'loop_increment_end' is NULL only if there is no join for continue and the
1277 // body is not open, i.e., no backward branch exists. 1250 // body is not open, i.e., no backward branch exists.
1278 if (loop_increment_end != NULL) { 1251 if (loop_increment_end != NULL) {
1279 JoinEntryInstr* loop_start = new JoinEntryInstr(); 1252 JoinEntryInstr* loop_start = new JoinEntryInstr();
1280 AddInstruction(new GotoInstr(loop_start)); 1253 AddInstruction(loop_start);
1281 AddBlockEntry(loop_start); 1254 loop_increment_end->SetSuccessor(loop_start);
1282 loop_increment_end->SetSuccessor(new GotoInstr(loop_start));
1283 } 1255 }
1284 1256
1285 if (node->condition() == NULL) { 1257 if (node->condition() == NULL) {
1286 // Endless loop, no test. 1258 // Endless loop, no test.
1287 Append(for_body); 1259 Append(for_body);
1288 if (node->label()->join_for_break() == NULL) { 1260 if (node->label()->join_for_break() == NULL) {
1289 CloseFragment(); 1261 CloseFragment();
1290 } else { 1262 } else {
1291 // Control flow of ForLoop continues into join_for_break. 1263 // Control flow of ForLoop continues into join_for_break.
1292 exit_ = node->label()->join_for_break(); 1264 exit_ = node->label()->join_for_break();
1293 } 1265 }
1294 } else { 1266 } else {
1295 TargetEntryInstr* loop_exit = new TargetEntryInstr(); 1267 TargetEntryInstr* loop_exit = new TargetEntryInstr();
1296 TestGraphVisitor for_test(owner(), 1268 TestGraphVisitor for_test(owner(),
1297 temp_index(), 1269 temp_index(),
1298 node->condition()->token_pos()); 1270 node->condition()->token_pos());
1299 node->condition()->Visit(&for_test); 1271 node->condition()->Visit(&for_test);
1300 Append(for_test); 1272 Append(for_test);
1301 *for_test.true_successor_address() = body_entry; 1273 *for_test.true_successor_address() = body_entry;
1302 *for_test.false_successor_address() = loop_exit; 1274 *for_test.false_successor_address() = loop_exit;
1303 if (node->label()->join_for_break() == NULL) { 1275 if (node->label()->join_for_break() == NULL) {
1304 exit_ = loop_exit; 1276 exit_ = loop_exit;
1305 } else { 1277 } else {
1306 loop_exit->SetSuccessor(new GotoInstr(node->label()->join_for_break())); 1278 loop_exit->SetSuccessor(node->label()->join_for_break());
1307 exit_ = node->label()->join_for_break(); 1279 exit_ = node->label()->join_for_break();
1308 } 1280 }
1309 } 1281 }
1310 } 1282 }
1311 1283
1312 1284
1313 void EffectGraphVisitor::VisitJumpNode(JumpNode* node) { 1285 void EffectGraphVisitor::VisitJumpNode(JumpNode* node) {
1314 for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) { 1286 for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) {
1315 EffectGraphVisitor for_effect(owner(), temp_index()); 1287 EffectGraphVisitor for_effect(owner(), temp_index());
1316 node->InlinedFinallyNodeAt(i)->Visit(&for_effect); 1288 node->InlinedFinallyNodeAt(i)->Visit(&for_effect);
(...skipping 22 matching lines...) Expand all
1339 target_context_level = target_scope->context_level(); 1311 target_context_level = target_scope->context_level();
1340 } 1312 }
1341 } 1313 }
1342 ASSERT(target_context_level >= 0); 1314 ASSERT(target_context_level >= 0);
1343 intptr_t current_context_level = owner()->context_level(); 1315 intptr_t current_context_level = owner()->context_level();
1344 ASSERT(current_context_level >= target_context_level); 1316 ASSERT(current_context_level >= target_context_level);
1345 while (current_context_level-- > target_context_level) { 1317 while (current_context_level-- > target_context_level) {
1346 UnchainContext(); 1318 UnchainContext();
1347 } 1319 }
1348 1320
1349 BlockEntryInstr* jump_target = NULL; 1321 Instruction* jump_target = NULL;
1350 if (node->kind() == Token::kBREAK) { 1322 if (node->kind() == Token::kBREAK) {
1351 if (node->label()->join_for_break() == NULL) { 1323 if (node->label()->join_for_break() == NULL) {
1352 node->label()->set_join_for_break(new JoinEntryInstr()); 1324 node->label()->set_join_for_break(new JoinEntryInstr());
1353 } 1325 }
1354 jump_target = node->label()->join_for_break(); 1326 jump_target = node->label()->join_for_break();
1355 } else { 1327 } else {
1356 if (node->label()->join_for_continue() == NULL) { 1328 if (node->label()->join_for_continue() == NULL) {
1357 node->label()->set_join_for_continue(new JoinEntryInstr()); 1329 node->label()->set_join_for_continue(new JoinEntryInstr());
1358 } 1330 }
1359 jump_target = node->label()->join_for_continue(); 1331 jump_target = node->label()->join_for_continue();
1360 } 1332 }
1361 AddInstruction(new GotoInstr(jump_target)); 1333 AddInstruction(jump_target);
1362 AddBlockEntry(jump_target);
1363 CloseFragment(); 1334 CloseFragment();
1364 } 1335 }
1365 1336
1366 1337
1367 void EffectGraphVisitor::VisitArgumentListNode(ArgumentListNode* node) { 1338 void EffectGraphVisitor::VisitArgumentListNode(ArgumentListNode* node) {
1368 UNREACHABLE(); 1339 UNREACHABLE();
1369 } 1340 }
1370 1341
1371 1342
1372 void EffectGraphVisitor::VisitArrayNode(ArrayNode* node) { 1343 void EffectGraphVisitor::VisitArrayNode(ArrayNode* node) {
(...skipping 875 matching lines...) Expand 10 before | Expand all | Expand 10 after
2248 } 2219 }
2249 2220
2250 // No continue on sequence allowed. 2221 // No continue on sequence allowed.
2251 ASSERT((node->label() == NULL) || 2222 ASSERT((node->label() == NULL) ||
2252 (node->label()->join_for_continue() == NULL)); 2223 (node->label()->join_for_continue() == NULL));
2253 // If this node sequence is labeled, a break out of the sequence will have 2224 // If this node sequence is labeled, a break out of the sequence will have
2254 // taken care of unchaining the context. 2225 // taken care of unchaining the context.
2255 if ((node->label() != NULL) && 2226 if ((node->label() != NULL) &&
2256 (node->label()->join_for_break() != NULL)) { 2227 (node->label()->join_for_break() != NULL)) {
2257 if (is_open()) { 2228 if (is_open()) {
2258 AddInstruction(new GotoInstr(node->label()->join_for_break())); 2229 AddInstruction(node->label()->join_for_break());
2259 AddBlockEntry(node->label()->join_for_break());
2260 } else { 2230 } else {
2261 exit_ = node->label()->join_for_break(); 2231 exit_ = node->label()->join_for_break();
2262 } 2232 }
2263 } 2233 }
2264 2234
2265 // The outermost function sequence cannot contain a label. 2235 // The outermost function sequence cannot contain a label.
2266 ASSERT((node->label() == NULL) || 2236 ASSERT((node->label() == NULL) ||
2267 (node != owner()->parsed_function().node_sequence())); 2237 (node != owner()->parsed_function().node_sequence()));
2268 owner()->set_context_level(previous_context_level); 2238 owner()->set_context_level(previous_context_level);
2269 } 2239 }
(...skipping 30 matching lines...) Expand all
2300 owner()->set_try_index(old_try_index); 2270 owner()->set_try_index(old_try_index);
2301 2271
2302 CatchClauseNode* catch_block = node->catch_block(); 2272 CatchClauseNode* catch_block = node->catch_block();
2303 if (catch_block != NULL) { 2273 if (catch_block != NULL) {
2304 // Set the corresponding try index for this catch block so 2274 // Set the corresponding try index for this catch block so
2305 // that we can set the appropriate handler pc when we generate 2275 // that we can set the appropriate handler pc when we generate
2306 // code for this catch block. 2276 // code for this catch block.
2307 catch_block->set_try_index(try_index); 2277 catch_block->set_try_index(try_index);
2308 EffectGraphVisitor for_catch_block(owner(), temp_index()); 2278 EffectGraphVisitor for_catch_block(owner(), temp_index());
2309 TargetEntryInstr* catch_entry = new TargetEntryInstr(try_index); 2279 TargetEntryInstr* catch_entry = new TargetEntryInstr(try_index);
2310 for_catch_block.AddBlockEntry(catch_entry); 2280 for_catch_block.AddInstruction(catch_entry);
2311 catch_block->Visit(&for_catch_block); 2281 catch_block->Visit(&for_catch_block);
2312 owner()->AddCatchEntry(catch_entry); 2282 owner()->AddCatchEntry(catch_entry);
2313 ASSERT(!for_catch_block.is_open()); 2283 ASSERT(!for_catch_block.is_open());
2314 if ((node->end_catch_label() != NULL) && 2284 if ((node->end_catch_label() != NULL) &&
2315 (node->end_catch_label()->join_for_continue() != NULL)) { 2285 (node->end_catch_label()->join_for_continue() != NULL)) {
2316 if (is_open()) { 2286 if (is_open()) {
2317 AddInstruction( 2287 AddInstruction(node->end_catch_label()->join_for_continue());
2318 new GotoInstr(node->end_catch_label()->join_for_continue()));
2319 AddBlockEntry(node->end_catch_label()->join_for_continue());
2320 } else { 2288 } else {
2321 exit_ = node->end_catch_label()->join_for_continue(); 2289 exit_ = node->end_catch_label()->join_for_continue();
2322 } 2290 }
2323 } 2291 }
2324 } 2292 }
2325 2293
2326 // Generate code for the finally block if one exists. 2294 // Generate code for the finally block if one exists.
2327 if ((node->finally_block() != NULL) && is_open()) { 2295 if ((node->finally_block() != NULL) && is_open()) {
2328 EffectGraphVisitor for_finally_block(owner(), temp_index()); 2296 EffectGraphVisitor for_finally_block(owner(), temp_index());
2329 node->finally_block()->Visit(&for_finally_block); 2297 node->finally_block()->Visit(&for_finally_block);
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
2390 void FlowGraphBuilder::BuildGraph(bool for_optimized, bool use_ssa) { 2358 void FlowGraphBuilder::BuildGraph(bool for_optimized, bool use_ssa) {
2391 if (FLAG_print_ast) { 2359 if (FLAG_print_ast) {
2392 // Print the function ast before IL generation. 2360 // Print the function ast before IL generation.
2393 AstPrinter::PrintFunctionNodes(parsed_function()); 2361 AstPrinter::PrintFunctionNodes(parsed_function());
2394 } 2362 }
2395 // Compilation can be nested, preserve the computation-id. 2363 // Compilation can be nested, preserve the computation-id.
2396 const Function& function = parsed_function().function(); 2364 const Function& function = parsed_function().function();
2397 TargetEntryInstr* normal_entry = new TargetEntryInstr(); 2365 TargetEntryInstr* normal_entry = new TargetEntryInstr();
2398 graph_entry_ = new GraphEntryInstr(normal_entry); 2366 graph_entry_ = new GraphEntryInstr(normal_entry);
2399 EffectGraphVisitor for_effect(this, 0); 2367 EffectGraphVisitor for_effect(this, 0);
2400 for_effect.AddBlockEntry(normal_entry); 2368 for_effect.AddInstruction(normal_entry);
2401 parsed_function().node_sequence()->Visit(&for_effect); 2369 parsed_function().node_sequence()->Visit(&for_effect);
2402 // Check that the graph is properly terminated. 2370 // Check that the graph is properly terminated.
2403 ASSERT(!for_effect.is_open()); 2371 ASSERT(!for_effect.is_open());
2404 GrowableArray<intptr_t> parent; 2372 GrowableArray<intptr_t> parent;
2405 GrowableArray<BitVector*> assigned_vars; 2373 GrowableArray<BitVector*> assigned_vars;
2406 intptr_t variable_count = parsed_function_.function().num_fixed_parameters() + 2374 intptr_t variable_count = parsed_function_.function().num_fixed_parameters() +
2407 parsed_function_.copied_parameter_count() + 2375 parsed_function_.copied_parameter_count() +
2408 parsed_function_.stack_local_count(); 2376 parsed_function_.stack_local_count();
2409 // Perform a depth-first traversal of the graph to build preorder and 2377 // Perform a depth-first traversal of the graph to build preorder and
2410 // postorder block orders. 2378 // postorder block orders.
(...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after
2799 char* chars = reinterpret_cast<char*>( 2767 char* chars = reinterpret_cast<char*>(
2800 Isolate::Current()->current_zone()->Allocate(len)); 2768 Isolate::Current()->current_zone()->Allocate(len));
2801 OS::SNPrint(chars, len, kFormat, function_name, reason); 2769 OS::SNPrint(chars, len, kFormat, function_name, reason);
2802 const Error& error = Error::Handle( 2770 const Error& error = Error::Handle(
2803 LanguageError::New(String::Handle(String::New(chars)))); 2771 LanguageError::New(String::Handle(String::New(chars))));
2804 Isolate::Current()->long_jump_base()->Jump(1, error); 2772 Isolate::Current()->long_jump_base()->Jump(1, error);
2805 } 2773 }
2806 2774
2807 2775
2808 } // namespace dart 2776 } // namespace dart
OLDNEW
« no previous file with comments | « vm/flow_graph_builder.h ('k') | vm/flow_graph_compiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698