| 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 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 98 Value* use = it.CurrentValue(); | 98 Value* use = it.CurrentValue(); |
| 99 use->set_instruction(NULL); | 99 use->set_instruction(NULL); |
| 100 use->set_use_index(-1); | 100 use->set_use_index(-1); |
| 101 use->set_next_use(NULL); | 101 use->set_next_use(NULL); |
| 102 } | 102 } |
| 103 } | 103 } |
| 104 } | 104 } |
| 105 | 105 |
| 106 | 106 |
| 107 bool FlowGraph::ResetUseLists() { | 107 bool FlowGraph::ResetUseLists() { |
| 108 // Reset global constants. | 108 // Reset initial definitions. |
| 109 ResetUseListsInInstruction(graph_entry_->constant_null()); | 109 for (intptr_t i = 0; i < graph_entry_->initial_definitions()->length(); ++i) { |
| 110 | 110 ResetUseListsInInstruction((*graph_entry_->initial_definitions())[i]); |
| 111 // Reset definitions referenced from the start environment. | |
| 112 for (intptr_t i = 0; i < graph_entry_->start_env()->Length(); ++i) { | |
| 113 Value* env_use = graph_entry_->start_env()->ValueAt(i); | |
| 114 ResetUseListsInInstruction(env_use->definition()); | |
| 115 } | 111 } |
| 116 | 112 |
| 117 // Reset phis in join entries and the instructions in each block. | 113 // Reset phis in join entries and the instructions in each block. |
| 118 for (intptr_t i = 0; i < preorder_.length(); ++i) { | 114 for (intptr_t i = 0; i < preorder_.length(); ++i) { |
| 119 BlockEntryInstr* entry = preorder_[i]; | 115 BlockEntryInstr* entry = preorder_[i]; |
| 120 JoinEntryInstr* join = entry->AsJoinEntry(); | 116 JoinEntryInstr* join = entry->AsJoinEntry(); |
| 121 if (join != NULL && join->phis() != NULL) { | 117 if (join != NULL && join->phis() != NULL) { |
| 122 for (intptr_t i = 0; i < join->phis()->length(); ++i) { | 118 for (intptr_t i = 0; i < join->phis()->length(); ++i) { |
| 123 PhiInstr* phi = (*join->phis())[i]; | 119 PhiInstr* phi = (*join->phis())[i]; |
| 124 if (phi != NULL) ResetUseListsInInstruction(phi); | 120 if (phi != NULL) ResetUseListsInInstruction(phi); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 161 use = use->next_use()) { | 157 use = use->next_use()) { |
| 162 ASSERT(defn == use->definition()); | 158 ASSERT(defn == use->definition()); |
| 163 ASSERT(use == | 159 ASSERT(use == |
| 164 use->instruction()->env()->ValueAtUseIndex(use->use_index())); | 160 use->instruction()->env()->ValueAtUseIndex(use->use_index())); |
| 165 } | 161 } |
| 166 } | 162 } |
| 167 } | 163 } |
| 168 | 164 |
| 169 | 165 |
| 170 bool FlowGraph::ValidateUseLists() { | 166 bool FlowGraph::ValidateUseLists() { |
| 171 // Validate global constants. | 167 // Validate initial definitions. |
| 172 ValidateUseListsInInstruction(graph_entry_->constant_null()); | 168 for (intptr_t i = 0; i < graph_entry_->initial_definitions()->length(); ++i) { |
| 173 | 169 ValidateUseListsInInstruction((*graph_entry_->initial_definitions())[i]); |
| 174 // Validate definitions referenced from the start environment. | |
| 175 for (intptr_t i = 0; i < graph_entry_->start_env()->Length(); ++i) { | |
| 176 Value* env_use = graph_entry_->start_env()->ValueAt(i); | |
| 177 ValidateUseListsInInstruction(env_use->definition()); | |
| 178 } | 170 } |
| 179 | 171 |
| 180 // Validate phis in join entries and the instructions in each block. | 172 // Validate phis in join entries and the instructions in each block. |
| 181 for (intptr_t i = 0; i < preorder_.length(); ++i) { | 173 for (intptr_t i = 0; i < preorder_.length(); ++i) { |
| 182 BlockEntryInstr* entry = preorder_[i]; | 174 BlockEntryInstr* entry = preorder_[i]; |
| 183 JoinEntryInstr* join = entry->AsJoinEntry(); | 175 JoinEntryInstr* join = entry->AsJoinEntry(); |
| 184 if (join != NULL && join->phis() != NULL) { | 176 if (join != NULL && join->phis() != NULL) { |
| 185 for (intptr_t i = 0; i < join->phis()->length(); ++i) { | 177 for (intptr_t i = 0; i < join->phis()->length(); ++i) { |
| 186 PhiInstr* phi = (*join->phis())[i]; | 178 PhiInstr* phi = (*join->phis())[i]; |
| 187 if (phi != NULL) ValidateUseListsInInstruction(phi); | 179 if (phi != NULL) ValidateUseListsInInstruction(phi); |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 279 use->set_use_index(pred_index); | 271 use->set_use_index(pred_index); |
| 280 use->AddToInputUseList(); | 272 use->AddToInputUseList(); |
| 281 } | 273 } |
| 282 } | 274 } |
| 283 } | 275 } |
| 284 } | 276 } |
| 285 | 277 |
| 286 | 278 |
| 287 void FlowGraph::ComputeUseLists() { | 279 void FlowGraph::ComputeUseLists() { |
| 288 DEBUG_ASSERT(ResetUseLists()); | 280 DEBUG_ASSERT(ResetUseLists()); |
| 289 // Clear global constants and definitions in the start environment. | 281 // Clear initial definitions. |
| 290 ClearUseLists(graph_entry_->constant_null()); | 282 for (intptr_t i = 0; i < graph_entry_->initial_definitions()->length(); ++i) { |
| 291 for (intptr_t i = 0; i < graph_entry_->start_env()->Length(); ++i) { | 283 ClearUseLists((*graph_entry_->initial_definitions())[i]); |
| 292 ClearUseLists(graph_entry_->start_env()->ValueAt(i)->definition()); | |
| 293 } | 284 } |
| 294 ComputeUseListsRecursive(graph_entry_); | 285 ComputeUseListsRecursive(graph_entry_); |
| 295 DEBUG_ASSERT(ValidateUseLists()); | 286 DEBUG_ASSERT(ValidateUseLists()); |
| 296 } | 287 } |
| 297 | 288 |
| 298 | 289 |
| 299 void FlowGraph::ComputeSSA(intptr_t next_virtual_register_number) { | 290 void FlowGraph::ComputeSSA(intptr_t next_virtual_register_number) { |
| 300 current_ssa_temp_index_ = next_virtual_register_number; | 291 current_ssa_temp_index_ = next_virtual_register_number; |
| 301 GrowableArray<BitVector*> dominance_frontier; | 292 GrowableArray<BitVector*> dominance_frontier; |
| 302 ComputeDominators(&preorder_, &parent_, &dominance_frontier); | 293 ComputeDominators(&preorder_, &parent_, &dominance_frontier); |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 488 } | 479 } |
| 489 } | 480 } |
| 490 | 481 |
| 491 | 482 |
| 492 void FlowGraph::Rename(GrowableArray<PhiInstr*>* live_phis) { | 483 void FlowGraph::Rename(GrowableArray<PhiInstr*>* live_phis) { |
| 493 // TODO(fschneider): Support catch-entry. | 484 // TODO(fschneider): Support catch-entry. |
| 494 if (graph_entry_->SuccessorCount() > 1) { | 485 if (graph_entry_->SuccessorCount() > 1) { |
| 495 Bailout("Catch-entry support in SSA."); | 486 Bailout("Catch-entry support in SSA."); |
| 496 } | 487 } |
| 497 | 488 |
| 498 // Name global constants. | 489 // Initial renaming environment. |
| 490 GrowableArray<Definition*> env(variable_count()); |
| 491 |
| 492 // Add global constants to the initial definitions. |
| 499 ConstantInstr* constant_null = new ConstantInstr(Object::ZoneHandle()); | 493 ConstantInstr* constant_null = new ConstantInstr(Object::ZoneHandle()); |
| 500 constant_null->set_ssa_temp_index(alloc_ssa_temp_index()); | 494 constant_null->set_ssa_temp_index(alloc_ssa_temp_index()); |
| 501 graph_entry_->set_constant_null(constant_null); | 495 graph_entry_->initial_definitions()->Add(constant_null); |
| 502 | 496 |
| 503 // Initialize start environment. | 497 // Add incoming parameters to the initial definitions and the renaming |
| 504 GrowableArray<Definition*> start_env(variable_count()); | 498 // environment. |
| 505 for (intptr_t i = 0; i < parameter_count(); ++i) { | 499 for (intptr_t i = 0; i < parameter_count(); ++i) { |
| 506 ParameterInstr* param = new ParameterInstr(i, graph_entry_); | 500 ParameterInstr* param = new ParameterInstr(i, graph_entry_); |
| 507 param->set_ssa_temp_index(alloc_ssa_temp_index()); // New SSA temp. | 501 param->set_ssa_temp_index(alloc_ssa_temp_index()); // New SSA temp. |
| 508 start_env.Add(param); | 502 graph_entry_->initial_definitions()->Add(param); |
| 503 env.Add(param); |
| 509 } | 504 } |
| 510 | 505 |
| 511 // All locals are initialized with #null. Use the global definition, uses | 506 // Initialize all locals with #null in the renaming environment. |
| 512 // will be created in the Environment constructor. | 507 for (intptr_t i = parameter_count(); i < variable_count(); ++i) { |
| 513 while (start_env.length() < variable_count()) { | 508 env.Add(constant_null); |
| 514 start_env.Add(graph_entry_->constant_null()); | |
| 515 } | 509 } |
| 516 graph_entry_->set_start_env( | |
| 517 Environment::From(start_env, | |
| 518 num_non_copied_params_, | |
| 519 parsed_function_.function())); | |
| 520 | 510 |
| 521 BlockEntryInstr* normal_entry = graph_entry_->SuccessorAt(0); | 511 BlockEntryInstr* normal_entry = graph_entry_->SuccessorAt(0); |
| 522 ASSERT(normal_entry != NULL); // Must have entry. | 512 ASSERT(normal_entry != NULL); // Must have entry. |
| 523 GrowableArray<Definition*> env(variable_count()); | |
| 524 env.AddArray(start_env); | |
| 525 RenameRecursive(normal_entry, &env, live_phis); | 513 RenameRecursive(normal_entry, &env, live_phis); |
| 526 } | 514 } |
| 527 | 515 |
| 528 | 516 |
| 529 void FlowGraph::RenameRecursive(BlockEntryInstr* block_entry, | 517 void FlowGraph::RenameRecursive(BlockEntryInstr* block_entry, |
| 530 GrowableArray<Definition*>* env, | 518 GrowableArray<Definition*>* env, |
| 531 GrowableArray<PhiInstr*>* live_phis) { | 519 GrowableArray<PhiInstr*>* live_phis) { |
| 532 // 1. Process phis first. | 520 // 1. Process phis first. |
| 533 if (block_entry->IsJoinEntry()) { | 521 if (block_entry->IsJoinEntry()) { |
| 534 JoinEntryInstr* join = block_entry->AsJoinEntry(); | 522 JoinEntryInstr* join = block_entry->AsJoinEntry(); |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 807 // TODO(zerny): Support multiple exits. | 795 // TODO(zerny): Support multiple exits. |
| 808 UNREACHABLE(); | 796 UNREACHABLE(); |
| 809 } | 797 } |
| 810 | 798 |
| 811 // TODO(zerny): Adjust pre/post orders. | 799 // TODO(zerny): Adjust pre/post orders. |
| 812 // TODO(zerny): Update dominator tree. | 800 // TODO(zerny): Update dominator tree. |
| 813 } | 801 } |
| 814 | 802 |
| 815 | 803 |
| 816 } // namespace dart | 804 } // namespace dart |
| OLD | NEW |