Chromium Code Reviews| 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 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 96 if (use == NULL) continue; | 96 if (use == NULL) continue; |
| 97 use->set_instruction(NULL); | 97 use->set_instruction(NULL); |
| 98 use->set_use_index(-1); | 98 use->set_use_index(-1); |
| 99 use->set_next_use(NULL); | 99 use->set_next_use(NULL); |
| 100 } | 100 } |
| 101 } | 101 } |
| 102 } | 102 } |
| 103 | 103 |
| 104 | 104 |
| 105 bool FlowGraph::ResetUseLists() { | 105 bool FlowGraph::ResetUseLists() { |
| 106 // Reset global constants. | |
| 107 ResetUseListsInInstruction(graph_entry_->constant_null()); | |
| 108 | |
| 106 // Reset definitions referenced from the start environment. | 109 // Reset definitions referenced from the start environment. |
| 107 for (intptr_t i = 0; i < graph_entry_->start_env()->values().length(); ++i) { | 110 for (intptr_t i = 0; i < graph_entry_->start_env()->values().length(); ++i) { |
| 108 UseVal* env_use = graph_entry_->start_env()->values()[i]->AsUse(); | 111 UseVal* env_use = graph_entry_->start_env()->values()[i]->AsUse(); |
| 109 if (env_use != NULL) ResetUseListsInInstruction(env_use->definition()); | 112 if (env_use != NULL) ResetUseListsInInstruction(env_use->definition()); |
| 110 } | 113 } |
| 114 | |
| 111 // Reset phis in join entries and the instructions in each block. | 115 // Reset phis in join entries and the instructions in each block. |
| 112 for (intptr_t i = 0; i < preorder_.length(); ++i) { | 116 for (intptr_t i = 0; i < preorder_.length(); ++i) { |
| 113 BlockEntryInstr* entry = preorder_[i]; | 117 BlockEntryInstr* entry = preorder_[i]; |
| 114 JoinEntryInstr* join = entry->AsJoinEntry(); | 118 JoinEntryInstr* join = entry->AsJoinEntry(); |
| 115 if (join != NULL && join->phis() != NULL) { | 119 if (join != NULL && join->phis() != NULL) { |
| 116 for (intptr_t i = 0; i < join->phis()->length(); ++i) { | 120 for (intptr_t i = 0; i < join->phis()->length(); ++i) { |
| 117 PhiInstr* phi = (*join->phis())[i]; | 121 PhiInstr* phi = (*join->phis())[i]; |
| 118 if (phi != NULL) ResetUseListsInInstruction(phi); | 122 if (phi != NULL) ResetUseListsInInstruction(phi); |
| 119 } | 123 } |
| 120 } | 124 } |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 156 use != NULL; | 160 use != NULL; |
| 157 use = use->next_use()) { | 161 use = use->next_use()) { |
| 158 ASSERT(defn == use->definition()); | 162 ASSERT(defn == use->definition()); |
| 159 ASSERT(use == use->instruction()->env()->values()[use->use_index()]); | 163 ASSERT(use == use->instruction()->env()->values()[use->use_index()]); |
| 160 } | 164 } |
| 161 } | 165 } |
| 162 } | 166 } |
| 163 | 167 |
| 164 | 168 |
| 165 bool FlowGraph::ValidateUseLists() { | 169 bool FlowGraph::ValidateUseLists() { |
| 170 // Validate global constants. | |
| 171 ValidateUseListsInInstruction(graph_entry_->constant_null()); | |
| 172 | |
| 166 // Validate definitions referenced from the start environment. | 173 // Validate definitions referenced from the start environment. |
| 167 for (intptr_t i = 0; i < graph_entry_->start_env()->values().length(); ++i) { | 174 for (intptr_t i = 0; i < graph_entry_->start_env()->values().length(); ++i) { |
| 168 UseVal* env_use = graph_entry_->start_env()->values()[i]->AsUse(); | 175 UseVal* env_use = graph_entry_->start_env()->values()[i]->AsUse(); |
| 169 if (env_use != NULL) ValidateUseListsInInstruction(env_use->definition()); | 176 if (env_use != NULL) ValidateUseListsInInstruction(env_use->definition()); |
| 170 } | 177 } |
| 178 | |
| 171 // Validate phis in join entries and the instructions in each block. | 179 // Validate phis in join entries and the instructions in each block. |
| 172 for (intptr_t i = 0; i < preorder_.length(); ++i) { | 180 for (intptr_t i = 0; i < preorder_.length(); ++i) { |
| 173 BlockEntryInstr* entry = preorder_[i]; | 181 BlockEntryInstr* entry = preorder_[i]; |
| 174 JoinEntryInstr* join = entry->AsJoinEntry(); | 182 JoinEntryInstr* join = entry->AsJoinEntry(); |
| 175 if (join != NULL && join->phis() != NULL) { | 183 if (join != NULL && join->phis() != NULL) { |
| 176 for (intptr_t i = 0; i < join->phis()->length(); ++i) { | 184 for (intptr_t i = 0; i < join->phis()->length(); ++i) { |
| 177 PhiInstr* phi = (*join->phis())[i]; | 185 PhiInstr* phi = (*join->phis())[i]; |
| 178 if (phi != NULL) ValidateUseListsInInstruction(phi); | 186 if (phi != NULL) ValidateUseListsInInstruction(phi); |
| 179 } | 187 } |
| 180 } | 188 } |
| (...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 475 } | 483 } |
| 476 } | 484 } |
| 477 | 485 |
| 478 | 486 |
| 479 void FlowGraph::Rename(GrowableArray<PhiInstr*>* live_phis) { | 487 void FlowGraph::Rename(GrowableArray<PhiInstr*>* live_phis) { |
| 480 // TODO(fschneider): Support catch-entry. | 488 // TODO(fschneider): Support catch-entry. |
| 481 if (graph_entry_->SuccessorCount() > 1) { | 489 if (graph_entry_->SuccessorCount() > 1) { |
| 482 Bailout("Catch-entry support in SSA."); | 490 Bailout("Catch-entry support in SSA."); |
| 483 } | 491 } |
| 484 | 492 |
| 493 // Name global constants. | |
| 494 graph_entry_->constant_null()->set_ssa_temp_index(alloc_ssa_temp_index()); | |
| 495 | |
| 485 // Initialize start environment. | 496 // Initialize start environment. |
| 486 GrowableArray<Definition*> start_env(variable_count()); | 497 GrowableArray<Definition*> start_env(variable_count()); |
| 487 for (intptr_t i = 0; i < parameter_count(); ++i) { | 498 for (intptr_t i = 0; i < parameter_count(); ++i) { |
| 488 ParameterInstr* param = new ParameterInstr(i); | 499 ParameterInstr* param = new ParameterInstr(i); |
| 489 param->set_ssa_temp_index(alloc_ssa_temp_index()); // New SSA temp. | 500 param->set_ssa_temp_index(alloc_ssa_temp_index()); // New SSA temp. |
| 490 start_env.Add(param); | 501 start_env.Add(param); |
| 491 } | 502 } |
| 492 | 503 |
| 493 // All locals are initialized with #null. | 504 // All locals are initialized with #null. Use the global definition, uses |
| 494 Definition* null_defn = | 505 // will be created in the Environment constructor. |
| 495 new BindInstr(BindInstr::kUsed, | |
| 496 new MaterializeComp(new ConstantVal(Object::ZoneHandle()))); | |
| 497 // The null definition should not appear in input positions. | |
| 498 ASSERT(null_defn->ssa_temp_index() == -1); | |
| 499 while (start_env.length() < variable_count()) { | 506 while (start_env.length() < variable_count()) { |
| 500 start_env.Add(null_defn); | 507 start_env.Add(graph_entry_->constant_null()); |
|
Kevin Millikin (Google)
2012/08/29 09:56:00
This is a bit dodgy, because there are now multipl
| |
| 501 } | 508 } |
| 502 graph_entry_->set_start_env( | 509 graph_entry_->set_start_env( |
| 503 new Environment(start_env, non_copied_parameter_count_)); | 510 new Environment(start_env, non_copied_parameter_count_)); |
| 504 | 511 |
| 505 BlockEntryInstr* normal_entry = graph_entry_->SuccessorAt(0); | 512 BlockEntryInstr* normal_entry = graph_entry_->SuccessorAt(0); |
| 506 ASSERT(normal_entry != NULL); // Must have entry. | 513 ASSERT(normal_entry != NULL); // Must have entry. |
| 507 GrowableArray<Definition*> env(variable_count()); | 514 GrowableArray<Definition*> env(variable_count()); |
| 508 env.AddArray(start_env); | 515 env.AddArray(start_env); |
| 509 RenameRecursive(normal_entry, &env, live_phis); | 516 RenameRecursive(normal_entry, &env, live_phis); |
| 510 } | 517 } |
| 511 | 518 |
| 512 | 519 |
| 513 // Helper to either use the constant value of a definition or the definition. | |
| 514 static Value* UseDefinition(Definition* defn) { | |
| 515 if (defn->IsBind() && defn->AsBind()->computation()->IsMaterialize()) { | |
| 516 return defn->AsBind()->computation()->AsMaterialize()->constant_val(); | |
| 517 } else { | |
| 518 return new UseVal(defn); | |
| 519 } | |
| 520 } | |
| 521 | |
| 522 | |
| 523 void FlowGraph::RenameRecursive(BlockEntryInstr* block_entry, | 520 void FlowGraph::RenameRecursive(BlockEntryInstr* block_entry, |
| 524 GrowableArray<Definition*>* env, | 521 GrowableArray<Definition*>* env, |
| 525 GrowableArray<PhiInstr*>* live_phis) { | 522 GrowableArray<PhiInstr*>* live_phis) { |
| 526 // 1. Process phis first. | 523 // 1. Process phis first. |
| 527 if (block_entry->IsJoinEntry()) { | 524 if (block_entry->IsJoinEntry()) { |
| 528 JoinEntryInstr* join = block_entry->AsJoinEntry(); | 525 JoinEntryInstr* join = block_entry->AsJoinEntry(); |
| 529 if (join->phis() != NULL) { | 526 if (join->phis() != NULL) { |
| 530 for (intptr_t i = 0; i < join->phis()->length(); ++i) { | 527 for (intptr_t i = 0; i < join->phis()->length(); ++i) { |
| 531 PhiInstr* phi = (*join->phis())[i]; | 528 PhiInstr* phi = (*join->phis())[i]; |
| 532 if (phi != NULL) { | 529 if (phi != NULL) { |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 639 block_entry->last_instruction()->SuccessorAt(0)->IsJoinEntry()) { | 636 block_entry->last_instruction()->SuccessorAt(0)->IsJoinEntry()) { |
| 640 JoinEntryInstr* successor = | 637 JoinEntryInstr* successor = |
| 641 block_entry->last_instruction()->SuccessorAt(0)->AsJoinEntry(); | 638 block_entry->last_instruction()->SuccessorAt(0)->AsJoinEntry(); |
| 642 intptr_t pred_index = successor->IndexOfPredecessor(block_entry); | 639 intptr_t pred_index = successor->IndexOfPredecessor(block_entry); |
| 643 ASSERT(pred_index >= 0); | 640 ASSERT(pred_index >= 0); |
| 644 if (successor->phis() != NULL) { | 641 if (successor->phis() != NULL) { |
| 645 for (intptr_t i = 0; i < successor->phis()->length(); ++i) { | 642 for (intptr_t i = 0; i < successor->phis()->length(); ++i) { |
| 646 PhiInstr* phi = (*successor->phis())[i]; | 643 PhiInstr* phi = (*successor->phis())[i]; |
| 647 if (phi != NULL) { | 644 if (phi != NULL) { |
| 648 // Rename input operand. | 645 // Rename input operand. |
| 649 phi->SetInputAt(pred_index, UseDefinition((*env)[i])); | 646 phi->SetInputAt(pred_index, new UseVal((*env)[i])); |
| 650 } | 647 } |
| 651 } | 648 } |
| 652 } | 649 } |
| 653 } | 650 } |
| 654 } | 651 } |
| 655 | 652 |
| 656 | 653 |
| 657 void FlowGraph::MarkLivePhis(GrowableArray<PhiInstr*>* live_phis) { | 654 void FlowGraph::MarkLivePhis(GrowableArray<PhiInstr*>* live_phis) { |
| 658 while (!live_phis->is_empty()) { | 655 while (!live_phis->is_empty()) { |
| 659 PhiInstr* phi = live_phis->Last(); | 656 PhiInstr* phi = live_phis->Last(); |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 677 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; | 674 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; |
| 678 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); | 675 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); |
| 679 OS::SNPrint(chars, len, kFormat, function_name, reason); | 676 OS::SNPrint(chars, len, kFormat, function_name, reason); |
| 680 const Error& error = Error::Handle( | 677 const Error& error = Error::Handle( |
| 681 LanguageError::New(String::Handle(String::New(chars)))); | 678 LanguageError::New(String::Handle(String::New(chars)))); |
| 682 Isolate::Current()->long_jump_base()->Jump(1, error); | 679 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 683 } | 680 } |
| 684 | 681 |
| 685 | 682 |
| 686 } // namespace dart | 683 } // namespace dart |
| OLD | NEW |