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

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

Issue 10967007: Inlining functions with control flow. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 2 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_builder.h ('k') | runtime/vm/flow_graph_inliner.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/code_descriptors.h" 8 #include "vm/code_descriptors.h"
9 #include "vm/dart_entry.h" 9 #include "vm/dart_entry.h"
10 #include "vm/flags.h" 10 #include "vm/flags.h"
(...skipping 1075 matching lines...) Expand 10 before | Expand all | Expand 10 after
1086 // e) true-target-0 -> case-statements-join 1086 // e) true-target-0 -> case-statements-join
1087 // f) true-target-1 -> case-statements-join 1087 // f) true-target-1 -> case-statements-join
1088 // g) case-statements-join 1088 // g) case-statements-join
1089 // h) [ case-statements ] -> exit-join 1089 // h) [ case-statements ] -> exit-join
1090 // i) exit-target -> exit-join 1090 // i) exit-target -> exit-join
1091 // j) exit-join 1091 // j) exit-join
1092 // 1092 //
1093 // Note: The specification of switch/case is under discussion and may change 1093 // Note: The specification of switch/case is under discussion and may change
1094 // drastically. 1094 // drastically.
1095 void EffectGraphVisitor::VisitCaseNode(CaseNode* node) { 1095 void EffectGraphVisitor::VisitCaseNode(CaseNode* node) {
1096 InlineBailout("EffectGraphVisitor::VisitCaseNode (control)");
1097 const intptr_t len = node->case_expressions()->length(); 1096 const intptr_t len = node->case_expressions()->length();
1098 // Create case statements instructions. 1097 // Create case statements instructions.
1099 EffectGraphVisitor for_case_statements(owner(), temp_index()); 1098 EffectGraphVisitor for_case_statements(owner(), temp_index());
1100 // Compute start of statements fragment. 1099 // Compute start of statements fragment.
1101 JoinEntryInstr* statement_start = NULL; 1100 JoinEntryInstr* statement_start = NULL;
1102 if ((node->label() != NULL) && node->label()->is_continue_target()) { 1101 if ((node->label() != NULL) && node->label()->is_continue_target()) {
1103 // Since a labeled jump continue statement occur in a different case node, 1102 // Since a labeled jump continue statement occur in a different case node,
1104 // allocate JoinNode here and use it as statement start. 1103 // allocate JoinNode here and use it as statement start.
1105 statement_start = node->label()->join_for_continue(); 1104 statement_start = node->label()->join_for_continue();
1106 if (statement_start == NULL) { 1105 if (statement_start == NULL) {
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
1182 // body: <Sequence> } 1181 // body: <Sequence> }
1183 // The fragment is composed as follows: 1182 // The fragment is composed as follows:
1184 // a) loop-join 1183 // a) loop-join
1185 // b) [ test ] -> (body-entry-target, loop-exit-target) 1184 // b) [ test ] -> (body-entry-target, loop-exit-target)
1186 // c) body-entry-target 1185 // c) body-entry-target
1187 // d) [ body ] -> (continue-join) 1186 // d) [ body ] -> (continue-join)
1188 // e) continue-join -> (loop-join) 1187 // e) continue-join -> (loop-join)
1189 // f) loop-exit-target 1188 // f) loop-exit-target
1190 // g) break-join (optional) 1189 // g) break-join (optional)
1191 void EffectGraphVisitor::VisitWhileNode(WhileNode* node) { 1190 void EffectGraphVisitor::VisitWhileNode(WhileNode* node) {
1192 InlineBailout("EffectGraphVisitor::VisitWhileNode (control)");
1193 TestGraphVisitor for_test(owner(), 1191 TestGraphVisitor for_test(owner(),
1194 temp_index(), 1192 temp_index(),
1195 node->condition()->token_pos()); 1193 node->condition()->token_pos());
1196 node->condition()->Visit(&for_test); 1194 node->condition()->Visit(&for_test);
1197 ASSERT(!for_test.is_empty()); // Language spec. 1195 ASSERT(!for_test.is_empty()); // Language spec.
1198 1196
1199 EffectGraphVisitor for_body(owner(), temp_index()); 1197 EffectGraphVisitor for_body(owner(), temp_index());
1200 for_body.AddInstruction( 1198 for_body.AddInstruction(
1201 new CheckStackOverflowInstr(node->token_pos())); 1199 new CheckStackOverflowInstr(node->token_pos()));
1202 node->body()->Visit(&for_body); 1200 node->body()->Visit(&for_body);
(...skipping 17 matching lines...) Expand all
1220 1218
1221 // The fragment is composed as follows: 1219 // The fragment is composed as follows:
1222 // a) body-entry-join 1220 // a) body-entry-join
1223 // b) [ body ] 1221 // b) [ body ]
1224 // c) test-entry (continue-join or body-exit-target) 1222 // c) test-entry (continue-join or body-exit-target)
1225 // d) [ test-entry ] -> (back-target, loop-exit-target) 1223 // d) [ test-entry ] -> (back-target, loop-exit-target)
1226 // e) back-target -> (body-entry-join) 1224 // e) back-target -> (body-entry-join)
1227 // f) loop-exit-target 1225 // f) loop-exit-target
1228 // g) break-join 1226 // g) break-join
1229 void EffectGraphVisitor::VisitDoWhileNode(DoWhileNode* node) { 1227 void EffectGraphVisitor::VisitDoWhileNode(DoWhileNode* node) {
1230 InlineBailout("EffectGraphVisitor::VisitDoWhileNode (control)");
1231 // Traverse body first in order to generate continue and break labels. 1228 // Traverse body first in order to generate continue and break labels.
1232 EffectGraphVisitor for_body(owner(), temp_index()); 1229 EffectGraphVisitor for_body(owner(), temp_index());
1233 for_body.AddInstruction( 1230 for_body.AddInstruction(
1234 new CheckStackOverflowInstr(node->token_pos())); 1231 new CheckStackOverflowInstr(node->token_pos()));
1235 node->body()->Visit(&for_body); 1232 node->body()->Visit(&for_body);
1236 1233
1237 TestGraphVisitor for_test(owner(), 1234 TestGraphVisitor for_test(owner(),
1238 temp_index(), 1235 temp_index(),
1239 node->condition()->token_pos()); 1236 node->condition()->token_pos());
1240 node->condition()->Visit(&for_test); 1237 node->condition()->Visit(&for_test);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1275 // a) [ initializer ] 1272 // a) [ initializer ]
1276 // b) loop-join 1273 // b) loop-join
1277 // c) [ test ] -> (body-entry-target, loop-exit-target) 1274 // c) [ test ] -> (body-entry-target, loop-exit-target)
1278 // d) body-entry-target 1275 // d) body-entry-target
1279 // e) [ body ] 1276 // e) [ body ]
1280 // f) continue-join (optional) 1277 // f) continue-join (optional)
1281 // g) [ increment ] -> (loop-join) 1278 // g) [ increment ] -> (loop-join)
1282 // h) loop-exit-target 1279 // h) loop-exit-target
1283 // i) break-join 1280 // i) break-join
1284 void EffectGraphVisitor::VisitForNode(ForNode* node) { 1281 void EffectGraphVisitor::VisitForNode(ForNode* node) {
1285 InlineBailout("EffectGraphVisitor::VisitForNode (control)");
1286 EffectGraphVisitor for_initializer(owner(), temp_index()); 1282 EffectGraphVisitor for_initializer(owner(), temp_index());
1287 node->initializer()->Visit(&for_initializer); 1283 node->initializer()->Visit(&for_initializer);
1288 Append(for_initializer); 1284 Append(for_initializer);
1289 ASSERT(is_open()); 1285 ASSERT(is_open());
1290 1286
1291 // Compose body to set any jump labels. 1287 // Compose body to set any jump labels.
1292 EffectGraphVisitor for_body(owner(), temp_index()); 1288 EffectGraphVisitor for_body(owner(), temp_index());
1293 for_body.AddInstruction( 1289 for_body.AddInstruction(
1294 new CheckStackOverflowInstr(node->token_pos())); 1290 new CheckStackOverflowInstr(node->token_pos()));
1295 node->body()->Visit(&for_body); 1291 node->body()->Visit(&for_body);
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1349 exit_ = for_test.CreateFalseSuccessor(); 1345 exit_ = for_test.CreateFalseSuccessor();
1350 } else { 1346 } else {
1351 for_test.IfFalseGoto(node->label()->join_for_break()); 1347 for_test.IfFalseGoto(node->label()->join_for_break());
1352 exit_ = node->label()->join_for_break(); 1348 exit_ = node->label()->join_for_break();
1353 } 1349 }
1354 } 1350 }
1355 } 1351 }
1356 1352
1357 1353
1358 void EffectGraphVisitor::VisitJumpNode(JumpNode* node) { 1354 void EffectGraphVisitor::VisitJumpNode(JumpNode* node) {
1359 InlineBailout("EffectGraphVisitor::VisitJumpNode (control)");
1360 for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) { 1355 for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) {
1361 EffectGraphVisitor for_effect(owner(), temp_index()); 1356 EffectGraphVisitor for_effect(owner(), temp_index());
1362 node->InlinedFinallyNodeAt(i)->Visit(&for_effect); 1357 node->InlinedFinallyNodeAt(i)->Visit(&for_effect);
1363 Append(for_effect); 1358 Append(for_effect);
1364 if (!is_open()) return; 1359 if (!is_open()) return;
1365 } 1360 }
1366 1361
1367 // Unchain the context(s) up to the outer context level of the scope which 1362 // Unchain the context(s) up to the outer context level of the scope which
1368 // contains the destination label. 1363 // contains the destination label.
1369 SourceLabel* label = node->label(); 1364 SourceLabel* label = node->label();
(...skipping 1259 matching lines...) Expand 10 before | Expand all | Expand 10 after
2629 // TODO(kmillikin): We can eliminate stack checks in some cases (e.g., the 2624 // TODO(kmillikin): We can eliminate stack checks in some cases (e.g., the
2630 // stack check on entry for leaf routines). 2625 // stack check on entry for leaf routines).
2631 Instruction* check = new CheckStackOverflowInstr(function.token_pos()); 2626 Instruction* check = new CheckStackOverflowInstr(function.token_pos());
2632 // If we are inlining don't actually attach the stack check. We must still 2627 // If we are inlining don't actually attach the stack check. We must still
2633 // create the stack check inorder to allocate a deopt id. 2628 // create the stack check inorder to allocate a deopt id.
2634 if (!InInliningContext()) for_effect.AddInstruction(check); 2629 if (!InInliningContext()) for_effect.AddInstruction(check);
2635 parsed_function().node_sequence()->Visit(&for_effect); 2630 parsed_function().node_sequence()->Visit(&for_effect);
2636 AppendFragment(normal_entry, for_effect); 2631 AppendFragment(normal_entry, for_effect);
2637 // Check that the graph is properly terminated. 2632 // Check that the graph is properly terminated.
2638 ASSERT(!for_effect.is_open()); 2633 ASSERT(!for_effect.is_open());
2639 FlowGraph* graph = new FlowGraph(*this, graph_entry_); 2634 FlowGraph* graph = new FlowGraph(*this, graph_entry_, last_used_block_id_);
2640 if (InInliningContext()) graph->set_exits(exits_); 2635 if (InInliningContext()) graph->set_exits(exits_);
2641 return graph; 2636 return graph;
2642 } 2637 }
2643 2638
2644 2639
2645 void FlowGraphBuilder::Bailout(const char* reason) { 2640 void FlowGraphBuilder::Bailout(const char* reason) {
2646 const char* kFormat = "FlowGraphBuilder Bailout: %s %s"; 2641 const char* kFormat = "FlowGraphBuilder Bailout: %s %s";
2647 const char* function_name = parsed_function_.function().ToCString(); 2642 const char* function_name = parsed_function_.function().ToCString();
2648 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; 2643 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1;
2649 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); 2644 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len);
2650 OS::SNPrint(chars, len, kFormat, function_name, reason); 2645 OS::SNPrint(chars, len, kFormat, function_name, reason);
2651 const Error& error = Error::Handle( 2646 const Error& error = Error::Handle(
2652 LanguageError::New(String::Handle(String::New(chars)))); 2647 LanguageError::New(String::Handle(String::New(chars))));
2653 Isolate::Current()->long_jump_base()->Jump(1, error); 2648 Isolate::Current()->long_jump_base()->Jump(1, error);
2654 } 2649 }
2655 2650
2656 2651
2657 } // namespace dart 2652 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_builder.h ('k') | runtime/vm/flow_graph_inliner.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698