Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(937)

Side by Side Diff: runtime/vm/flow_graph_optimizer.cc

Issue 619903002: Generalize bounds checks. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698