| 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/flow_graph_optimizer.h" | 5 #include "vm/flow_graph_optimizer.h" |
| 6 | 6 |
| 7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
| 8 #include "vm/cha.h" | 8 #include "vm/cha.h" |
| 9 #include "vm/cpu.h" | 9 #include "vm/cpu.h" |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 4707 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4718 // can't deoptimize. | 4718 // can't deoptimize. |
| 4719 instr->RemoveEnvironment(); | 4719 instr->RemoveEnvironment(); |
| 4720 ReplaceCall(instr, store); | 4720 ReplaceCall(instr, store); |
| 4721 return true; | 4721 return true; |
| 4722 } | 4722 } |
| 4723 | 4723 |
| 4724 | 4724 |
| 4725 #if defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_IA32) | 4725 #if defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_IA32) |
| 4726 // Smi widening pass is only meaningful on platforms where Smi | 4726 // Smi widening pass is only meaningful on platforms where Smi |
| 4727 // is smaller than 32bit. For now only support it on ARM and ia32. | 4727 // is smaller than 32bit. For now only support it on ARM and ia32. |
| 4728 | |
| 4729 class DefinitionWorklist : public ValueObject { | |
| 4730 public: | |
| 4731 DefinitionWorklist(FlowGraph* flow_graph, | |
| 4732 intptr_t initial_capacity) | |
| 4733 : defs_(initial_capacity), | |
| 4734 contains_vector_(new(flow_graph->isolate()) BitVector( | |
| 4735 flow_graph->isolate(), flow_graph->current_ssa_temp_index())) { | |
| 4736 } | |
| 4737 | |
| 4738 void Add(Definition* defn) { | |
| 4739 if (!Contains(defn)) { | |
| 4740 defs_.Add(defn); | |
| 4741 contains_vector_->Add(defn->ssa_temp_index()); | |
| 4742 } | |
| 4743 } | |
| 4744 | |
| 4745 bool Contains(Definition* defn) const { | |
| 4746 return (defn->ssa_temp_index() >= 0) && | |
| 4747 contains_vector_->Contains(defn->ssa_temp_index()); | |
| 4748 } | |
| 4749 | |
| 4750 const GrowableArray<Definition*>& definitions() const { return defs_; } | |
| 4751 BitVector* contains_vector() const { return contains_vector_; } | |
| 4752 | |
| 4753 void Clear() { | |
| 4754 defs_.TruncateTo(0); | |
| 4755 contains_vector_->Clear(); | |
| 4756 } | |
| 4757 | |
| 4758 private: | |
| 4759 GrowableArray<Definition*> defs_; | |
| 4760 BitVector* contains_vector_; | |
| 4761 }; | |
| 4762 | |
| 4763 | |
| 4764 static bool CanBeWidened(BinarySmiOpInstr* smi_op) { | 4728 static bool CanBeWidened(BinarySmiOpInstr* smi_op) { |
| 4765 return BinaryInt32OpInstr::IsSupported(smi_op->op_kind(), | 4729 return BinaryInt32OpInstr::IsSupported(smi_op->op_kind(), |
| 4766 smi_op->left(), | 4730 smi_op->left(), |
| 4767 smi_op->right()); | 4731 smi_op->right()); |
| 4768 } | 4732 } |
| 4769 | 4733 |
| 4770 | 4734 |
| 4771 static bool BenefitsFromWidening(BinarySmiOpInstr* smi_op) { | 4735 static bool BenefitsFromWidening(BinarySmiOpInstr* smi_op) { |
| 4772 // TODO(vegorov): when shifts with non-constants shift count are supported | 4736 // TODO(vegorov): when shifts with non-constants shift count are supported |
| 4773 // add them here as we save untagging for the count. | 4737 // add them here as we save untagging for the count. |
| (...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5052 new(flow_graph->isolate()) ConstantInstr(orig->value()); | 5016 new(flow_graph->isolate()) ConstantInstr(orig->value()); |
| 5053 copy->set_ssa_temp_index(flow_graph->alloc_ssa_temp_index()); | 5017 copy->set_ssa_temp_index(flow_graph->alloc_ssa_temp_index()); |
| 5054 old->ReplaceUsesWith(copy); | 5018 old->ReplaceUsesWith(copy); |
| 5055 (*idefs)[j] = copy; | 5019 (*idefs)[j] = copy; |
| 5056 } | 5020 } |
| 5057 } | 5021 } |
| 5058 } | 5022 } |
| 5059 } | 5023 } |
| 5060 | 5024 |
| 5061 | 5025 |
| 5062 static BlockEntryInstr* FindPreHeader(BlockEntryInstr* header) { | |
| 5063 for (intptr_t j = 0; j < header->PredecessorCount(); ++j) { | |
| 5064 BlockEntryInstr* candidate = header->PredecessorAt(j); | |
| 5065 if (header->dominator() == candidate) { | |
| 5066 return candidate; | |
| 5067 } | |
| 5068 } | |
| 5069 return NULL; | |
| 5070 } | |
| 5071 | |
| 5072 | |
| 5073 LICM::LICM(FlowGraph* flow_graph) : flow_graph_(flow_graph) { | 5026 LICM::LICM(FlowGraph* flow_graph) : flow_graph_(flow_graph) { |
| 5074 ASSERT(flow_graph->is_licm_allowed()); | 5027 ASSERT(flow_graph->is_licm_allowed()); |
| 5075 } | 5028 } |
| 5076 | 5029 |
| 5077 | 5030 |
| 5078 void LICM::Hoist(ForwardInstructionIterator* it, | 5031 void LICM::Hoist(ForwardInstructionIterator* it, |
| 5079 BlockEntryInstr* pre_header, | 5032 BlockEntryInstr* pre_header, |
| 5080 Instruction* current) { | 5033 Instruction* current) { |
| 5081 if (current->IsCheckClass()) { | 5034 if (current->IsCheckClass()) { |
| 5082 current->AsCheckClass()->set_licm_hoisted(true); | 5035 current->AsCheckClass()->set_licm_hoisted(true); |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5181 // Do not hoist any. | 5134 // Do not hoist any. |
| 5182 return; | 5135 return; |
| 5183 } | 5136 } |
| 5184 | 5137 |
| 5185 const ZoneGrowableArray<BlockEntryInstr*>& loop_headers = | 5138 const ZoneGrowableArray<BlockEntryInstr*>& loop_headers = |
| 5186 flow_graph()->LoopHeaders(); | 5139 flow_graph()->LoopHeaders(); |
| 5187 | 5140 |
| 5188 for (intptr_t i = 0; i < loop_headers.length(); ++i) { | 5141 for (intptr_t i = 0; i < loop_headers.length(); ++i) { |
| 5189 JoinEntryInstr* header = loop_headers[i]->AsJoinEntry(); | 5142 JoinEntryInstr* header = loop_headers[i]->AsJoinEntry(); |
| 5190 // Skip loop that don't have a pre-header block. | 5143 // Skip loop that don't have a pre-header block. |
| 5191 BlockEntryInstr* pre_header = FindPreHeader(header); | 5144 BlockEntryInstr* pre_header = header->ImmediateDominator(); |
| 5192 if (pre_header == NULL) continue; | 5145 if (pre_header == NULL) continue; |
| 5193 | 5146 |
| 5194 for (PhiIterator it(header); !it.Done(); it.Advance()) { | 5147 for (PhiIterator it(header); !it.Done(); it.Advance()) { |
| 5195 TrySpecializeSmiPhi(it.Current(), header, pre_header); | 5148 TrySpecializeSmiPhi(it.Current(), header, pre_header); |
| 5196 } | 5149 } |
| 5197 } | 5150 } |
| 5198 } | 5151 } |
| 5199 | 5152 |
| 5200 | 5153 |
| 5201 void LICM::Optimize() { | 5154 void LICM::Optimize() { |
| 5202 if (!flow_graph()->parsed_function().function(). | 5155 if (!flow_graph()->parsed_function().function(). |
| 5203 allows_hoisting_check_class()) { | 5156 allows_hoisting_check_class()) { |
| 5204 // Do not hoist any. | 5157 // Do not hoist any. |
| 5205 return; | 5158 return; |
| 5206 } | 5159 } |
| 5207 | 5160 |
| 5208 const ZoneGrowableArray<BlockEntryInstr*>& loop_headers = | 5161 const ZoneGrowableArray<BlockEntryInstr*>& loop_headers = |
| 5209 flow_graph()->LoopHeaders(); | 5162 flow_graph()->LoopHeaders(); |
| 5210 | 5163 |
| 5211 ZoneGrowableArray<BitVector*>* loop_invariant_loads = | 5164 ZoneGrowableArray<BitVector*>* loop_invariant_loads = |
| 5212 flow_graph()->loop_invariant_loads(); | 5165 flow_graph()->loop_invariant_loads(); |
| 5213 | 5166 |
| 5214 BlockEffects* block_effects = flow_graph()->block_effects(); | 5167 BlockEffects* block_effects = flow_graph()->block_effects(); |
| 5215 | 5168 |
| 5216 for (intptr_t i = 0; i < loop_headers.length(); ++i) { | 5169 for (intptr_t i = 0; i < loop_headers.length(); ++i) { |
| 5217 BlockEntryInstr* header = loop_headers[i]; | 5170 BlockEntryInstr* header = loop_headers[i]; |
| 5218 // Skip loop that don't have a pre-header block. | 5171 // Skip loop that don't have a pre-header block. |
| 5219 BlockEntryInstr* pre_header = FindPreHeader(header); | 5172 BlockEntryInstr* pre_header = header->ImmediateDominator(); |
| 5220 if (pre_header == NULL) continue; | 5173 if (pre_header == NULL) continue; |
| 5221 | 5174 |
| 5222 for (BitVector::Iterator loop_it(header->loop_info()); | 5175 for (BitVector::Iterator loop_it(header->loop_info()); |
| 5223 !loop_it.Done(); | 5176 !loop_it.Done(); |
| 5224 loop_it.Advance()) { | 5177 loop_it.Advance()) { |
| 5225 BlockEntryInstr* block = flow_graph()->preorder()[loop_it.Current()]; | 5178 BlockEntryInstr* block = flow_graph()->preorder()[loop_it.Current()]; |
| 5226 for (ForwardInstructionIterator it(block); | 5179 for (ForwardInstructionIterator it(block); |
| 5227 !it.Done(); | 5180 !it.Done(); |
| 5228 it.Advance()) { | 5181 it.Advance()) { |
| 5229 Instruction* current = it.Current(); | 5182 Instruction* current = it.Current(); |
| (...skipping 1505 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6735 | 6688 |
| 6736 void MarkLoopInvariantLoads() { | 6689 void MarkLoopInvariantLoads() { |
| 6737 const ZoneGrowableArray<BlockEntryInstr*>& loop_headers = | 6690 const ZoneGrowableArray<BlockEntryInstr*>& loop_headers = |
| 6738 graph_->LoopHeaders(); | 6691 graph_->LoopHeaders(); |
| 6739 | 6692 |
| 6740 ZoneGrowableArray<BitVector*>* invariant_loads = | 6693 ZoneGrowableArray<BitVector*>* invariant_loads = |
| 6741 new(I) ZoneGrowableArray<BitVector*>(loop_headers.length()); | 6694 new(I) ZoneGrowableArray<BitVector*>(loop_headers.length()); |
| 6742 | 6695 |
| 6743 for (intptr_t i = 0; i < loop_headers.length(); i++) { | 6696 for (intptr_t i = 0; i < loop_headers.length(); i++) { |
| 6744 BlockEntryInstr* header = loop_headers[i]; | 6697 BlockEntryInstr* header = loop_headers[i]; |
| 6745 BlockEntryInstr* pre_header = FindPreHeader(header); | 6698 BlockEntryInstr* pre_header = header->ImmediateDominator(); |
| 6746 if (pre_header == NULL) { | 6699 if (pre_header == NULL) { |
| 6747 invariant_loads->Add(NULL); | 6700 invariant_loads->Add(NULL); |
| 6748 continue; | 6701 continue; |
| 6749 } | 6702 } |
| 6750 | 6703 |
| 6751 BitVector* loop_gen = new(I) BitVector(I, aliased_set_->max_place_id()); | 6704 BitVector* loop_gen = new(I) BitVector(I, aliased_set_->max_place_id()); |
| 6752 for (BitVector::Iterator loop_it(header->loop_info()); | 6705 for (BitVector::Iterator loop_it(header->loop_info()); |
| 6753 !loop_it.Done(); | 6706 !loop_it.Done(); |
| 6754 loop_it.Advance()) { | 6707 loop_it.Advance()) { |
| 6755 const intptr_t preorder_number = loop_it.Current(); | 6708 const intptr_t preorder_number = loop_it.Current(); |
| (...skipping 3364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10120 | 10073 |
| 10121 // Insert materializations at environment uses. | 10074 // Insert materializations at environment uses. |
| 10122 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) { | 10075 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) { |
| 10123 CreateMaterializationAt( | 10076 CreateMaterializationAt( |
| 10124 exits_collector_.exits()[i], alloc, alloc->cls(), *slots); | 10077 exits_collector_.exits()[i], alloc, alloc->cls(), *slots); |
| 10125 } | 10078 } |
| 10126 } | 10079 } |
| 10127 | 10080 |
| 10128 | 10081 |
| 10129 } // namespace dart | 10082 } // namespace dart |
| OLD | NEW |