| 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/longjump.h" | 10 #include "vm/longjump.h" |
| (...skipping 18 matching lines...) Expand all Loading... |
| 29 graph_entry_(graph_entry), | 29 graph_entry_(graph_entry), |
| 30 preorder_(), | 30 preorder_(), |
| 31 postorder_(), | 31 postorder_(), |
| 32 reverse_postorder_(), | 32 reverse_postorder_(), |
| 33 exits_(NULL), | 33 exits_(NULL), |
| 34 invalid_dominator_tree_(true) { | 34 invalid_dominator_tree_(true) { |
| 35 DiscoverBlocks(); | 35 DiscoverBlocks(); |
| 36 } | 36 } |
| 37 | 37 |
| 38 | 38 |
| 39 ConstantInstr* FlowGraph::AddConstantToInitialDefinitions( |
| 40 const Object& object) { |
| 41 // Check if the constant is already in the pool. |
| 42 for (intptr_t i = 0; i < graph_entry_->initial_definitions()->length(); ++i) { |
| 43 ConstantInstr* constant = |
| 44 (*graph_entry_->initial_definitions())[i]->AsConstant(); |
| 45 if ((constant != NULL) && (constant->value().raw() == object.raw())) { |
| 46 return constant; |
| 47 } |
| 48 } |
| 49 // Otherwise, allocate and add it to the pool. |
| 50 ConstantInstr* constant = new ConstantInstr(object); |
| 51 constant->set_ssa_temp_index(alloc_ssa_temp_index()); |
| 52 graph_entry_->initial_definitions()->Add(constant); |
| 53 return constant; |
| 54 } |
| 55 |
| 56 |
| 39 void FlowGraph::DiscoverBlocks() { | 57 void FlowGraph::DiscoverBlocks() { |
| 40 // Initialize state. | 58 // Initialize state. |
| 41 preorder_.Clear(); | 59 preorder_.Clear(); |
| 42 postorder_.Clear(); | 60 postorder_.Clear(); |
| 43 reverse_postorder_.Clear(); | 61 reverse_postorder_.Clear(); |
| 44 parent_.Clear(); | 62 parent_.Clear(); |
| 45 assigned_vars_.Clear(); | 63 assigned_vars_.Clear(); |
| 46 // Perform a depth-first traversal of the graph to build preorder and | 64 // Perform a depth-first traversal of the graph to build preorder and |
| 47 // postorder block orders. | 65 // postorder block orders. |
| 48 graph_entry_->DiscoverBlocks(NULL, // Entry block predecessor. | 66 graph_entry_->DiscoverBlocks(NULL, // Entry block predecessor. |
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 275 DEBUG_ASSERT(ResetUseLists()); | 293 DEBUG_ASSERT(ResetUseLists()); |
| 276 // Clear initial definitions. | 294 // Clear initial definitions. |
| 277 for (intptr_t i = 0; i < graph_entry_->initial_definitions()->length(); ++i) { | 295 for (intptr_t i = 0; i < graph_entry_->initial_definitions()->length(); ++i) { |
| 278 ClearUseLists((*graph_entry_->initial_definitions())[i]); | 296 ClearUseLists((*graph_entry_->initial_definitions())[i]); |
| 279 } | 297 } |
| 280 ComputeUseListsRecursive(graph_entry_); | 298 ComputeUseListsRecursive(graph_entry_); |
| 281 DEBUG_ASSERT(!FLAG_verify_compiler || ValidateUseLists()); | 299 DEBUG_ASSERT(!FLAG_verify_compiler || ValidateUseLists()); |
| 282 } | 300 } |
| 283 | 301 |
| 284 | 302 |
| 285 void FlowGraph::ComputeSSA(intptr_t next_virtual_register_number) { | 303 void FlowGraph::ComputeSSA(intptr_t next_virtual_register_number, |
| 304 GrowableArray<Definition*>* inlining_parameters) { |
| 305 ASSERT((next_virtual_register_number == 0) || (inlining_parameters != NULL)); |
| 286 current_ssa_temp_index_ = next_virtual_register_number; | 306 current_ssa_temp_index_ = next_virtual_register_number; |
| 287 GrowableArray<BitVector*> dominance_frontier; | 307 GrowableArray<BitVector*> dominance_frontier; |
| 288 ComputeDominators(&dominance_frontier); | 308 ComputeDominators(&dominance_frontier); |
| 289 InsertPhis(preorder_, assigned_vars_, dominance_frontier); | 309 InsertPhis(preorder_, assigned_vars_, dominance_frontier); |
| 290 GrowableArray<PhiInstr*> live_phis; | 310 GrowableArray<PhiInstr*> live_phis; |
| 291 // Rename uses to reference inserted phis where appropriate. | 311 // Rename uses to reference inserted phis where appropriate. |
| 292 // Collect phis that reach a non-environment use. | 312 // Collect phis that reach a non-environment use. |
| 293 Rename(&live_phis); | 313 Rename(&live_phis, inlining_parameters); |
| 294 // Propagate alive mark transitively from alive phis. | 314 // Propagate alive mark transitively from alive phis. |
| 295 MarkLivePhis(&live_phis); | 315 MarkLivePhis(&live_phis); |
| 296 } | 316 } |
| 297 | 317 |
| 298 | 318 |
| 299 // Compute immediate dominators and the dominance frontier for each basic | 319 // Compute immediate dominators and the dominance frontier for each basic |
| 300 // block. As a side effect of the algorithm, sets the immediate dominator | 320 // block. As a side effect of the algorithm, sets the immediate dominator |
| 301 // of each basic block. | 321 // of each basic block. |
| 302 // | 322 // |
| 303 // dominance_frontier: an output parameter encoding the dominance frontier. | 323 // dominance_frontier: an output parameter encoding the dominance frontier. |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 464 work[index] = var_index; | 484 work[index] = var_index; |
| 465 worklist.Add(block); | 485 worklist.Add(block); |
| 466 } | 486 } |
| 467 } | 487 } |
| 468 } | 488 } |
| 469 } | 489 } |
| 470 } | 490 } |
| 471 } | 491 } |
| 472 | 492 |
| 473 | 493 |
| 474 void FlowGraph::Rename(GrowableArray<PhiInstr*>* live_phis) { | 494 void FlowGraph::Rename(GrowableArray<PhiInstr*>* live_phis, |
| 495 GrowableArray<Definition*>* inlining_parameters) { |
| 475 // TODO(fschneider): Support catch-entry. | 496 // TODO(fschneider): Support catch-entry. |
| 476 if (graph_entry_->SuccessorCount() > 1) { | 497 if (graph_entry_->SuccessorCount() > 1) { |
| 477 Bailout("Catch-entry support in SSA."); | 498 Bailout("Catch-entry support in SSA."); |
| 478 } | 499 } |
| 479 | 500 |
| 480 // Initial renaming environment. | 501 // Initial renaming environment. |
| 481 GrowableArray<Definition*> env(variable_count()); | 502 GrowableArray<Definition*> env(variable_count()); |
| 482 | 503 |
| 483 // Add global constants to the initial definitions. | 504 // Add global constants to the initial definitions. |
| 484 ConstantInstr* constant_null = new ConstantInstr(Object::ZoneHandle()); | 505 ConstantInstr* constant_null = new ConstantInstr(Object::ZoneHandle()); |
| 485 constant_null->set_ssa_temp_index(alloc_ssa_temp_index()); | 506 constant_null->set_ssa_temp_index(alloc_ssa_temp_index()); |
| 486 graph_entry_->initial_definitions()->Add(constant_null); | 507 graph_entry_->initial_definitions()->Add(constant_null); |
| 487 | 508 |
| 488 // Add incoming parameters to the initial definitions and the renaming | 509 // Add parameters to the initial definitions and renaming environment. |
| 489 // environment. | 510 if (inlining_parameters != NULL) { |
| 490 for (intptr_t i = 0; i < parameter_count(); ++i) { | 511 // Use known parameters. |
| 491 ParameterInstr* param = new ParameterInstr(i, graph_entry_); | 512 ASSERT(parameter_count() == inlining_parameters->length()); |
| 492 param->set_ssa_temp_index(alloc_ssa_temp_index()); // New SSA temp. | 513 for (intptr_t i = 0; i < parameter_count(); ++i) { |
| 493 graph_entry_->initial_definitions()->Add(param); | 514 Definition* defn = (*inlining_parameters)[i]; |
| 494 env.Add(param); | 515 defn->set_ssa_temp_index(alloc_ssa_temp_index()); // New SSA temp. |
| 516 graph_entry_->initial_definitions()->Add(defn); |
| 517 env.Add(defn); |
| 518 } |
| 519 } else { |
| 520 // Create new parameters. |
| 521 for (intptr_t i = 0; i < parameter_count(); ++i) { |
| 522 ParameterInstr* param = new ParameterInstr(i, graph_entry_); |
| 523 param->set_ssa_temp_index(alloc_ssa_temp_index()); // New SSA temp. |
| 524 graph_entry_->initial_definitions()->Add(param); |
| 525 env.Add(param); |
| 526 } |
| 495 } | 527 } |
| 496 | 528 |
| 497 // Initialize all locals with #null in the renaming environment. | 529 // Initialize all locals with #null in the renaming environment. |
| 498 for (intptr_t i = parameter_count(); i < variable_count(); ++i) { | 530 for (intptr_t i = parameter_count(); i < variable_count(); ++i) { |
| 499 env.Add(constant_null); | 531 env.Add(constant_null); |
| 500 } | 532 } |
| 501 | 533 |
| 502 BlockEntryInstr* normal_entry = graph_entry_->SuccessorAt(0); | 534 BlockEntryInstr* normal_entry = graph_entry_->SuccessorAt(0); |
| 503 ASSERT(normal_entry != NULL); // Must have entry. | 535 ASSERT(normal_entry != NULL); // Must have entry. |
| 504 RenameRecursive(normal_entry, &env, live_phis); | 536 RenameRecursive(normal_entry, &env, live_phis); |
| (...skipping 465 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 970 !it.Done(); | 1002 !it.Done(); |
| 971 it.Advance()) { | 1003 it.Advance()) { |
| 972 ++size; | 1004 ++size; |
| 973 } | 1005 } |
| 974 } | 1006 } |
| 975 return size; | 1007 return size; |
| 976 } | 1008 } |
| 977 | 1009 |
| 978 | 1010 |
| 979 } // namespace dart | 1011 } // namespace dart |
| OLD | NEW |