| OLD | NEW |
| 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.h" | 5 #include "vm/flow_graph.h" |
| 6 | 6 |
| 7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
| 8 #include "vm/flow_graph_builder.h" | 8 #include "vm/flow_graph_builder.h" |
| 9 #include "vm/intermediate_language.h" | 9 #include "vm/intermediate_language.h" |
| 10 #include "vm/growable_array.h" | 10 #include "vm/growable_array.h" |
| (...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 216 reverse_postorder_.Add(postorder_[block_count - i - 1]); | 216 reverse_postorder_.Add(postorder_[block_count - i - 1]); |
| 217 } | 217 } |
| 218 | 218 |
| 219 // Block effects are using postorder numbering. Discard computed information. | 219 // Block effects are using postorder numbering. Discard computed information. |
| 220 block_effects_ = NULL; | 220 block_effects_ = NULL; |
| 221 loop_headers_ = NULL; | 221 loop_headers_ = NULL; |
| 222 loop_invariant_loads_ = NULL; | 222 loop_invariant_loads_ = NULL; |
| 223 } | 223 } |
| 224 | 224 |
| 225 | 225 |
| 226 void FlowGraph::MergeBlocks() { |
| 227 bool changed = false; |
| 228 BitVector* merged = new(isolate()) BitVector(isolate(), postorder().length()); |
| 229 for (BlockIterator block_it = reverse_postorder_iterator(); |
| 230 !block_it.Done(); |
| 231 block_it.Advance()) { |
| 232 BlockEntryInstr* block = block_it.Current(); |
| 233 if (block->IsGraphEntry()) continue; |
| 234 if (merged->Contains(block->postorder_number())) continue; |
| 235 |
| 236 Instruction* last = block->last_instruction(); |
| 237 BlockEntryInstr* successor = NULL; |
| 238 while ((last->SuccessorCount() == 1) && |
| 239 (last->SuccessorAt(0)->PredecessorCount() == 1) && |
| 240 (block->try_index() == last->SuccessorAt(0)->try_index())) { |
| 241 successor = last->SuccessorAt(0); |
| 242 ASSERT(last->IsGoto()); |
| 243 |
| 244 // Remove environment uses and unlink goto and block entry. |
| 245 successor->UnuseAllInputs(); |
| 246 last->previous()->LinkTo(successor->next()); |
| 247 last->UnuseAllInputs(); |
| 248 |
| 249 last = successor->last_instruction(); |
| 250 merged->Add(successor->postorder_number()); |
| 251 changed = true; |
| 252 if (FLAG_trace_optimization) { |
| 253 OS::Print("Merged blocks B%" Pd " and B%" Pd "\n", |
| 254 block->block_id(), |
| 255 successor->block_id()); |
| 256 } |
| 257 } |
| 258 // The new block inherits the block id of the last successor to maintain |
| 259 // the order of phi inputs at its successors consistent with block ids. |
| 260 if (successor != NULL) { |
| 261 block->set_block_id(successor->block_id()); |
| 262 } |
| 263 } |
| 264 // Recompute block order after changes were made. |
| 265 if (changed) DiscoverBlocks(); |
| 266 } |
| 267 |
| 268 |
| 226 // Debugging code to verify the construction of use lists. | 269 // Debugging code to verify the construction of use lists. |
| 227 static intptr_t MembershipCount(Value* use, Value* list) { | 270 static intptr_t MembershipCount(Value* use, Value* list) { |
| 228 intptr_t count = 0; | 271 intptr_t count = 0; |
| 229 while (list != NULL) { | 272 while (list != NULL) { |
| 230 if (list == use) ++count; | 273 if (list == use) ++count; |
| 231 list = list->next_use(); | 274 list = list->next_use(); |
| 232 } | 275 } |
| 233 return count; | 276 return count; |
| 234 } | 277 } |
| 235 | 278 |
| (...skipping 1103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1339 } | 1382 } |
| 1340 | 1383 |
| 1341 | 1384 |
| 1342 bool BlockEffects::IsSideEffectFreePath(BlockEntryInstr* from, | 1385 bool BlockEffects::IsSideEffectFreePath(BlockEntryInstr* from, |
| 1343 BlockEntryInstr* to) const { | 1386 BlockEntryInstr* to) const { |
| 1344 return available_at_[to->postorder_number()]->Contains( | 1387 return available_at_[to->postorder_number()]->Contains( |
| 1345 from->postorder_number()); | 1388 from->postorder_number()); |
| 1346 } | 1389 } |
| 1347 | 1390 |
| 1348 } // namespace dart | 1391 } // namespace dart |
| OLD | NEW |