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

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

Issue 9704063: Simplify translation of conditionals in the flow graph builder. (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
« no previous file with comments | « runtime/vm/flow_graph_builder.h ('k') | no next file » | 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/flags.h" 8 #include "vm/flags.h"
9 #include "vm/intermediate_language.h" 9 #include "vm/intermediate_language.h"
10 #include "vm/longjump.h" 10 #include "vm/longjump.h"
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
46 const EffectGraphVisitor& false_fragment) { 46 const EffectGraphVisitor& false_fragment) {
47 // We have: a test graph fragment with zero, one, or two available exits; 47 // We have: a test graph fragment with zero, one, or two available exits;
48 // and a pair of effect graph fragments with zero or one available exits. 48 // and a pair of effect graph fragments with zero or one available exits.
49 // We want to append the branch and (if necessary) a join node to this 49 // We want to append the branch and (if necessary) a join node to this
50 // graph fragment. 50 // graph fragment.
51 ASSERT(is_open()); 51 ASSERT(is_open());
52 52
53 // 1. Connect the test to this graph. 53 // 1. Connect the test to this graph.
54 Append(test_fragment); 54 Append(test_fragment);
55 55
56 // 2. Connect the true and false bodies to the test if they are reachable, 56 // 2. Connect the true and false bodies to the test and record their exits
57 // and if so record their exits (if any). 57 // (if any).
58 Instruction* true_exit = NULL; 58 Instruction* true_exit = NULL;
59 Instruction* false_exit = NULL; 59 Instruction* false_exit = NULL;
60 if (test_fragment.can_be_true()) { 60 TargetEntryInstr* true_entry = new TargetEntryInstr();
61 TargetEntryInstr* true_entry = new TargetEntryInstr(); 61 *test_fragment.true_successor_address() = true_entry;
62 *test_fragment.true_successor_address() = true_entry; 62 true_entry->SetSuccessor(true_fragment.entry());
63 true_entry->SetSuccessor(true_fragment.entry()); 63 true_exit = true_fragment.is_empty() ? true_entry : true_fragment.exit();
64 true_exit = true_fragment.is_empty() ? true_entry : true_fragment.exit();
65 64
66 TargetEntryInstr* false_entry = new TargetEntryInstr(); 65 TargetEntryInstr* false_entry = new TargetEntryInstr();
67 *test_fragment.false_successor_address() = false_entry; 66 *test_fragment.false_successor_address() = false_entry;
68 false_entry->SetSuccessor(false_fragment.entry()); 67 false_entry->SetSuccessor(false_fragment.entry());
69 false_exit = 68 false_exit = false_fragment.is_empty() ? false_entry : false_fragment.exit();
70 false_fragment.is_empty() ? false_entry : false_fragment.exit();
71 }
72 69
73 // 3. Add a join or select one (or neither) of the arms as exit. 70 // 3. Add a join or select one (or neither) of the arms as exit.
74 if (true_exit == NULL) { 71 if (true_exit == NULL) {
75 exit_ = false_exit; // May be NULL. 72 exit_ = false_exit; // May be NULL.
76 } else if (false_exit == NULL) { 73 } else if (false_exit == NULL) {
77 exit_ = true_exit; 74 exit_ = true_exit;
78 } else { 75 } else {
79 exit_ = new JoinEntryInstr(); 76 exit_ = new JoinEntryInstr();
80 true_exit->SetSuccessor(exit_); 77 true_exit->SetSuccessor(exit_);
81 false_exit->SetSuccessor(exit_); 78 false_exit->SetSuccessor(exit_);
82 } 79 }
83 } 80 }
84 81
85 82
86 void EffectGraphVisitor::TieLoop(const TestGraphVisitor& test_fragment, 83 void EffectGraphVisitor::TieLoop(const TestGraphVisitor& test_fragment,
87 const EffectGraphVisitor& body_fragment) { 84 const EffectGraphVisitor& body_fragment) {
88 // We have: a test graph fragment with zero, one, or two available exits; 85 // We have: a test graph fragment with zero, one, or two available exits;
89 // and an effect graph fragment with zero or one available exits. We want 86 // and an effect graph fragment with zero or one available exits. We want
90 // to append the 'while loop' consisting of the test graph fragment as 87 // to append the 'while loop' consisting of the test graph fragment as
91 // condition and the effect graph fragment as body. 88 // condition and the effect graph fragment as body.
92 ASSERT(is_open()); 89 ASSERT(is_open());
93 90
94 // 1. Connect the body to the test if it is reachable, and if so record 91 // 1. Connect the body to the test if it is reachable, and if so record
95 // its exit (if any). 92 // its exit (if any).
96 Instruction* body_exit = NULL; 93 Instruction* body_exit = NULL;
97 if (test_fragment.can_be_true()) { 94 TargetEntryInstr* body_entry = new TargetEntryInstr();
98 TargetEntryInstr* body_entry = new TargetEntryInstr(); 95 *test_fragment.true_successor_address() = body_entry;
99 *test_fragment.true_successor_address() = body_entry; 96 body_entry->SetSuccessor(body_fragment.entry());
100 body_entry->SetSuccessor(body_fragment.entry()); 97 body_exit = body_fragment.is_empty() ? body_entry : body_fragment.exit();
101 body_exit = body_fragment.is_empty() ? body_entry : body_fragment.exit();
102 }
103 98
104 // 2. Connect the test to this graph, including the body if reachable and 99 // 2. Connect the test to this graph, including the body if reachable and
105 // using a fresh join node if the body is reachable and has an open exit. 100 // using a fresh join node if the body is reachable and has an open exit.
106 if (body_exit == NULL) { 101 if (body_exit == NULL) {
107 Append(test_fragment); 102 Append(test_fragment);
108 } else { 103 } else {
109 JoinEntryInstr* join = new JoinEntryInstr(); 104 JoinEntryInstr* join = new JoinEntryInstr();
110 AddInstruction(join); 105 AddInstruction(join);
111 join->SetSuccessor(test_fragment.entry()); 106 join->SetSuccessor(test_fragment.entry());
112 body_exit->SetSuccessor(join); 107 body_exit->SetSuccessor(join);
113 } 108 }
114 109
115 // 3. Set the exit to the graph to be empty or a fresh target node 110 // 3. Set the exit to the graph to be the false successor of the test, a
116 // depending on whether the false branch of the test is reachable. 111 // fresh target node
117 if (test_fragment.can_be_false()) { 112 exit_ = *test_fragment.false_successor_address() = new TargetEntryInstr();
118 exit_ = *test_fragment.false_successor_address() = new TargetEntryInstr();
119 } else {
120 exit_ = NULL;
121 }
122 } 113 }
123 114
124 115
125 void TestGraphVisitor::ReturnValue(Value* value) { 116 void TestGraphVisitor::ReturnValue(Value* value) {
126 BranchInstr* branch = new BranchInstr(value); 117 BranchInstr* branch = new BranchInstr(value);
127 AddInstruction(branch); 118 AddInstruction(branch);
128 CloseFragment(); 119 CloseFragment();
129 true_successor_address_ = branch->true_successor_address(); 120 true_successor_address_ = branch->true_successor_address();
130 false_successor_address_ = branch->false_successor_address(); 121 false_successor_address_ = branch->false_successor_address();
131 } 122 }
(...skipping 492 matching lines...) Expand 10 before | Expand all | Expand 10 after
624 new InstanceCallComp(node->store_id(), node->token_index(), store_name, 615 new InstanceCallComp(node->store_id(), node->token_index(), store_name,
625 arguments, Array::ZoneHandle(), 1); 616 arguments, Array::ZoneHandle(), 1);
626 AddInstruction(new DoInstr(store)); 617 AddInstruction(new DoInstr(store));
627 ReturnValue(new TempVal(AllocateTempIndex())); 618 ReturnValue(new TempVal(AllocateTempIndex()));
628 } 619 }
629 620
630 621
631 void EffectGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { 622 void EffectGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) {
632 TestGraphVisitor for_test(owner(), temp_index()); 623 TestGraphVisitor for_test(owner(), temp_index());
633 node->condition()->Visit(&for_test); 624 node->condition()->Visit(&for_test);
634 ASSERT(for_test.can_be_true() && for_test.can_be_false());
635 625
636 // Translate the subexpressions for their effects. 626 // Translate the subexpressions for their effects.
637 EffectGraphVisitor for_true(owner(), temp_index()); 627 EffectGraphVisitor for_true(owner(), temp_index());
638 node->true_expr()->Visit(&for_true); 628 node->true_expr()->Visit(&for_true);
639 EffectGraphVisitor for_false(owner(), temp_index()); 629 EffectGraphVisitor for_false(owner(), temp_index());
640 node->false_expr()->Visit(&for_false); 630 node->false_expr()->Visit(&for_false);
641 631
642 Join(for_test, for_true, for_false); 632 Join(for_test, for_true, for_false);
643 } 633 }
644 634
645 635
646 void ValueGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { 636 void ValueGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) {
647 TestGraphVisitor for_test(owner(), temp_index()); 637 TestGraphVisitor for_test(owner(), temp_index());
648 node->condition()->Visit(&for_test); 638 node->condition()->Visit(&for_test);
649 ASSERT(for_test.can_be_true() && for_test.can_be_false());
650 639
651 // Ensure that the value of the true/false subexpressions are named with 640 // Ensure that the value of the true/false subexpressions are named with
652 // the same temporary name. 641 // the same temporary name.
653 ValueGraphVisitor for_true(owner(), temp_index()); 642 ValueGraphVisitor for_true(owner(), temp_index());
654 node->true_expr()->Visit(&for_true); 643 node->true_expr()->Visit(&for_true);
655 ASSERT(for_true.is_open()); 644 ASSERT(for_true.is_open());
656 if (for_true.value()->IsTemp()) { 645 if (for_true.value()->IsTemp()) {
657 ASSERT(for_true.value()->AsTemp()->index() == temp_index()); 646 ASSERT(for_true.value()->AsTemp()->index() == temp_index());
658 } else { 647 } else {
659 for_true.AddInstruction(new BindInstr(temp_index(), for_true.value())); 648 for_true.AddInstruction(new BindInstr(temp_index(), for_true.value()));
(...skipping 16 matching lines...) Expand all
676 // <Statement> ::= If { condition: <Expression> 665 // <Statement> ::= If { condition: <Expression>
677 // true_branch: <Sequence> 666 // true_branch: <Sequence>
678 // false_branch: <Sequence> } 667 // false_branch: <Sequence> }
679 void EffectGraphVisitor::VisitIfNode(IfNode* node) { 668 void EffectGraphVisitor::VisitIfNode(IfNode* node) {
680 TestGraphVisitor for_test(owner(), temp_index()); 669 TestGraphVisitor for_test(owner(), temp_index());
681 node->condition()->Visit(&for_test); 670 node->condition()->Visit(&for_test);
682 671
683 EffectGraphVisitor for_true(owner(), temp_index()); 672 EffectGraphVisitor for_true(owner(), temp_index());
684 EffectGraphVisitor for_false(owner(), temp_index()); 673 EffectGraphVisitor for_false(owner(), temp_index());
685 674
686 if (for_test.can_be_true()) { 675 node->true_branch()->Visit(&for_true);
687 node->true_branch()->Visit(&for_true); 676 // The for_false graph fragment will be empty (default graph fragment) if
688 // The for_false graph fragment will be empty (default graph fragment) 677 // we do not call Visit.
689 // if we do not call Visit. 678 if (node->false_branch() != NULL) node->false_branch()->Visit(&for_false);
690 if (node->false_branch() != NULL) node->false_branch()->Visit(&for_false);
691 }
692 Join(for_test, for_true, for_false); 679 Join(for_test, for_true, for_false);
693 } 680 }
694 681
695 682
696 void EffectGraphVisitor::VisitSwitchNode(SwitchNode* node) { 683 void EffectGraphVisitor::VisitSwitchNode(SwitchNode* node) {
697 Bailout("EffectGraphVisitor::VisitSwitchNode"); 684 Bailout("EffectGraphVisitor::VisitSwitchNode");
698 } 685 }
699 686
700 687
701 void EffectGraphVisitor::VisitCaseNode(CaseNode* node) { 688 void EffectGraphVisitor::VisitCaseNode(CaseNode* node) {
702 Bailout("EffectGraphVisitor::VisitCaseNode"); 689 Bailout("EffectGraphVisitor::VisitCaseNode");
703 } 690 }
704 691
705 692
706 // <Statement> ::= While { label: SourceLabel 693 // <Statement> ::= While { label: SourceLabel
707 // condition: <Expression> 694 // condition: <Expression>
708 // body: <Sequence> } 695 // body: <Sequence> }
709 void EffectGraphVisitor::VisitWhileNode(WhileNode* node) { 696 void EffectGraphVisitor::VisitWhileNode(WhileNode* node) {
710 TestGraphVisitor for_test(owner(), temp_index()); 697 TestGraphVisitor for_test(owner(), temp_index());
711 node->condition()->Visit(&for_test); 698 node->condition()->Visit(&for_test);
712 699
713 EffectGraphVisitor for_body(owner(), temp_index()); 700 EffectGraphVisitor for_body(owner(), temp_index());
714 if (for_test.can_be_true()) node->body()->Visit(&for_body); 701 node->body()->Visit(&for_body);
715 TieLoop(for_test, for_body); 702 TieLoop(for_test, for_body);
716 } 703 }
717 704
718 705
719 void EffectGraphVisitor::VisitDoWhileNode(DoWhileNode* node) { 706 void EffectGraphVisitor::VisitDoWhileNode(DoWhileNode* node) {
720 EffectGraphVisitor for_body(owner(), temp_index()); 707 EffectGraphVisitor for_body(owner(), temp_index());
721 node->body()->Visit(&for_body); 708 node->body()->Visit(&for_body);
722 TestGraphVisitor for_test(owner(), temp_index()); 709 TestGraphVisitor for_test(owner(), temp_index());
723 node->condition()->Visit(&for_test); 710 node->condition()->Visit(&for_test);
724 ASSERT(is_open()); 711 ASSERT(is_open());
(...skipping 916 matching lines...) Expand 10 before | Expand all | Expand 10 after
1641 char* chars = reinterpret_cast<char*>( 1628 char* chars = reinterpret_cast<char*>(
1642 Isolate::Current()->current_zone()->Allocate(len)); 1629 Isolate::Current()->current_zone()->Allocate(len));
1643 OS::SNPrint(chars, len, kFormat, function_name, reason); 1630 OS::SNPrint(chars, len, kFormat, function_name, reason);
1644 const Error& error = Error::Handle( 1631 const Error& error = Error::Handle(
1645 LanguageError::New(String::Handle(String::New(chars)))); 1632 LanguageError::New(String::Handle(String::New(chars))));
1646 Isolate::Current()->long_jump_base()->Jump(1, error); 1633 Isolate::Current()->long_jump_base()->Jump(1, error);
1647 } 1634 }
1648 1635
1649 1636
1650 } // namespace dart 1637 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_builder.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698