Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 608 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 619 } | 619 } |
| 620 } | 620 } |
| 621 | 621 |
| 622 | 622 |
| 623 void Instruction::RecordAssignedVars(BitVector* assigned_vars, | 623 void Instruction::RecordAssignedVars(BitVector* assigned_vars, |
| 624 intptr_t fixed_parameter_count) { | 624 intptr_t fixed_parameter_count) { |
| 625 // Nothing to do for the base class. | 625 // Nothing to do for the base class. |
| 626 } | 626 } |
| 627 | 627 |
| 628 | 628 |
| 629 void Value::AddToInputUseList() { | 629 void Value::AddToList(Value* value, Value** list) { |
| 630 Value* next = definition()->input_use_list(); | 630 Value* next = *list; |
| 631 definition()->set_input_use_list(this); | 631 *list = value; |
| 632 set_next_use(next); | 632 value->set_next_use(next); |
| 633 set_previous_use(NULL); | 633 value->set_previous_use(NULL); |
| 634 if (next != NULL) next->set_previous_use(this); | 634 if (next != NULL) next->set_previous_use(value); |
| 635 } | 635 } |
| 636 | 636 |
| 637 | 637 |
| 638 void Value::AddToEnvUseList() { | 638 void Value::RemoveFromUseList() { |
| 639 Value* next = definition()->env_use_list(); | 639 Definition* def = definition(); |
| 640 definition()->set_env_use_list(this); | 640 Value* next = next_use(); |
| 641 set_next_use(next); | 641 if (this == def->input_use_list()) { |
| 642 def->set_input_use_list(next); | |
| 643 if (next != NULL) next->set_previous_use(NULL); | |
| 644 } else if (this == def->env_use_list()) { | |
| 645 def->set_env_use_list(next); | |
| 646 if (next != NULL) next->set_previous_use(NULL); | |
| 647 } else { | |
| 648 Value* prev = previous_use(); | |
| 649 prev->set_next_use(next); | |
|
Kevin Millikin (Google)
2013/02/01 09:35:24
Here we still assume use lists are coherent. If t
| |
| 650 if (next != NULL) next->set_previous_use(prev); | |
| 651 } | |
| 652 | |
| 653 set_definition(NULL); | |
| 642 set_previous_use(NULL); | 654 set_previous_use(NULL); |
| 643 if (next != NULL) next->set_previous_use(this); | 655 set_next_use(NULL); |
| 644 } | |
| 645 | |
| 646 | |
| 647 void Value::RemoveFromInputUseList() { | |
| 648 Value* previous = previous_use(); | |
| 649 Value* next = next_use(); | |
| 650 if (previous == NULL) { | |
| 651 definition()->set_input_use_list(next); | |
| 652 } else { | |
| 653 previous->set_next_use(next); | |
| 654 } | |
| 655 if (next != NULL) next->set_previous_use(previous); | |
| 656 set_definition(NULL); | |
| 657 } | 656 } |
| 658 | 657 |
| 659 | 658 |
| 660 void Definition::ReplaceUsesWith(Definition* other) { | 659 void Definition::ReplaceUsesWith(Definition* other) { |
| 661 ASSERT(other != NULL); | 660 ASSERT(other != NULL); |
| 662 ASSERT(this != other); | 661 ASSERT(this != other); |
| 662 | |
| 663 Value* current = NULL; | |
| 663 Value* next = input_use_list(); | 664 Value* next = input_use_list(); |
| 664 while (next != NULL) { | 665 if (next != NULL) { |
| 665 Value* current = next; | 666 // Change all the definitions. |
| 666 next = current->next_use(); | 667 while (next != NULL) { |
| 667 current->set_definition(other); | 668 current = next; |
| 668 current->AddToInputUseList(); | 669 current->set_definition(other); |
| 670 next = current->next_use(); | |
| 671 } | |
| 672 | |
| 673 // Concatenate the lists. | |
| 674 next = other->input_use_list(); | |
| 675 current->set_next_use(next); | |
| 676 if (next != NULL) next->set_previous_use(current); | |
| 677 other->set_input_use_list(input_use_list()); | |
| 678 set_input_use_list(NULL); | |
| 669 } | 679 } |
| 670 | 680 |
| 681 // Repeat for environment uses. | |
| 682 current = NULL; | |
| 671 next = env_use_list(); | 683 next = env_use_list(); |
| 672 while (next != NULL) { | 684 if (next != NULL) { |
| 673 Value* current = next; | 685 while (next != NULL) { |
| 674 next = current->next_use(); | 686 current = next; |
| 675 current->set_definition(other); | 687 current->set_definition(other); |
| 676 current->AddToEnvUseList(); | 688 next = current->next_use(); |
| 689 } | |
| 690 next = other->env_use_list(); | |
| 691 current->set_next_use(next); | |
|
Vyacheslav Egorov (Google)
2013/02/01 14:38:19
There is a bit of duplicated code here with above
| |
| 692 if (next != NULL) next->set_previous_use(current); | |
| 693 other->set_env_use_list(env_use_list()); | |
| 694 set_env_use_list(NULL); | |
| 677 } | 695 } |
| 678 | |
| 679 set_input_use_list(NULL); | |
| 680 set_env_use_list(NULL); | |
| 681 } | 696 } |
| 682 | 697 |
| 683 | 698 |
| 684 void Definition::ReplaceWith(Definition* other, | 699 void Definition::ReplaceWith(Definition* other, |
| 685 ForwardInstructionIterator* iterator) { | 700 ForwardInstructionIterator* iterator) { |
| 686 if ((iterator != NULL) && (this == iterator->Current())) { | 701 if ((iterator != NULL) && (this == iterator->Current())) { |
| 687 iterator->ReplaceCurrentWith(other); | 702 iterator->ReplaceCurrentWith(other); |
| 688 } else { | 703 } else { |
| 689 ReplaceUsesWith(other); | 704 ReplaceUsesWith(other); |
| 690 ASSERT(other->env() == NULL); | 705 ASSERT(other->env() == NULL); |
| (...skipping 1014 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1705 constant_type_args->value().IsTypeArguments()) { | 1720 constant_type_args->value().IsTypeArguments()) { |
| 1706 const TypeArguments& instantiator_type_args = | 1721 const TypeArguments& instantiator_type_args = |
| 1707 TypeArguments::Cast(constant_type_args->value()); | 1722 TypeArguments::Cast(constant_type_args->value()); |
| 1708 const AbstractType& new_dst_type = AbstractType::Handle( | 1723 const AbstractType& new_dst_type = AbstractType::Handle( |
| 1709 dst_type().InstantiateFrom(instantiator_type_args)); | 1724 dst_type().InstantiateFrom(instantiator_type_args)); |
| 1710 set_dst_type(AbstractType::ZoneHandle(new_dst_type.Canonicalize())); | 1725 set_dst_type(AbstractType::ZoneHandle(new_dst_type.Canonicalize())); |
| 1711 ConstantInstr* null_constant = new ConstantInstr(Object::ZoneHandle()); | 1726 ConstantInstr* null_constant = new ConstantInstr(Object::ZoneHandle()); |
| 1712 // It is ok to insert instructions before the current during | 1727 // It is ok to insert instructions before the current during |
| 1713 // forward iteration. | 1728 // forward iteration. |
| 1714 optimizer->InsertBefore(this, null_constant, NULL, Definition::kValue); | 1729 optimizer->InsertBefore(this, null_constant, NULL, Definition::kValue); |
| 1715 instantiator_type_arguments()->RemoveFromInputUseList(); | 1730 instantiator_type_arguments()->RemoveFromUseList(); |
| 1716 instantiator_type_arguments()->set_definition(null_constant); | 1731 instantiator_type_arguments()->set_definition(null_constant); |
| 1717 instantiator_type_arguments()->AddToInputUseList(); | 1732 null_constant->AddInputUse(instantiator_type_arguments()); |
| 1718 } | 1733 } |
| 1719 return this; | 1734 return this; |
| 1720 } | 1735 } |
| 1721 | 1736 |
| 1722 | 1737 |
| 1723 Instruction* BranchInstr::Canonicalize(FlowGraphOptimizer* optimizer) { | 1738 Instruction* BranchInstr::Canonicalize(FlowGraphOptimizer* optimizer) { |
| 1724 // Only handle strict-compares. | 1739 // Only handle strict-compares. |
| 1725 if (comparison()->IsStrictCompare()) { | 1740 if (comparison()->IsStrictCompare()) { |
| 1726 Definition* replacement = comparison()->Canonicalize(optimizer); | 1741 Definition* replacement = comparison()->Canonicalize(optimizer); |
| 1727 if (replacement == comparison() || replacement == NULL) return this; | 1742 if (replacement == comparison() || replacement == NULL) return this; |
| (...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2060 | 2075 |
| 2061 | 2076 |
| 2062 // Copies the environment and updates the environment use lists. | 2077 // Copies the environment and updates the environment use lists. |
| 2063 void Environment::DeepCopyTo(Instruction* instr) const { | 2078 void Environment::DeepCopyTo(Instruction* instr) const { |
| 2064 Environment* copy = DeepCopy(); | 2079 Environment* copy = DeepCopy(); |
| 2065 intptr_t use_index = 0; | 2080 intptr_t use_index = 0; |
| 2066 for (Environment::DeepIterator it(copy); !it.Done(); it.Advance()) { | 2081 for (Environment::DeepIterator it(copy); !it.Done(); it.Advance()) { |
| 2067 Value* value = it.CurrentValue(); | 2082 Value* value = it.CurrentValue(); |
| 2068 value->set_instruction(instr); | 2083 value->set_instruction(instr); |
| 2069 value->set_use_index(use_index++); | 2084 value->set_use_index(use_index++); |
| 2070 value->AddToEnvUseList(); | 2085 value->definition()->AddEnvUse(value); |
| 2071 } | 2086 } |
| 2072 instr->set_env(copy); | 2087 instr->set_env(copy); |
| 2073 } | 2088 } |
| 2074 | 2089 |
| 2075 | 2090 |
| 2076 // Copies the environment as outer on an inlined instruction and updates the | 2091 // Copies the environment as outer on an inlined instruction and updates the |
| 2077 // environment use lists. | 2092 // environment use lists. |
| 2078 void Environment::DeepCopyToOuter(Instruction* instr) const { | 2093 void Environment::DeepCopyToOuter(Instruction* instr) const { |
| 2079 ASSERT(instr->env()->outer() == NULL); | 2094 ASSERT(instr->env()->outer() == NULL); |
| 2080 // Create a deep copy removing caller arguments from the environment. | 2095 // Create a deep copy removing caller arguments from the environment. |
| 2081 intptr_t argument_count = instr->env()->fixed_parameter_count(); | 2096 intptr_t argument_count = instr->env()->fixed_parameter_count(); |
| 2082 Environment* copy = | 2097 Environment* copy = |
| 2083 new Environment(values_.length() - argument_count, | 2098 new Environment(values_.length() - argument_count, |
| 2084 fixed_parameter_count_, | 2099 fixed_parameter_count_, |
| 2085 deopt_id_, | 2100 deopt_id_, |
| 2086 function_, | 2101 function_, |
| 2087 (outer_ == NULL) ? NULL : outer_->DeepCopy()); | 2102 (outer_ == NULL) ? NULL : outer_->DeepCopy()); |
| 2088 for (intptr_t i = 0; i < values_.length() - argument_count; ++i) { | 2103 for (intptr_t i = 0; i < values_.length() - argument_count; ++i) { |
| 2089 copy->values_.Add(values_[i]->Copy()); | 2104 copy->values_.Add(values_[i]->Copy()); |
| 2090 } | 2105 } |
| 2091 intptr_t use_index = instr->env()->Length(); // Start index after inner. | 2106 intptr_t use_index = instr->env()->Length(); // Start index after inner. |
| 2092 for (Environment::DeepIterator it(copy); !it.Done(); it.Advance()) { | 2107 for (Environment::DeepIterator it(copy); !it.Done(); it.Advance()) { |
| 2093 Value* value = it.CurrentValue(); | 2108 Value* value = it.CurrentValue(); |
| 2094 value->set_instruction(instr); | 2109 value->set_instruction(instr); |
| 2095 value->set_use_index(use_index++); | 2110 value->set_use_index(use_index++); |
| 2096 value->AddToEnvUseList(); | 2111 value->definition()->AddEnvUse(value); |
| 2097 } | 2112 } |
| 2098 instr->env()->outer_ = copy; | 2113 instr->env()->outer_ = copy; |
| 2099 } | 2114 } |
| 2100 | 2115 |
| 2101 | 2116 |
| 2102 RangeBoundary RangeBoundary::FromDefinition(Definition* defn, intptr_t offs) { | 2117 RangeBoundary RangeBoundary::FromDefinition(Definition* defn, intptr_t offs) { |
| 2103 if (defn->IsConstant() && defn->AsConstant()->value().IsSmi()) { | 2118 if (defn->IsConstant() && defn->AsConstant()->value().IsSmi()) { |
| 2104 return FromConstant(Smi::Cast(defn->AsConstant()->value()).Value() + offs); | 2119 return FromConstant(Smi::Cast(defn->AsConstant()->value()).Value() + offs); |
| 2105 } | 2120 } |
| 2106 return RangeBoundary(kSymbol, reinterpret_cast<intptr_t>(defn), offs); | 2121 return RangeBoundary(kSymbol, reinterpret_cast<intptr_t>(defn), offs); |
| (...skipping 662 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2769 default: | 2784 default: |
| 2770 UNREACHABLE(); | 2785 UNREACHABLE(); |
| 2771 } | 2786 } |
| 2772 return kPowRuntimeEntry; | 2787 return kPowRuntimeEntry; |
| 2773 } | 2788 } |
| 2774 | 2789 |
| 2775 | 2790 |
| 2776 #undef __ | 2791 #undef __ |
| 2777 | 2792 |
| 2778 } // namespace dart | 2793 } // namespace dart |
| OLD | NEW |