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 |