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

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

Issue 9553008: Implement DoWhile. (Closed) Base URL: http://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/ast_printer.h"
7 #include "vm/flags.h" 8 #include "vm/flags.h"
8 #include "vm/intermediate_language.h" 9 #include "vm/intermediate_language.h"
9 #include "vm/longjump.h" 10 #include "vm/longjump.h"
10 #include "vm/os.h" 11 #include "vm/os.h"
11 #include "vm/parser.h" 12 #include "vm/parser.h"
12 13
13 namespace dart { 14 namespace dart {
14 15
15 DEFINE_FLAG(bool, print_flow_graph, false, "Print the IR flow graph."); 16 DEFINE_FLAG(bool, print_flow_graph, false, "Print the IR flow graph.");
16 DECLARE_FLAG(bool, enable_type_checks); 17 DECLARE_FLAG(bool, enable_type_checks);
18 DECLARE_FLAG(bool, print_ast);
17 19
18 void EffectGraphVisitor::Append(const EffectGraphVisitor& other_fragment) { 20 void EffectGraphVisitor::Append(const EffectGraphVisitor& other_fragment) {
19 ASSERT(is_open()); 21 ASSERT(is_open());
20 if (other_fragment.is_empty()) return; 22 if (other_fragment.is_empty()) return;
21 if (is_empty()) { 23 if (is_empty()) {
22 entry_ = other_fragment.entry(); 24 entry_ = other_fragment.entry();
23 exit_ = other_fragment.exit(); 25 exit_ = other_fragment.exit();
24 } else { 26 } else {
25 exit()->SetSuccessor(other_fragment.entry()); 27 exit()->SetSuccessor(other_fragment.entry());
26 exit_ = other_fragment.exit(); 28 exit_ = other_fragment.exit();
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 } 212 }
211 213
212 214
213 // <Expression> :: BinaryOp { kind: Token::Kind 215 // <Expression> :: BinaryOp { kind: Token::Kind
214 // left: <Expression> 216 // left: <Expression>
215 // right: <Expression> } 217 // right: <Expression> }
216 void EffectGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { 218 void EffectGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) {
217 // Operators "&&" and "||" cannot be overloaded therefore do not call 219 // Operators "&&" and "||" cannot be overloaded therefore do not call
218 // operator. 220 // operator.
219 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { 221 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) {
222 // Implement short-circuit logic: do not evaluate right if evaluation
223 // of left is sufficient.
220 Bailout("EffectGraphVisitor::VisitBinaryOpNode AND/OR"); 224 Bailout("EffectGraphVisitor::VisitBinaryOpNode AND/OR");
221 } 225 }
222 ArgumentGraphVisitor for_left_value(owner(), temp_index()); 226 ArgumentGraphVisitor for_left_value(owner(), temp_index());
223 node->left()->Visit(&for_left_value); 227 node->left()->Visit(&for_left_value);
224 Append(for_left_value); 228 Append(for_left_value);
225 ArgumentGraphVisitor for_right_value(owner(), for_left_value.temp_index()); 229 ArgumentGraphVisitor for_right_value(owner(), for_left_value.temp_index());
226 node->right()->Visit(&for_right_value); 230 node->right()->Visit(&for_right_value);
227 Append(for_right_value); 231 Append(for_right_value);
228 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2); 232 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2);
229 arguments->Add(for_left_value.value()); 233 arguments->Add(for_left_value.value());
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
432 TestGraphVisitor for_test(owner(), temp_index()); 436 TestGraphVisitor for_test(owner(), temp_index());
433 node->condition()->Visit(&for_test); 437 node->condition()->Visit(&for_test);
434 438
435 EffectGraphVisitor for_body(owner(), temp_index()); 439 EffectGraphVisitor for_body(owner(), temp_index());
436 if (for_test.can_be_true()) node->body()->Visit(&for_body); 440 if (for_test.can_be_true()) node->body()->Visit(&for_body);
437 TieLoop(for_test, for_body); 441 TieLoop(for_test, for_body);
438 } 442 }
439 443
440 444
441 void EffectGraphVisitor::VisitDoWhileNode(DoWhileNode* node) { 445 void EffectGraphVisitor::VisitDoWhileNode(DoWhileNode* node) {
442 Bailout("EffectGraphVisitor::VisitDoWhileNode"); 446 EffectGraphVisitor for_body(owner(), temp_index());
447 node->body()->Visit(&for_body);
448 TestGraphVisitor for_test(owner(), temp_index());
449 node->condition()->Visit(&for_test);
450 ASSERT(is_open());
451
452 // Tie do-while loop (test is after the body).
Kevin Millikin (Google) 2012/03/07 09:15:44 I think we can come up with a generic loop-tying f
453 JoinEntryInstr* join = new JoinEntryInstr();
454 AddInstruction(join);
455 join->SetSuccessor(for_body.entry());
456 Instruction* body_exit = for_body.is_empty() ? join : for_body.exit();
Kevin Millikin (Google) 2012/03/07 09:15:44 This is correct but contains introduces an extra b
457
458 if (body_exit != NULL) {
459 TargetEntryInstr* target_entry = new TargetEntryInstr();
460 target_entry->SetSuccessor(for_test.entry());
461 body_exit->SetSuccessor(target_entry);
462 }
463
464 *for_test.true_successor_address() = join;
465 exit_ = *for_test.false_successor_address() = new TargetEntryInstr();
443 } 466 }
444 467
445 468
446 void EffectGraphVisitor::VisitForNode(ForNode* node) { 469 void EffectGraphVisitor::VisitForNode(ForNode* node) {
447 Bailout("EffectGraphVisitor::VisitForNode"); 470 Bailout("EffectGraphVisitor::VisitForNode");
448 } 471 }
449 472
450 473
451 void EffectGraphVisitor::VisitJumpNode(JumpNode* node) { 474 void EffectGraphVisitor::VisitJumpNode(JumpNode* node) {
452 Bailout("EffectGraphVisitor::VisitJumpNode"); 475 Bailout("EffectGraphVisitor::VisitJumpNode");
(...skipping 500 matching lines...) Expand 10 before | Expand all | Expand 10 after
953 976
954 void FlowGraphPrinter::VisitBranch(BranchInstr* instr) { 977 void FlowGraphPrinter::VisitBranch(BranchInstr* instr) {
955 OS::Print(" if "); 978 OS::Print(" if ");
956 instr->value()->Accept(this); 979 instr->value()->Accept(this);
957 OS::Print(" goto(%d, %d)", instr->true_successor()->block_number(), 980 OS::Print(" goto(%d, %d)", instr->true_successor()->block_number(),
958 instr->false_successor()->block_number()); 981 instr->false_successor()->block_number());
959 } 982 }
960 983
961 984
962 void FlowGraphBuilder::BuildGraph() { 985 void FlowGraphBuilder::BuildGraph() {
986 if (FLAG_print_ast) {
987 // Print the function ast before IL generation.
988 AstPrinter::PrintFunctionNodes(parsed_function_);
989 }
963 EffectGraphVisitor for_effect(this, 0); 990 EffectGraphVisitor for_effect(this, 0);
964 for_effect.AddInstruction(new TargetEntryInstr()); 991 for_effect.AddInstruction(new TargetEntryInstr());
965 parsed_function().node_sequence()->Visit(&for_effect); 992 parsed_function().node_sequence()->Visit(&for_effect);
966 // Check that the graph is properly terminated. 993 // Check that the graph is properly terminated.
967 ASSERT(!for_effect.is_open()); 994 ASSERT(!for_effect.is_open());
968 if (for_effect.entry() != NULL) { 995 if (for_effect.entry() != NULL) {
969 // Accumulate basic block entries via postorder traversal. 996 // Accumulate basic block entries via postorder traversal.
970 for_effect.entry()->Postorder(&postorder_block_entries_); 997 for_effect.entry()->Postorder(&postorder_block_entries_);
971 // Number the blocks in reverse postorder starting with 0. 998 // Number the blocks in reverse postorder starting with 0.
972 intptr_t last_index = postorder_block_entries_.length() - 1; 999 intptr_t last_index = postorder_block_entries_.length() - 1;
(...skipping 15 matching lines...) Expand all
988 char* chars = reinterpret_cast<char*>( 1015 char* chars = reinterpret_cast<char*>(
989 Isolate::Current()->current_zone()->Allocate(len)); 1016 Isolate::Current()->current_zone()->Allocate(len));
990 OS::SNPrint(chars, len, kFormat, function_name, reason); 1017 OS::SNPrint(chars, len, kFormat, function_name, reason);
991 const Error& error = Error::Handle( 1018 const Error& error = Error::Handle(
992 LanguageError::New(String::Handle(String::New(chars)))); 1019 LanguageError::New(String::Handle(String::New(chars))));
993 Isolate::Current()->long_jump_base()->Jump(1, error); 1020 Isolate::Current()->long_jump_base()->Jump(1, error);
994 } 1021 }
995 1022
996 1023
997 } // namespace dart 1024 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698