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/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/dart_entry.h" | 9 #include "vm/dart_entry.h" |
| 10 #include "vm/flow_graph_builder.h" | 10 #include "vm/flow_graph_builder.h" |
| (...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 296 Instruction* replacement, | 296 Instruction* replacement, |
| 297 FlowGraph* graph) { | 297 FlowGraph* graph) { |
| 298 Definition* current_defn = current->AsDefinition(); | 298 Definition* current_defn = current->AsDefinition(); |
| 299 if ((replacement != NULL) && (current_defn != NULL)) { | 299 if ((replacement != NULL) && (current_defn != NULL)) { |
| 300 Definition* replacement_defn = replacement->AsDefinition(); | 300 Definition* replacement_defn = replacement->AsDefinition(); |
| 301 ASSERT(replacement_defn != NULL); | 301 ASSERT(replacement_defn != NULL); |
| 302 current_defn->ReplaceUsesWith(replacement_defn); | 302 current_defn->ReplaceUsesWith(replacement_defn); |
| 303 EnsureSSATempIndex(graph, current_defn, replacement_defn); | 303 EnsureSSATempIndex(graph, current_defn, replacement_defn); |
| 304 | 304 |
| 305 if (FLAG_trace_optimization) { | 305 if (FLAG_trace_optimization) { |
| 306 OS::Print("Replacing v%"Pd" with v%"Pd"\n", | 306 OS::Print("Replacing v%" Pd " with v%" Pd "\n", |
| 307 current_defn->ssa_temp_index(), | 307 current_defn->ssa_temp_index(), |
| 308 replacement_defn->ssa_temp_index()); | 308 replacement_defn->ssa_temp_index()); |
| 309 } | 309 } |
| 310 } else if (FLAG_trace_optimization) { | 310 } else if (FLAG_trace_optimization) { |
| 311 if (current_defn == NULL) { | 311 if (current_defn == NULL) { |
| 312 OS::Print("Removing %s\n", current->DebugName()); | 312 OS::Print("Removing %s\n", current->DebugName()); |
| 313 } else { | 313 } else { |
| 314 ASSERT(!current_defn->HasUses()); | 314 ASSERT(!current_defn->HasUses()); |
| 315 OS::Print("Removing v%"Pd".\n", current_defn->ssa_temp_index()); | 315 OS::Print("Removing v%" Pd ".\n", current_defn->ssa_temp_index()); |
| 316 } | 316 } |
| 317 } | 317 } |
| 318 iterator->RemoveCurrentFromGraph(); | 318 iterator->RemoveCurrentFromGraph(); |
| 319 } | 319 } |
| 320 | 320 |
| 321 | 321 |
| 322 bool FlowGraphOptimizer::Canonicalize() { | 322 bool FlowGraphOptimizer::Canonicalize() { |
| 323 bool changed = false; | 323 bool changed = false; |
| 324 for (intptr_t i = 0; i < block_order_.length(); ++i) { | 324 for (intptr_t i = 0; i < block_order_.length(); ++i) { |
| 325 BlockEntryInstr* entry = block_order_[i]; | 325 BlockEntryInstr* entry = block_order_[i]; |
| (...skipping 3492 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3818 ASSERT(flow_graph->is_licm_allowed()); | 3818 ASSERT(flow_graph->is_licm_allowed()); |
| 3819 } | 3819 } |
| 3820 | 3820 |
| 3821 | 3821 |
| 3822 void LICM::Hoist(ForwardInstructionIterator* it, | 3822 void LICM::Hoist(ForwardInstructionIterator* it, |
| 3823 BlockEntryInstr* pre_header, | 3823 BlockEntryInstr* pre_header, |
| 3824 Instruction* current) { | 3824 Instruction* current) { |
| 3825 // TODO(fschneider): Avoid repeated deoptimization when | 3825 // TODO(fschneider): Avoid repeated deoptimization when |
| 3826 // speculatively hoisting checks. | 3826 // speculatively hoisting checks. |
| 3827 if (FLAG_trace_optimization) { | 3827 if (FLAG_trace_optimization) { |
| 3828 OS::Print("Hoisting instruction %s:%"Pd" from B%"Pd" to B%"Pd"\n", | 3828 OS::Print("Hoisting instruction %s:%" Pd " from B%" Pd " to B%" Pd "\n", |
| 3829 current->DebugName(), | 3829 current->DebugName(), |
| 3830 current->GetDeoptId(), | 3830 current->GetDeoptId(), |
| 3831 current->GetBlock()->block_id(), | 3831 current->GetBlock()->block_id(), |
| 3832 pre_header->block_id()); | 3832 pre_header->block_id()); |
| 3833 } | 3833 } |
| 3834 // Move the instruction out of the loop. | 3834 // Move the instruction out of the loop. |
| 3835 current->RemoveEnvironment(); | 3835 current->RemoveEnvironment(); |
| 3836 it->RemoveCurrentFromGraph(); | 3836 it->RemoveCurrentFromGraph(); |
| 3837 GotoInstr* last = pre_header->last_instruction()->AsGoto(); | 3837 GotoInstr* last = pre_header->last_instruction()->AsGoto(); |
| 3838 // Using kind kEffect will not assign a fresh ssa temporary index. | 3838 // Using kind kEffect will not assign a fresh ssa temporary index. |
| (...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4167 switch (kind_) { | 4167 switch (kind_) { |
| 4168 case kNone: | 4168 case kNone: |
| 4169 return "<none>"; | 4169 return "<none>"; |
| 4170 | 4170 |
| 4171 case kField: { | 4171 case kField: { |
| 4172 const char* field_name = String::Handle(field().name()).ToCString(); | 4172 const char* field_name = String::Handle(field().name()).ToCString(); |
| 4173 if (instance() == NULL) { | 4173 if (instance() == NULL) { |
| 4174 return field_name; | 4174 return field_name; |
| 4175 } | 4175 } |
| 4176 return Isolate::Current()->current_zone()->PrintToString( | 4176 return Isolate::Current()->current_zone()->PrintToString( |
| 4177 "<v%"Pd".%s>", instance()->ssa_temp_index(), field_name); | 4177 "<v%" Pd ".%s>", instance()->ssa_temp_index(), field_name); |
| 4178 } | 4178 } |
| 4179 | 4179 |
| 4180 case kVMField: { | 4180 case kVMField: { |
| 4181 return Isolate::Current()->current_zone()->PrintToString( | 4181 return Isolate::Current()->current_zone()->PrintToString( |
| 4182 "<v%"Pd"@%"Pd">", instance()->ssa_temp_index(), offset_in_bytes()); | 4182 "<v%" Pd "@%" Pd ">", instance()->ssa_temp_index(), offset_in_bytes( )); |
|
siva
2013/08/20 19:54:51
"<v%" Pd "@%" Pd ">",
instance()->ssa_temp_index()
Jacob
2013/08/20 20:32:15
Done.
| |
| 4183 } | 4183 } |
| 4184 | 4184 |
| 4185 case kIndexed: { | 4185 case kIndexed: { |
| 4186 return Isolate::Current()->current_zone()->PrintToString( | 4186 return Isolate::Current()->current_zone()->PrintToString( |
| 4187 "<v%"Pd"[v%"Pd"]>", | 4187 "<v%" Pd "[v%" Pd "]>", |
| 4188 instance()->ssa_temp_index(), | 4188 instance()->ssa_temp_index(), |
| 4189 index()->ssa_temp_index()); | 4189 index()->ssa_temp_index()); |
| 4190 } | 4190 } |
| 4191 | 4191 |
| 4192 case kContext: | 4192 case kContext: |
| 4193 return "<context>"; | 4193 return "<context>"; |
| 4194 } | 4194 } |
| 4195 UNREACHABLE(); | 4195 UNREACHABLE(); |
| 4196 return "<?>"; | 4196 return "<?>"; |
| 4197 } | 4197 } |
| (...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4632 for (intptr_t j = 0; j < phi->InputCount(); j++) { | 4632 for (intptr_t j = 0; j < phi->InputCount(); j++) { |
| 4633 input_place.set_instance(phi->InputAt(j)->definition()); | 4633 input_place.set_instance(phi->InputAt(j)->definition()); |
| 4634 | 4634 |
| 4635 Place* result = map->Lookup(&input_place); | 4635 Place* result = map->Lookup(&input_place); |
| 4636 if (result == NULL) { | 4636 if (result == NULL) { |
| 4637 input_place.set_id(places->length()); | 4637 input_place.set_id(places->length()); |
| 4638 result = Place::Wrap(input_place); | 4638 result = Place::Wrap(input_place); |
| 4639 map->Insert(result); | 4639 map->Insert(result); |
| 4640 places->Add(result); | 4640 places->Add(result); |
| 4641 if (FLAG_trace_optimization) { | 4641 if (FLAG_trace_optimization) { |
| 4642 OS::Print(" adding place %s as %"Pd"\n", | 4642 OS::Print(" adding place %s as %" Pd "\n", |
| 4643 result->ToCString(), | 4643 result->ToCString(), |
| 4644 result->id()); | 4644 result->id()); |
| 4645 } | 4645 } |
| 4646 } | 4646 } |
| 4647 | 4647 |
| 4648 phi_moves->CreateOutgoingMove(block->PredecessorAt(j), | 4648 phi_moves->CreateOutgoingMove(block->PredecessorAt(j), |
| 4649 result->id(), | 4649 result->id(), |
| 4650 place->id()); | 4650 place->id()); |
| 4651 } | 4651 } |
| 4652 } | 4652 } |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 4678 } | 4678 } |
| 4679 | 4679 |
| 4680 Place* result = map->Lookup(&place); | 4680 Place* result = map->Lookup(&place); |
| 4681 if (result == NULL) { | 4681 if (result == NULL) { |
| 4682 place.set_id(places->length()); | 4682 place.set_id(places->length()); |
| 4683 result = Place::Wrap(place); | 4683 result = Place::Wrap(place); |
| 4684 map->Insert(result); | 4684 map->Insert(result); |
| 4685 places->Add(result); | 4685 places->Add(result); |
| 4686 | 4686 |
| 4687 if (FLAG_trace_optimization) { | 4687 if (FLAG_trace_optimization) { |
| 4688 OS::Print("numbering %s as %"Pd"\n", | 4688 OS::Print("numbering %s as %" Pd "\n", |
| 4689 result->ToCString(), | 4689 result->ToCString(), |
| 4690 result->id()); | 4690 result->id()); |
| 4691 } | 4691 } |
| 4692 } | 4692 } |
| 4693 | 4693 |
| 4694 instr->set_place_id(result->id()); | 4694 instr->set_place_id(result->id()); |
| 4695 } | 4695 } |
| 4696 } | 4696 } |
| 4697 | 4697 |
| 4698 if (!has_loads) { | 4698 if (!has_loads) { |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4924 } | 4924 } |
| 4925 | 4925 |
| 4926 const intptr_t place_id = defn->place_id(); | 4926 const intptr_t place_id = defn->place_id(); |
| 4927 if (gen->Contains(place_id)) { | 4927 if (gen->Contains(place_id)) { |
| 4928 // This is a locally redundant load. | 4928 // This is a locally redundant load. |
| 4929 ASSERT((out_values != NULL) && ((*out_values)[place_id] != NULL)); | 4929 ASSERT((out_values != NULL) && ((*out_values)[place_id] != NULL)); |
| 4930 | 4930 |
| 4931 Definition* replacement = (*out_values)[place_id]; | 4931 Definition* replacement = (*out_values)[place_id]; |
| 4932 EnsureSSATempIndex(graph_, defn, replacement); | 4932 EnsureSSATempIndex(graph_, defn, replacement); |
| 4933 if (FLAG_trace_optimization) { | 4933 if (FLAG_trace_optimization) { |
| 4934 OS::Print("Replacing load v%"Pd" with v%"Pd"\n", | 4934 OS::Print("Replacing load v%" Pd " with v%" Pd "\n", |
| 4935 defn->ssa_temp_index(), | 4935 defn->ssa_temp_index(), |
| 4936 replacement->ssa_temp_index()); | 4936 replacement->ssa_temp_index()); |
| 4937 } | 4937 } |
| 4938 | 4938 |
| 4939 defn->ReplaceUsesWith(replacement); | 4939 defn->ReplaceUsesWith(replacement); |
| 4940 instr_it.RemoveCurrentFromGraph(); | 4940 instr_it.RemoveCurrentFromGraph(); |
| 4941 forwarded_ = true; | 4941 forwarded_ = true; |
| 4942 continue; | 4942 continue; |
| 4943 } else if (!kill->Contains(place_id)) { | 4943 } else if (!kill->Contains(place_id)) { |
| 4944 // This is an exposed load: it is the first representative of a | 4944 // This is an exposed load: it is the first representative of a |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5134 for (intptr_t i = 0; i < phi_moves->length(); i++) { | 5134 for (intptr_t i = 0; i < phi_moves->length(); i++) { |
| 5135 const intptr_t from = (*phi_moves)[i].from(); | 5135 const intptr_t from = (*phi_moves)[i].from(); |
| 5136 const intptr_t to = (*phi_moves)[i].to(); | 5136 const intptr_t to = (*phi_moves)[i].to(); |
| 5137 if (from == to) continue; | 5137 if (from == to) continue; |
| 5138 | 5138 |
| 5139 (*block_out_values)[to] = (*temp_forwarded_values)[to]; | 5139 (*block_out_values)[to] = (*temp_forwarded_values)[to]; |
| 5140 } | 5140 } |
| 5141 } | 5141 } |
| 5142 | 5142 |
| 5143 if (FLAG_trace_load_optimization) { | 5143 if (FLAG_trace_load_optimization) { |
| 5144 OS::Print("B%"Pd"\n", block->block_id()); | 5144 OS::Print("B%" Pd "\n", block->block_id()); |
| 5145 OS::Print(" IN: "); | 5145 OS::Print(" IN: "); |
| 5146 aliased_set_->PrintSet(in_[preorder_number]); | 5146 aliased_set_->PrintSet(in_[preorder_number]); |
| 5147 OS::Print("\n"); | 5147 OS::Print("\n"); |
| 5148 | 5148 |
| 5149 OS::Print(" KILL: "); | 5149 OS::Print(" KILL: "); |
| 5150 aliased_set_->PrintSet(kill_[preorder_number]); | 5150 aliased_set_->PrintSet(kill_[preorder_number]); |
| 5151 OS::Print("\n"); | 5151 OS::Print("\n"); |
| 5152 | 5152 |
| 5153 OS::Print(" OUT: "); | 5153 OS::Print(" OUT: "); |
| 5154 aliased_set_->PrintSet(out_[preorder_number]); | 5154 aliased_set_->PrintSet(out_[preorder_number]); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5198 | 5198 |
| 5199 for (BitVector::Iterator loop_it(header->loop_info()); | 5199 for (BitVector::Iterator loop_it(header->loop_info()); |
| 5200 !loop_it.Done(); | 5200 !loop_it.Done(); |
| 5201 loop_it.Advance()) { | 5201 loop_it.Advance()) { |
| 5202 const intptr_t preorder_number = loop_it.Current(); | 5202 const intptr_t preorder_number = loop_it.Current(); |
| 5203 loop_gen->RemoveAll(kill_[preorder_number]); | 5203 loop_gen->RemoveAll(kill_[preorder_number]); |
| 5204 } | 5204 } |
| 5205 | 5205 |
| 5206 if (FLAG_trace_optimization) { | 5206 if (FLAG_trace_optimization) { |
| 5207 for (BitVector::Iterator it(loop_gen); !it.Done(); it.Advance()) { | 5207 for (BitVector::Iterator it(loop_gen); !it.Done(); it.Advance()) { |
| 5208 OS::Print("place %s is loop invariant for B%"Pd"\n", | 5208 OS::Print("place %s is loop invariant for B%" Pd "\n", |
| 5209 aliased_set_->places()[it.Current()]->ToCString(), | 5209 aliased_set_->places()[it.Current()]->ToCString(), |
| 5210 header->block_id()); | 5210 header->block_id()); |
| 5211 } | 5211 } |
| 5212 } | 5212 } |
| 5213 | 5213 |
| 5214 invariant_loads->Add(loop_gen); | 5214 invariant_loads->Add(loop_gen); |
| 5215 } | 5215 } |
| 5216 | 5216 |
| 5217 graph_->set_loop_invariant_loads(invariant_loads); | 5217 graph_->set_loop_invariant_loads(invariant_loads); |
| 5218 } | 5218 } |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5269 Definition* replacement = (*pred_out_values)[place_id]->Replacement(); | 5269 Definition* replacement = (*pred_out_values)[place_id]->Replacement(); |
| 5270 Value* input = new Value(replacement); | 5270 Value* input = new Value(replacement); |
| 5271 phi->SetInputAt(i, input); | 5271 phi->SetInputAt(i, input); |
| 5272 replacement->AddInputUse(input); | 5272 replacement->AddInputUse(input); |
| 5273 } | 5273 } |
| 5274 | 5274 |
| 5275 phi->set_ssa_temp_index(graph_->alloc_ssa_temp_index()); | 5275 phi->set_ssa_temp_index(graph_->alloc_ssa_temp_index()); |
| 5276 phis_.Add(phi); // Postpone phi insertion until after load forwarding. | 5276 phis_.Add(phi); // Postpone phi insertion until after load forwarding. |
| 5277 | 5277 |
| 5278 if (FLAG_trace_load_optimization) { | 5278 if (FLAG_trace_load_optimization) { |
| 5279 OS::Print("created pending phi %s for %s at B%"Pd"\n", | 5279 OS::Print("created pending phi %s for %s at B%" Pd "\n", |
| 5280 phi->ToCString(), | 5280 phi->ToCString(), |
| 5281 aliased_set_->places()[place_id]->ToCString(), | 5281 aliased_set_->places()[place_id]->ToCString(), |
| 5282 block->block_id()); | 5282 block->block_id()); |
| 5283 } | 5283 } |
| 5284 } | 5284 } |
| 5285 | 5285 |
| 5286 // Iterate over basic blocks and replace exposed loads with incoming | 5286 // Iterate over basic blocks and replace exposed loads with incoming |
| 5287 // values. | 5287 // values. |
| 5288 void ForwardLoads() { | 5288 void ForwardLoads() { |
| 5289 for (BlockIterator block_it = graph_->reverse_postorder_iterator(); | 5289 for (BlockIterator block_it = graph_->reverse_postorder_iterator(); |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 5308 // they might contain values that were replace and removed | 5308 // they might contain values that were replace and removed |
| 5309 // from the graph by this iteration. | 5309 // from the graph by this iteration. |
| 5310 // To prevent using them we additionally mark definitions themselves | 5310 // To prevent using them we additionally mark definitions themselves |
| 5311 // as replaced and store a pointer to the replacement. | 5311 // as replaced and store a pointer to the replacement. |
| 5312 replacement = replacement->Replacement(); | 5312 replacement = replacement->Replacement(); |
| 5313 | 5313 |
| 5314 if (load != replacement) { | 5314 if (load != replacement) { |
| 5315 EnsureSSATempIndex(graph_, load, replacement); | 5315 EnsureSSATempIndex(graph_, load, replacement); |
| 5316 | 5316 |
| 5317 if (FLAG_trace_optimization) { | 5317 if (FLAG_trace_optimization) { |
| 5318 OS::Print("Replacing load v%"Pd" with v%"Pd"\n", | 5318 OS::Print("Replacing load v%" Pd " with v%" Pd "\n", |
| 5319 load->ssa_temp_index(), | 5319 load->ssa_temp_index(), |
| 5320 replacement->ssa_temp_index()); | 5320 replacement->ssa_temp_index()); |
| 5321 } | 5321 } |
| 5322 | 5322 |
| 5323 load->ReplaceUsesWith(replacement); | 5323 load->ReplaceUsesWith(replacement); |
| 5324 load->RemoveFromGraph(); | 5324 load->RemoveFromGraph(); |
| 5325 load->SetReplacement(replacement); | 5325 load->SetReplacement(replacement); |
| 5326 forwarded_ = true; | 5326 forwarded_ = true; |
| 5327 } | 5327 } |
| 5328 } | 5328 } |
| (...skipping 1437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6766 // instructions, previous pointers, predecessors, etc. after eliminating | 6766 // instructions, previous pointers, predecessors, etc. after eliminating |
| 6767 // unreachable code. We do not maintain those properties during the | 6767 // unreachable code. We do not maintain those properties during the |
| 6768 // transformation. | 6768 // transformation. |
| 6769 for (BlockIterator b = graph_->reverse_postorder_iterator(); | 6769 for (BlockIterator b = graph_->reverse_postorder_iterator(); |
| 6770 !b.Done(); | 6770 !b.Done(); |
| 6771 b.Advance()) { | 6771 b.Advance()) { |
| 6772 BlockEntryInstr* block = b.Current(); | 6772 BlockEntryInstr* block = b.Current(); |
| 6773 JoinEntryInstr* join = block->AsJoinEntry(); | 6773 JoinEntryInstr* join = block->AsJoinEntry(); |
| 6774 if (!reachable_->Contains(block->preorder_number())) { | 6774 if (!reachable_->Contains(block->preorder_number())) { |
| 6775 if (FLAG_trace_constant_propagation) { | 6775 if (FLAG_trace_constant_propagation) { |
| 6776 OS::Print("Unreachable B%"Pd"\n", block->block_id()); | 6776 OS::Print("Unreachable B%" Pd "\n", block->block_id()); |
| 6777 } | 6777 } |
| 6778 // Remove all uses in unreachable blocks. | 6778 // Remove all uses in unreachable blocks. |
| 6779 if (join != NULL) { | 6779 if (join != NULL) { |
| 6780 for (PhiIterator it(join); !it.Done(); it.Advance()) { | 6780 for (PhiIterator it(join); !it.Done(); it.Advance()) { |
| 6781 it.Current()->UnuseAllInputs(); | 6781 it.Current()->UnuseAllInputs(); |
| 6782 } | 6782 } |
| 6783 } | 6783 } |
| 6784 block->UnuseAllInputs(); | 6784 block->UnuseAllInputs(); |
| 6785 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) { | 6785 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) { |
| 6786 it.Current()->UnuseAllInputs(); | 6786 it.Current()->UnuseAllInputs(); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6846 if ((defn != NULL) && | 6846 if ((defn != NULL) && |
| 6847 IsConstant(defn->constant_value()) && | 6847 IsConstant(defn->constant_value()) && |
| 6848 (defn->constant_value().IsSmi() || defn->constant_value().IsOld()) && | 6848 (defn->constant_value().IsSmi() || defn->constant_value().IsOld()) && |
| 6849 !defn->IsConstant() && | 6849 !defn->IsConstant() && |
| 6850 !defn->IsPushArgument() && | 6850 !defn->IsPushArgument() && |
| 6851 !defn->IsStoreIndexed() && | 6851 !defn->IsStoreIndexed() && |
| 6852 !defn->IsStoreInstanceField() && | 6852 !defn->IsStoreInstanceField() && |
| 6853 !defn->IsStoreStaticField() && | 6853 !defn->IsStoreStaticField() && |
| 6854 !defn->IsStoreVMField()) { | 6854 !defn->IsStoreVMField()) { |
| 6855 if (FLAG_trace_constant_propagation) { | 6855 if (FLAG_trace_constant_propagation) { |
| 6856 OS::Print("Constant v%"Pd" = %s\n", | 6856 OS::Print("Constant v%" Pd " = %s\n", |
| 6857 defn->ssa_temp_index(), | 6857 defn->ssa_temp_index(), |
| 6858 defn->constant_value().ToCString()); | 6858 defn->constant_value().ToCString()); |
| 6859 } | 6859 } |
| 6860 ConstantInstr* constant = graph_->GetConstant(defn->constant_value()); | 6860 ConstantInstr* constant = graph_->GetConstant(defn->constant_value()); |
| 6861 defn->ReplaceUsesWith(constant); | 6861 defn->ReplaceUsesWith(constant); |
| 6862 i.RemoveCurrentFromGraph(); | 6862 i.RemoveCurrentFromGraph(); |
| 6863 } | 6863 } |
| 6864 } | 6864 } |
| 6865 | 6865 |
| 6866 // Replace branches where one target is unreachable with jumps. | 6866 // Replace branches where one target is unreachable with jumps. |
| (...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7316 return true; | 7316 return true; |
| 7317 } | 7317 } |
| 7318 | 7318 |
| 7319 | 7319 |
| 7320 // Remove the given allocation from the graph. It is not observable. | 7320 // Remove the given allocation from the graph. It is not observable. |
| 7321 // If deoptimization occurs the object will be materialized. | 7321 // If deoptimization occurs the object will be materialized. |
| 7322 static void EliminateAllocation(AllocateObjectInstr* alloc) { | 7322 static void EliminateAllocation(AllocateObjectInstr* alloc) { |
| 7323 ASSERT(IsAllocationSinkingCandidate(alloc)); | 7323 ASSERT(IsAllocationSinkingCandidate(alloc)); |
| 7324 | 7324 |
| 7325 if (FLAG_trace_optimization) { | 7325 if (FLAG_trace_optimization) { |
| 7326 OS::Print("removing allocation from the graph: v%"Pd"\n", | 7326 OS::Print("removing allocation from the graph: v%" Pd "\n", |
| 7327 alloc->ssa_temp_index()); | 7327 alloc->ssa_temp_index()); |
| 7328 } | 7328 } |
| 7329 | 7329 |
| 7330 // As an allocation sinking candidate it is only used in stores to its own | 7330 // As an allocation sinking candidate it is only used in stores to its own |
| 7331 // fields. Remove these stores. | 7331 // fields. Remove these stores. |
| 7332 for (Value* use = alloc->input_use_list(); | 7332 for (Value* use = alloc->input_use_list(); |
| 7333 use != NULL; | 7333 use != NULL; |
| 7334 use = alloc->input_use_list()) { | 7334 use = alloc->input_use_list()) { |
| 7335 use->instruction()->RemoveFromGraph(); | 7335 use->instruction()->RemoveFromGraph(); |
| 7336 } | 7336 } |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 7355 // Collect sinking candidates. | 7355 // Collect sinking candidates. |
| 7356 const GrowableArray<BlockEntryInstr*>& postorder = flow_graph_->postorder(); | 7356 const GrowableArray<BlockEntryInstr*>& postorder = flow_graph_->postorder(); |
| 7357 for (BlockIterator block_it(postorder); | 7357 for (BlockIterator block_it(postorder); |
| 7358 !block_it.Done(); | 7358 !block_it.Done(); |
| 7359 block_it.Advance()) { | 7359 block_it.Advance()) { |
| 7360 BlockEntryInstr* block = block_it.Current(); | 7360 BlockEntryInstr* block = block_it.Current(); |
| 7361 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) { | 7361 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) { |
| 7362 AllocateObjectInstr* alloc = it.Current()->AsAllocateObject(); | 7362 AllocateObjectInstr* alloc = it.Current()->AsAllocateObject(); |
| 7363 if ((alloc != NULL) && IsAllocationSinkingCandidate(alloc)) { | 7363 if ((alloc != NULL) && IsAllocationSinkingCandidate(alloc)) { |
| 7364 if (FLAG_trace_optimization) { | 7364 if (FLAG_trace_optimization) { |
| 7365 OS::Print("discovered allocation sinking candidate: v%"Pd"\n", | 7365 OS::Print("discovered allocation sinking candidate: v%" Pd "\n", |
| 7366 alloc->ssa_temp_index()); | 7366 alloc->ssa_temp_index()); |
| 7367 } | 7367 } |
| 7368 | 7368 |
| 7369 // All sinking candidate are known to be not aliased. | 7369 // All sinking candidate are known to be not aliased. |
| 7370 alloc->set_identity(AllocateObjectInstr::kNotAliased); | 7370 alloc->set_identity(AllocateObjectInstr::kNotAliased); |
| 7371 | 7371 |
| 7372 candidates.Add(alloc); | 7372 candidates.Add(alloc); |
| 7373 } | 7373 } |
| 7374 } | 7374 } |
| 7375 } | 7375 } |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7537 } | 7537 } |
| 7538 | 7538 |
| 7539 // Insert materializations at environment uses. | 7539 // Insert materializations at environment uses. |
| 7540 for (intptr_t i = 0; i < exits.length(); i++) { | 7540 for (intptr_t i = 0; i < exits.length(); i++) { |
| 7541 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields); | 7541 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields); |
| 7542 } | 7542 } |
| 7543 } | 7543 } |
| 7544 | 7544 |
| 7545 | 7545 |
| 7546 } // namespace dart | 7546 } // namespace dart |
| OLD | NEW |