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

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

Powered by Google App Engine
This is Rietveld 408576698