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/intermediate_language.h" | 5 #include "vm/intermediate_language.h" |
| 6 | 6 |
| 7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
| 8 #include "vm/dart_entry.h" | 8 #include "vm/dart_entry.h" |
| 9 #include "vm/flow_graph_allocator.h" | 9 #include "vm/flow_graph_allocator.h" |
| 10 #include "vm/flow_graph_builder.h" | 10 #include "vm/flow_graph_builder.h" |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 141 | 141 |
| 142 const Object& Value::BoundConstant() const { | 142 const Object& Value::BoundConstant() const { |
| 143 ASSERT(BindsToConstant()); | 143 ASSERT(BindsToConstant()); |
| 144 ConstantInstr* constant = definition()->AsConstant(); | 144 ConstantInstr* constant = definition()->AsConstant(); |
| 145 ASSERT(constant != NULL); | 145 ASSERT(constant != NULL); |
| 146 return constant->value(); | 146 return constant->value(); |
| 147 } | 147 } |
| 148 | 148 |
| 149 | 149 |
| 150 GraphEntryInstr::GraphEntryInstr(TargetEntryInstr* normal_entry) | 150 GraphEntryInstr::GraphEntryInstr(TargetEntryInstr* normal_entry) |
| 151 : BlockEntryInstr(CatchClauseNode::kInvalidTryIndex), | 151 : BlockEntryInstr(0, CatchClauseNode::kInvalidTryIndex), |
| 152 normal_entry_(normal_entry), | 152 normal_entry_(normal_entry), |
| 153 catch_entries_(), | 153 catch_entries_(), |
| 154 initial_definitions_(), | 154 initial_definitions_(), |
| 155 spill_slot_count_(0) { | 155 spill_slot_count_(0) { |
| 156 } | 156 } |
| 157 | 157 |
| 158 | 158 |
| 159 ConstantInstr* GraphEntryInstr::constant_null() { | 159 ConstantInstr* GraphEntryInstr::constant_null() { |
| 160 ASSERT(initial_definitions_.length() > 0 && | 160 ASSERT(initial_definitions_.length() > 0 && |
| 161 initial_definitions_[0]->IsConstant() && | 161 initial_definitions_[0]->IsConstant() && |
| (...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 474 // always be wrongly eliminated. | 474 // always be wrongly eliminated. |
| 475 return Type::DynamicType(); | 475 return Type::DynamicType(); |
| 476 } | 476 } |
| 477 | 477 |
| 478 | 478 |
| 479 RawAbstractType* PushArgumentInstr::CompileType() const { | 479 RawAbstractType* PushArgumentInstr::CompileType() const { |
| 480 return AbstractType::null(); | 480 return AbstractType::null(); |
| 481 } | 481 } |
| 482 | 482 |
| 483 | 483 |
| 484 void JoinEntryInstr::AddPredecessor(BlockEntryInstr* predecessor) { | |
| 485 // Require the predecessors to be sorted by block_id to make managing | |
| 486 // their corresponding phi inputs simpler. | |
| 487 intptr_t pred_id = predecessor->block_id(); | |
| 488 intptr_t index = 0; | |
| 489 while ((index < predecessors_.length()) && | |
| 490 (predecessors_[index]->block_id() < pred_id)) { | |
|
Vyacheslav Egorov (Google)
2012/09/21 12:52:59
assert here that there is not block with pred_id i
Kevin Millikin (Google)
2012/09/21 13:08:04
OK.
| |
| 491 ++index; | |
| 492 } | |
| 493 predecessors_.InsertAt(index, predecessor); | |
| 494 } | |
| 495 | |
| 496 | |
| 484 intptr_t JoinEntryInstr::IndexOfPredecessor(BlockEntryInstr* pred) const { | 497 intptr_t JoinEntryInstr::IndexOfPredecessor(BlockEntryInstr* pred) const { |
| 485 for (intptr_t i = 0; i < predecessors_.length(); ++i) { | 498 for (intptr_t i = 0; i < predecessors_.length(); ++i) { |
| 486 if (predecessors_[i] == pred) return i; | 499 if (predecessors_[i] == pred) return i; |
| 487 } | 500 } |
| 488 return -1; | 501 return -1; |
| 489 } | 502 } |
| 490 | 503 |
| 491 | 504 |
| 492 void JoinEntryInstr::EliminateUnreachablePhiInputs() { | |
| 493 if (phis_ == NULL || phis_->is_empty()) return; | |
| 494 | |
| 495 // Loop over the predecessors, reorganize phi inputs. | |
| 496 // TODO(kmillikin): Replace phis that have a single remaining input with | |
| 497 // the input. This requires being a bit careful about use lists. | |
| 498 intptr_t input_count = predecessors_.length(); | |
| 499 for (intptr_t new_idx = 0; new_idx < input_count; ++new_idx) { | |
| 500 BlockEntryInstr* pred = predecessors_[new_idx]; | |
| 501 // Linear search for the old predecessor index. We can't directly | |
| 502 // compare block entries, because unreachable code elimination has | |
| 503 // replaced some targets with joins. | |
| 504 intptr_t old_idx = 0; | |
| 505 for (; old_idx < stale_predecessors_.length(); ++old_idx) { | |
| 506 if (stale_predecessors_[old_idx]->next() == pred->next()) break; | |
| 507 } | |
| 508 ASSERT(old_idx < stale_predecessors_.length()); | |
| 509 // If the index has changed, adjust all phi inputs. | |
| 510 if (old_idx != new_idx) { | |
| 511 ASSERT(new_idx < old_idx); | |
| 512 // Swap each phi's inputs so the input at new_idx is correct. | |
| 513 // Preserve the previous value in case it is from a reachable | |
| 514 // predecessor. | |
| 515 for (intptr_t phi_idx = 0; phi_idx < phis_->length(); ++phi_idx) { | |
| 516 PhiInstr* phi = (*phis_)[phi_idx]; | |
| 517 if (phi == NULL) continue; | |
| 518 Value* temp = phi->InputAt(new_idx); | |
| 519 phi->SetInputAt(new_idx, phi->InputAt(old_idx)); | |
| 520 phi->SetInputAt(old_idx, temp); | |
| 521 } | |
| 522 // The old input at new_idx is now found at old_idx. It may be a | |
| 523 // reachable predecessor so swap the old predecessors too. | |
| 524 BlockEntryInstr* temp = stale_predecessors_[new_idx]; | |
| 525 stale_predecessors_[new_idx] = stale_predecessors_[old_idx]; | |
| 526 stale_predecessors_[old_idx] = temp; | |
| 527 } | |
| 528 } | |
| 529 // Now truncate each phi if necessary. | |
| 530 if (input_count < stale_predecessors_.length()) { | |
| 531 for (intptr_t phi_idx = 0; phi_idx < phis_->length(); ++phi_idx) { | |
| 532 PhiInstr* phi = (*phis_)[phi_idx]; | |
| 533 if (phi == NULL) continue; | |
| 534 phi->inputs_.TruncateTo(input_count); | |
| 535 } | |
| 536 } | |
| 537 } | |
| 538 | |
| 539 | |
| 540 // ==== Recording assigned variables. | 505 // ==== Recording assigned variables. |
| 541 void Definition::RecordAssignedVars(BitVector* assigned_vars, | 506 void Definition::RecordAssignedVars(BitVector* assigned_vars, |
| 542 intptr_t fixed_parameter_count) { | 507 intptr_t fixed_parameter_count) { |
| 543 // Nothing to do for the base class. | 508 // Nothing to do for the base class. |
| 544 } | 509 } |
| 545 | 510 |
| 546 | 511 |
| 547 void StoreLocalInstr::RecordAssignedVars(BitVector* assigned_vars, | 512 void StoreLocalInstr::RecordAssignedVars(BitVector* assigned_vars, |
| 548 intptr_t fixed_parameter_count) { | 513 intptr_t fixed_parameter_count) { |
| 549 if (!local().is_captured()) { | 514 if (!local().is_captured()) { |
| (...skipping 1289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1839 value->set_use_index(use_index++); | 1804 value->set_use_index(use_index++); |
| 1840 value->AddToEnvUseList(); | 1805 value->AddToEnvUseList(); |
| 1841 } | 1806 } |
| 1842 instr->env()->outer_ = copy; | 1807 instr->env()->outer_ = copy; |
| 1843 } | 1808 } |
| 1844 | 1809 |
| 1845 | 1810 |
| 1846 #undef __ | 1811 #undef __ |
| 1847 | 1812 |
| 1848 } // namespace dart | 1813 } // namespace dart |
| OLD | NEW |