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

Side by Side Diff: vm/flow_graph_builder.cc

Issue 10665022: Make IL instructions a doubly-linked list within basic blocks. (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_allocator.cc ('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 exit()->SetSuccessor(other_fragment.entry()); 54 exit()->set_successor(other_fragment.entry());
55 exit_ = other_fragment.exit(); 55 exit_ = other_fragment.exit();
56 } 56 }
57 temp_index_ = other_fragment.temp_index(); 57 temp_index_ = other_fragment.temp_index();
58 } 58 }
59 59
60 60
61 void EffectGraphVisitor::AddInstruction(Instruction* instruction) { 61 void EffectGraphVisitor::AddInstruction(Instruction* instruction) {
62 ASSERT(is_open()); 62 ASSERT(is_open());
63 DeallocateTempIndex(instruction->InputCount()); 63 DeallocateTempIndex(instruction->InputCount());
64 if (instruction->IsDefinition()) { 64 if (instruction->IsDefinition()) {
65 instruction->AsDefinition()->set_temp_index(AllocateTempIndex()); 65 instruction->AsDefinition()->set_temp_index(AllocateTempIndex());
66 } 66 }
67 if (is_empty()) { 67 if (is_empty()) {
68 entry_ = exit_ = instruction; 68 entry_ = exit_ = instruction;
69 } else { 69 } else {
70 exit()->SetSuccessor(instruction); 70 exit()->set_successor(instruction);
71 exit_ = instruction; 71 exit_ = instruction;
72 } 72 }
73 } 73 }
74 74
75 75
76 // Appends a graph fragment to a block entry instruction and returns the exit
77 // of the resulting graph fragment.
78 static Instruction* AppendFragment(BlockEntryInstr* entry,
79 const EffectGraphVisitor& fragment) {
80 if (fragment.is_empty()) return entry;
81 entry->set_successor(fragment.entry());
82 return fragment.exit();
83 }
84
85
76 void EffectGraphVisitor::Join(const TestGraphVisitor& test_fragment, 86 void EffectGraphVisitor::Join(const TestGraphVisitor& test_fragment,
77 const EffectGraphVisitor& true_fragment, 87 const EffectGraphVisitor& true_fragment,
78 const EffectGraphVisitor& false_fragment) { 88 const EffectGraphVisitor& false_fragment) {
79 // We have: a test graph fragment with zero, one, or two available exits; 89 // We have: a test graph fragment with zero, one, or two available exits;
80 // and a pair of effect graph fragments with zero or one available exits. 90 // and a pair of effect graph fragments with zero or one available exits.
81 // We want to append the branch and (if necessary) a join node to this 91 // We want to append the branch and (if necessary) a join node to this
82 // graph fragment. 92 // graph fragment.
83 ASSERT(is_open()); 93 ASSERT(is_open());
84 94
85 // 1. Connect the test to this graph. 95 // 1. Connect the test to this graph.
86 Append(test_fragment); 96 Append(test_fragment);
87 97
88 // 2. Connect the true and false bodies to the test and record their exits 98 // 2. Connect the true and false bodies to the test and record their exits
89 // (if any). 99 // (if any).
90 Instruction* true_exit = NULL;
91 Instruction* false_exit = NULL;
92 TargetEntryInstr* true_entry = new TargetEntryInstr(); 100 TargetEntryInstr* true_entry = new TargetEntryInstr();
93 *test_fragment.true_successor_address() = true_entry; 101 *test_fragment.true_successor_address() = true_entry;
94 true_entry->SetSuccessor(true_fragment.entry()); 102 Instruction* true_exit = AppendFragment(true_entry, true_fragment);
95 true_exit = true_fragment.is_empty() ? true_entry : true_fragment.exit();
96 103
97 TargetEntryInstr* false_entry = new TargetEntryInstr(); 104 TargetEntryInstr* false_entry = new TargetEntryInstr();
98 *test_fragment.false_successor_address() = false_entry; 105 *test_fragment.false_successor_address() = false_entry;
99 false_entry->SetSuccessor(false_fragment.entry()); 106 Instruction* false_exit = AppendFragment(false_entry, false_fragment);
100 false_exit = false_fragment.is_empty() ? false_entry : false_fragment.exit();
101 107
102 // 3. Add a join or select one (or neither) of the arms as exit. 108 // 3. Add a join or select one (or neither) of the arms as exit.
103 if (true_exit == NULL) { 109 if (true_exit == NULL) {
104 exit_ = false_exit; // May be NULL. 110 exit_ = false_exit; // May be NULL.
105 if (false_exit != NULL) temp_index_ = false_fragment.temp_index(); 111 if (false_exit != NULL) temp_index_ = false_fragment.temp_index();
106 } else if (false_exit == NULL) { 112 } else if (false_exit == NULL) {
107 exit_ = true_exit; 113 exit_ = true_exit;
108 temp_index_ = true_fragment.temp_index(); 114 temp_index_ = true_fragment.temp_index();
109 } else { 115 } else {
110 exit_ = new JoinEntryInstr(); 116 exit_ = new JoinEntryInstr();
111 true_exit->SetSuccessor(exit_); 117 true_exit->set_successor(exit_);
112 false_exit->SetSuccessor(exit_); 118 false_exit->set_successor(exit_);
113 ASSERT(true_fragment.temp_index() == false_fragment.temp_index()); 119 ASSERT(true_fragment.temp_index() == false_fragment.temp_index());
114 temp_index_ = true_fragment.temp_index(); 120 temp_index_ = true_fragment.temp_index();
115 } 121 }
116 } 122 }
117 123
118 124
119 void EffectGraphVisitor::TieLoop(const TestGraphVisitor& test_fragment, 125 void EffectGraphVisitor::TieLoop(const TestGraphVisitor& test_fragment,
120 const EffectGraphVisitor& body_fragment) { 126 const EffectGraphVisitor& body_fragment) {
121 // We have: a test graph fragment with zero, one, or two available exits; 127 // We have: a test graph fragment with zero, one, or two available exits;
122 // and an effect graph fragment with zero or one available exits. We want 128 // and an effect graph fragment with zero or one available exits. We want
123 // to append the 'while loop' consisting of the test graph fragment as 129 // to append the 'while loop' consisting of the test graph fragment as
124 // condition and the effect graph fragment as body. 130 // condition and the effect graph fragment as body.
125 ASSERT(is_open()); 131 ASSERT(is_open());
126 132
127 // 1. Connect the body to the test if it is reachable, and if so record 133 // 1. Connect the body to the test if it is reachable, and if so record
128 // its exit (if any). 134 // its exit (if any).
129 Instruction* body_exit = NULL;
130 TargetEntryInstr* body_entry = new TargetEntryInstr(); 135 TargetEntryInstr* body_entry = new TargetEntryInstr();
131 *test_fragment.true_successor_address() = body_entry; 136 *test_fragment.true_successor_address() = body_entry;
132 body_entry->SetSuccessor(body_fragment.entry()); 137 Instruction* body_exit = AppendFragment(body_entry, body_fragment);
133 body_exit = body_fragment.is_empty() ? body_entry : body_fragment.exit();
134 138
135 // 2. Connect the test to this graph, including the body if reachable and 139 // 2. Connect the test to this graph, including the body if reachable and
136 // using a fresh join node if the body is reachable and has an open exit. 140 // using a fresh join node if the body is reachable and has an open exit.
137 if (body_exit == NULL) { 141 if (body_exit == NULL) {
138 Append(test_fragment); 142 Append(test_fragment);
139 } else { 143 } else {
140 JoinEntryInstr* join = new JoinEntryInstr(); 144 JoinEntryInstr* join = new JoinEntryInstr();
141 AddInstruction(join); 145 AddInstruction(join);
142 join->SetSuccessor(test_fragment.entry()); 146 join->set_successor(test_fragment.entry());
143 body_exit->SetSuccessor(join); 147 body_exit->set_successor(join);
144 } 148 }
145 149
146 // 3. Set the exit to the graph to be the false successor of the test, a 150 // 3. Set the exit to the graph to be the false successor of the test, a
147 // fresh target node 151 // fresh target node
148 exit_ = *test_fragment.false_successor_address() = new TargetEntryInstr(); 152 exit_ = *test_fragment.false_successor_address() = new TargetEntryInstr();
149 } 153 }
150 154
151 155
152 Computation* EffectGraphVisitor::BuildStoreLocal( 156 Computation* EffectGraphVisitor::BuildStoreLocal(
153 const LocalVariable& local, Value* value) { 157 const LocalVariable& local, Value* value) {
(...skipping 897 matching lines...) Expand 10 before | Expand all | Expand 10 after
1051 1055
1052 // Once a test fragment has been added, this fragment is closed. 1056 // Once a test fragment has been added, this fragment is closed.
1053 ASSERT(!is_open()); 1057 ASSERT(!is_open());
1054 1058
1055 // Connect all test cases except the last one. 1059 // Connect all test cases except the last one.
1056 for (intptr_t i = 0; i < (len - 1); i++) { 1060 for (intptr_t i = 0; i < (len - 1); i++) {
1057 ASSERT(needs_join_at_statement_entry); 1061 ASSERT(needs_join_at_statement_entry);
1058 *case_false_addresses[i] = case_entries[i + 1]; 1062 *case_false_addresses[i] = case_entries[i + 1];
1059 TargetEntryInstr* true_target = new TargetEntryInstr(); 1063 TargetEntryInstr* true_target = new TargetEntryInstr();
1060 *case_true_addresses[i] = true_target; 1064 *case_true_addresses[i] = true_target;
1061 true_target->SetSuccessor(statement_start); 1065 true_target->set_successor(statement_start);
1062 } 1066 }
1063 1067
1064 BlockEntryInstr* exit_instruction = NULL; 1068 BlockEntryInstr* exit_instruction = NULL;
1065 // Handle last (or only) case: false goes to exit or to statement if this 1069 // Handle last (or only) case: false goes to exit or to statement if this
1066 // node contains default. 1070 // node contains default.
1067 if (len > 0) { 1071 if (len > 0) {
1068 if (statement_start->IsTargetEntry()) { 1072 if (statement_start->IsTargetEntry()) {
1069 *case_true_addresses[len - 1] = statement_start->AsTargetEntry(); 1073 *case_true_addresses[len - 1] = statement_start->AsTargetEntry();
1070 } else { 1074 } else {
1071 TargetEntryInstr* true_target = new TargetEntryInstr(); 1075 TargetEntryInstr* true_target = new TargetEntryInstr();
1072 *case_true_addresses[len - 1] = true_target; 1076 *case_true_addresses[len - 1] = true_target;
1073 true_target->SetSuccessor(statement_start); 1077 true_target->set_successor(statement_start);
1074 } 1078 }
1075 TargetEntryInstr* false_target = new TargetEntryInstr(); 1079 TargetEntryInstr* false_target = new TargetEntryInstr();
1076 *case_false_addresses[len - 1] = false_target; 1080 *case_false_addresses[len - 1] = false_target;
1077 if (node->contains_default()) { 1081 if (node->contains_default()) {
1078 // True and false go to statement start. 1082 // True and false go to statement start.
1079 false_target->SetSuccessor(statement_start); 1083 false_target->set_successor(statement_start);
1080 if (for_case_statements.is_open()) { 1084 if (for_case_statements.is_open()) {
1081 exit_instruction = new TargetEntryInstr(); 1085 exit_instruction = new TargetEntryInstr();
1082 for_case_statements.exit()->SetSuccessor(exit_instruction); 1086 for_case_statements.exit()->set_successor(exit_instruction);
1083 } 1087 }
1084 } else { 1088 } else {
1085 if (for_case_statements.is_open()) { 1089 if (for_case_statements.is_open()) {
1086 exit_instruction = new JoinEntryInstr(); 1090 exit_instruction = new JoinEntryInstr();
1087 for_case_statements.exit()->SetSuccessor(exit_instruction); 1091 for_case_statements.exit()->set_successor(exit_instruction);
1088 } else { 1092 } else {
1089 exit_instruction = new TargetEntryInstr(); 1093 exit_instruction = new TargetEntryInstr();
1090 } 1094 }
1091 false_target->SetSuccessor(exit_instruction); 1095 false_target->set_successor(exit_instruction);
1092 } 1096 }
1093 } else { 1097 } else {
1094 // A CaseNode without case expressions must contain default. 1098 // A CaseNode without case expressions must contain default.
1095 ASSERT(node->contains_default()); 1099 ASSERT(node->contains_default());
1096 AddInstruction(statement_start); 1100 AddInstruction(statement_start);
1097 } 1101 }
1098 1102
1099 ASSERT(!is_open()); 1103 ASSERT(!is_open());
1100 exit_ = exit_instruction; 1104 exit_ = exit_instruction;
1101 } 1105 }
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1156 1160
1157 TestGraphVisitor for_test(owner(), 1161 TestGraphVisitor for_test(owner(),
1158 temp_index(), 1162 temp_index(),
1159 node->condition()->token_pos()); 1163 node->condition()->token_pos());
1160 node->condition()->Visit(&for_test); 1164 node->condition()->Visit(&for_test);
1161 ASSERT(is_open()); 1165 ASSERT(is_open());
1162 1166
1163 // Tie do-while loop (test is after the body). 1167 // Tie do-while loop (test is after the body).
1164 JoinEntryInstr* body_entry_join = new JoinEntryInstr(); 1168 JoinEntryInstr* body_entry_join = new JoinEntryInstr();
1165 AddInstruction(body_entry_join); 1169 AddInstruction(body_entry_join);
1166 body_entry_join->SetSuccessor(for_body.entry()); 1170 Instruction* body_exit = AppendFragment(body_entry_join, for_body);
1167 Instruction* body_exit =
1168 for_body.is_empty() ? body_entry_join : for_body.exit();
1169 1171
1170 if (for_body.is_open() || (node->label()->join_for_continue() != NULL)) { 1172 if (for_body.is_open() || (node->label()->join_for_continue() != NULL)) {
1171 BlockEntryInstr* test_entry = NULL; 1173 BlockEntryInstr* test_entry = NULL;
1172 if (node->label()->join_for_continue() == NULL) { 1174 if (node->label()->join_for_continue() == NULL) {
1173 test_entry = new TargetEntryInstr(); 1175 test_entry = new TargetEntryInstr();
1174 } else { 1176 } else {
1175 test_entry = node->label()->join_for_continue(); 1177 test_entry = node->label()->join_for_continue();
1176 } 1178 }
1177 test_entry->SetSuccessor(for_test.entry()); 1179 test_entry->set_successor(for_test.entry());
1178 if (body_exit != NULL) { 1180 if (body_exit != NULL) {
1179 body_exit->SetSuccessor(test_entry); 1181 body_exit->set_successor(test_entry);
1180 } 1182 }
1181 } 1183 }
1182 1184
1183 TargetEntryInstr* back_target_entry = new TargetEntryInstr(); 1185 TargetEntryInstr* back_target_entry = new TargetEntryInstr();
1184 *for_test.true_successor_address() = back_target_entry; 1186 *for_test.true_successor_address() = back_target_entry;
1185 back_target_entry->SetSuccessor(body_entry_join); 1187 back_target_entry->set_successor(body_entry_join);
1186 TargetEntryInstr* loop_exit_target = new TargetEntryInstr(); 1188 TargetEntryInstr* loop_exit_target = new TargetEntryInstr();
1187 *for_test.false_successor_address() = loop_exit_target; 1189 *for_test.false_successor_address() = loop_exit_target;
1188 if (node->label()->join_for_break() == NULL) { 1190 if (node->label()->join_for_break() == NULL) {
1189 exit_ = loop_exit_target; 1191 exit_ = loop_exit_target;
1190 } else { 1192 } else {
1191 loop_exit_target->SetSuccessor(node->label()->join_for_break()); 1193 loop_exit_target->set_successor(node->label()->join_for_break());
1192 exit_ = node->label()->join_for_break(); 1194 exit_ = node->label()->join_for_break();
1193 } 1195 }
1194 } 1196 }
1195 1197
1196 1198
1197 // A ForNode can contain break and continue jumps. 'break' joins to 1199 // A ForNode can contain break and continue jumps. 'break' joins to
1198 // ForNode exit, 'continue' joins at increment entry. The fragment is composed 1200 // ForNode exit, 'continue' joins at increment entry. The fragment is composed
1199 // as follows: 1201 // as follows:
1200 // a) [ initializer ] 1202 // a) [ initializer ]
1201 // b) loop-join 1203 // b) loop-join
(...skipping 26 matching lines...) Expand all
1228 if ((node->label()->join_for_continue() == NULL) && for_body.is_open()) { 1230 if ((node->label()->join_for_continue() == NULL) && for_body.is_open()) {
1229 // Do not insert an extra basic block. 1231 // Do not insert an extra basic block.
1230 node->increment()->Visit(&for_increment); 1232 node->increment()->Visit(&for_increment);
1231 for_body.Append(for_increment); 1233 for_body.Append(for_increment);
1232 loop_increment_end = for_body.exit(); 1234 loop_increment_end = for_body.exit();
1233 // 'for_body' contains at least the TargetInstruction 'body_entry'. 1235 // 'for_body' contains at least the TargetInstruction 'body_entry'.
1234 ASSERT(loop_increment_end != NULL); 1236 ASSERT(loop_increment_end != NULL);
1235 } else if (node->label()->join_for_continue() != NULL) { 1237 } else if (node->label()->join_for_continue() != NULL) {
1236 // Insert join between body and increment. 1238 // Insert join between body and increment.
1237 if (for_body.is_open()) { 1239 if (for_body.is_open()) {
1238 for_body.exit()->SetSuccessor(node->label()->join_for_continue()); 1240 for_body.exit()->set_successor(node->label()->join_for_continue());
1239 } 1241 }
1240 for_increment.AddInstruction(node->label()->join_for_continue()); 1242 for_increment.AddInstruction(node->label()->join_for_continue());
1241 node->increment()->Visit(&for_increment); 1243 node->increment()->Visit(&for_increment);
1242 loop_increment_end = for_increment.exit(); 1244 loop_increment_end = for_increment.exit();
1243 ASSERT(loop_increment_end != NULL); 1245 ASSERT(loop_increment_end != NULL);
1244 } else { 1246 } else {
1245 loop_increment_end = NULL; 1247 loop_increment_end = NULL;
1246 ASSERT(!for_body.is_open() && node->label()->join_for_continue() == NULL); 1248 ASSERT(!for_body.is_open() && node->label()->join_for_continue() == NULL);
1247 } 1249 }
1248 1250
1249 // 'loop_increment_end' is NULL only if there is no join for continue and the 1251 // 'loop_increment_end' is NULL only if there is no join for continue and the
1250 // body is not open, i.e., no backward branch exists. 1252 // body is not open, i.e., no backward branch exists.
1251 if (loop_increment_end != NULL) { 1253 if (loop_increment_end != NULL) {
1252 JoinEntryInstr* loop_start = new JoinEntryInstr(); 1254 JoinEntryInstr* loop_start = new JoinEntryInstr();
1253 AddInstruction(loop_start); 1255 AddInstruction(loop_start);
1254 loop_increment_end->SetSuccessor(loop_start); 1256 loop_increment_end->set_successor(loop_start);
1255 } 1257 }
1256 1258
1257 if (node->condition() == NULL) { 1259 if (node->condition() == NULL) {
1258 // Endless loop, no test. 1260 // Endless loop, no test.
1259 Append(for_body); 1261 Append(for_body);
1260 if (node->label()->join_for_break() == NULL) { 1262 if (node->label()->join_for_break() == NULL) {
1261 CloseFragment(); 1263 CloseFragment();
1262 } else { 1264 } else {
1263 // Control flow of ForLoop continues into join_for_break. 1265 // Control flow of ForLoop continues into join_for_break.
1264 exit_ = node->label()->join_for_break(); 1266 exit_ = node->label()->join_for_break();
1265 } 1267 }
1266 } else { 1268 } else {
1267 TargetEntryInstr* loop_exit = new TargetEntryInstr(); 1269 TargetEntryInstr* loop_exit = new TargetEntryInstr();
1268 TestGraphVisitor for_test(owner(), 1270 TestGraphVisitor for_test(owner(),
1269 temp_index(), 1271 temp_index(),
1270 node->condition()->token_pos()); 1272 node->condition()->token_pos());
1271 node->condition()->Visit(&for_test); 1273 node->condition()->Visit(&for_test);
1272 Append(for_test); 1274 Append(for_test);
1273 *for_test.true_successor_address() = body_entry; 1275 *for_test.true_successor_address() = body_entry;
1274 *for_test.false_successor_address() = loop_exit; 1276 *for_test.false_successor_address() = loop_exit;
1275 if (node->label()->join_for_break() == NULL) { 1277 if (node->label()->join_for_break() == NULL) {
1276 exit_ = loop_exit; 1278 exit_ = loop_exit;
1277 } else { 1279 } else {
1278 loop_exit->SetSuccessor(node->label()->join_for_break()); 1280 loop_exit->set_successor(node->label()->join_for_break());
1279 exit_ = node->label()->join_for_break(); 1281 exit_ = node->label()->join_for_break();
1280 } 1282 }
1281 } 1283 }
1282 } 1284 }
1283 1285
1284 1286
1285 void EffectGraphVisitor::VisitJumpNode(JumpNode* node) { 1287 void EffectGraphVisitor::VisitJumpNode(JumpNode* node) {
1286 for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) { 1288 for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) {
1287 EffectGraphVisitor for_effect(owner(), temp_index()); 1289 EffectGraphVisitor for_effect(owner(), temp_index());
1288 node->InlinedFinallyNodeAt(i)->Visit(&for_effect); 1290 node->InlinedFinallyNodeAt(i)->Visit(&for_effect);
(...skipping 1092 matching lines...) Expand 10 before | Expand all | Expand 10 after
2381 &postorder_block_entries_, 2383 &postorder_block_entries_,
2382 &parent, 2384 &parent,
2383 &assigned_vars, 2385 &assigned_vars,
2384 variable_count); 2386 variable_count);
2385 // Number blocks in reverse postorder. 2387 // Number blocks in reverse postorder.
2386 intptr_t block_count = postorder_block_entries_.length(); 2388 intptr_t block_count = postorder_block_entries_.length();
2387 for (intptr_t i = 0; i < block_count; ++i) { 2389 for (intptr_t i = 0; i < block_count; ++i) {
2388 postorder_block_entries_[i]->set_block_id(block_count - i - 1); 2390 postorder_block_entries_[i]->set_block_id(block_count - i - 1);
2389 } 2391 }
2390 if (for_optimized && use_ssa) { 2392 if (for_optimized && use_ssa) {
2393 // Link instructions backwards for optimized compilation.
2394 for (intptr_t i = 0; i < block_count; ++i) {
2395 Instruction* prev = postorder_block_entries_[i];
2396 Instruction* current = prev->successor();
2397 while (current != NULL && !current->IsBlockEntry()) {
2398 current->set_previous(prev);
2399 prev = current;
2400 current = current->successor();
2401 }
2402 }
2391 GrowableArray<BitVector*> dominance_frontier; 2403 GrowableArray<BitVector*> dominance_frontier;
2392 ComputeDominators(&preorder_block_entries_, &parent, &dominance_frontier); 2404 ComputeDominators(&preorder_block_entries_, &parent, &dominance_frontier);
2393 InsertPhis(preorder_block_entries_, 2405 InsertPhis(preorder_block_entries_,
2394 assigned_vars, 2406 assigned_vars,
2395 variable_count, 2407 variable_count,
2396 dominance_frontier); 2408 dominance_frontier);
2397 Rename(variable_count); 2409 Rename(variable_count);
2398 } 2410 }
2399 if (FLAG_print_flow_graph || (Dart::flow_graph_writer() != NULL)) { 2411 if (FLAG_print_flow_graph || (Dart::flow_graph_writer() != NULL)) {
2400 intptr_t length = postorder_block_entries_.length(); 2412 intptr_t length = postorder_block_entries_.length();
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
2648 PhiInstr* phi = (*join->phis())[i]; 2660 PhiInstr* phi = (*join->phis())[i];
2649 if (phi != NULL) { 2661 if (phi != NULL) {
2650 (*env)[i] = new UseVal(phi); 2662 (*env)[i] = new UseVal(phi);
2651 phi->set_ssa_temp_index(current_ssa_temp_index_++); // New SSA temp. 2663 phi->set_ssa_temp_index(current_ssa_temp_index_++); // New SSA temp.
2652 } 2664 }
2653 } 2665 }
2654 } 2666 }
2655 } 2667 }
2656 2668
2657 // 2. Process normal instructions. 2669 // 2. Process normal instructions.
2658 Instruction* current = block_entry->StraightLineSuccessor(); 2670 Instruction* current = block_entry->successor();
2659 Instruction* prev = block_entry;
2660 while ((current != NULL) && !current->IsBlockEntry()) { 2671 while ((current != NULL) && !current->IsBlockEntry()) {
2661 // 2a. Handle uses of LoadLocal / StoreLocal 2672 // 2a. Handle uses of LoadLocal / StoreLocal
2662 // For each use of a LoadLocal or StoreLocal: Replace it with the value 2673 // For each use of a LoadLocal or StoreLocal: Replace it with the value
2663 // from the environment. 2674 // from the environment.
2664 for (intptr_t i = 0; i < current->InputCount(); ++i) { 2675 for (intptr_t i = 0; i < current->InputCount(); ++i) {
2665 Value* v = current->InputAt(i); 2676 Value* v = current->InputAt(i);
2666 if (v->IsUse() && 2677 if (v->IsUse() &&
2667 v->AsUse()->definition()->IsBind() && 2678 v->AsUse()->definition()->IsBind() &&
2668 v->AsUse()->definition()->AsBind()->computation()->IsLoadLocal()) { 2679 v->AsUse()->definition()->AsBind()->computation()->IsLoadLocal()) {
2669 Computation* comp = v->AsUse()->definition()->AsBind()->computation(); 2680 Computation* comp = v->AsUse()->definition()->AsBind()->computation();
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
2705 if (current->IsDo() && 2716 if (current->IsDo() &&
2706 current->AsDo()->computation()->IsStoreLocal()) { 2717 current->AsDo()->computation()->IsStoreLocal()) {
2707 store = current->AsDo()->computation()->AsStoreLocal(); 2718 store = current->AsDo()->computation()->AsStoreLocal();
2708 } else if (current->IsBind() && 2719 } else if (current->IsBind() &&
2709 current->AsBind()->computation()->IsStoreLocal()) { 2720 current->AsBind()->computation()->IsStoreLocal()) {
2710 store = current->AsBind()->computation()->AsStoreLocal(); 2721 store = current->AsBind()->computation()->AsStoreLocal();
2711 } 2722 }
2712 2723
2713 if (load != NULL) { 2724 if (load != NULL) {
2714 // Remove instruction. 2725 // Remove instruction.
2715 prev->SetSuccessor(current->StraightLineSuccessor()); 2726 current->RemoveFromGraph();
2716 } else if (store != NULL) { 2727 } else if (store != NULL) {
2717 // Remove instruction and update renaming environment. 2728 // Remove instruction and update renaming environment.
2718 prev->SetSuccessor(current->StraightLineSuccessor()); 2729 current->RemoveFromGraph();
2719 (*env)[store->local().BitIndexIn(var_count)] = store->value(); 2730 (*env)[store->local().BitIndexIn(var_count)] = store->value();
2720 } else { 2731 } else if (current->IsBind()) {
2721 // Assign new SSA temporary. 2732 // Assign new SSA temporary.
2722 if (current->IsBind()) { 2733 current->AsDefinition()->set_ssa_temp_index(current_ssa_temp_index_++);
2723 current->AsDefinition()->set_ssa_temp_index(current_ssa_temp_index_++);
2724 }
2725 // Update previous only if no instruction was removed from the graph.
2726 prev = current;
2727 } 2734 }
2728 current = current->StraightLineSuccessor(); 2735 current = current->successor();
2729 } 2736 }
2730 2737
2731 // 3. Process dominated blocks. 2738 // 3. Process dominated blocks.
2732 for (intptr_t i = 0; i < block_entry->dominated_blocks().length(); ++i) { 2739 for (intptr_t i = 0; i < block_entry->dominated_blocks().length(); ++i) {
2733 BlockEntryInstr* block = block_entry->dominated_blocks()[i]; 2740 BlockEntryInstr* block = block_entry->dominated_blocks()[i];
2734 ZoneGrowableArray<Value*>* new_env = 2741 ZoneGrowableArray<Value*>* new_env =
2735 new ZoneGrowableArray<Value*>(var_count); 2742 new ZoneGrowableArray<Value*>(var_count);
2736 new_env->AddArray(*env); 2743 new_env->AddArray(*env);
2737 RenameRecursive(block, new_env, var_count); 2744 RenameRecursive(block, new_env, var_count);
2738 } 2745 }
(...skipping 28 matching lines...) Expand all
2767 char* chars = reinterpret_cast<char*>( 2774 char* chars = reinterpret_cast<char*>(
2768 Isolate::Current()->current_zone()->Allocate(len)); 2775 Isolate::Current()->current_zone()->Allocate(len));
2769 OS::SNPrint(chars, len, kFormat, function_name, reason); 2776 OS::SNPrint(chars, len, kFormat, function_name, reason);
2770 const Error& error = Error::Handle( 2777 const Error& error = Error::Handle(
2771 LanguageError::New(String::Handle(String::New(chars)))); 2778 LanguageError::New(String::Handle(String::New(chars))));
2772 Isolate::Current()->long_jump_base()->Jump(1, error); 2779 Isolate::Current()->long_jump_base()->Jump(1, error);
2773 } 2780 }
2774 2781
2775 2782
2776 } // namespace dart 2783 } // namespace dart
OLDNEW
« no previous file with comments | « vm/flow_graph_allocator.cc ('k') | vm/flow_graph_compiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698