| 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" |
| 11 #include "vm/flow_graph_compiler.h" | 11 #include "vm/flow_graph_compiler.h" |
| 12 #include "vm/hash_map.h" | 12 #include "vm/hash_map.h" |
| 13 #include "vm/il_printer.h" | 13 #include "vm/il_printer.h" |
| 14 #include "vm/intermediate_language.h" | 14 #include "vm/intermediate_language.h" |
| 15 #include "vm/object_store.h" | 15 #include "vm/object_store.h" |
| 16 #include "vm/parser.h" | 16 #include "vm/parser.h" |
| 17 #include "vm/resolver.h" | 17 #include "vm/resolver.h" |
| 18 #include "vm/scopes.h" | 18 #include "vm/scopes.h" |
| 19 #include "vm/stack_frame.h" | 19 #include "vm/stack_frame.h" |
| 20 #include "vm/symbols.h" | 20 #include "vm/symbols.h" |
| 21 | 21 |
| 22 namespace dart { | 22 namespace dart { |
| 23 | 23 |
| 24 DEFINE_FLAG(bool, array_bounds_check_elimination, true, | 24 DEFINE_FLAG(bool, array_bounds_check_elimination, true, |
| 25 "Eliminate redundant bounds checks."); | 25 "Eliminate redundant bounds checks."); |
| 26 DEFINE_FLAG(int, getter_setter_ratio, 13, |
| 27 "Ratio of getter/setter usage used for double field unboxing heuristics"); |
| 26 DEFINE_FLAG(bool, load_cse, true, "Use redundant load elimination."); | 28 DEFINE_FLAG(bool, load_cse, true, "Use redundant load elimination."); |
| 27 DEFINE_FLAG(int, max_polymorphic_checks, 4, | 29 DEFINE_FLAG(int, max_polymorphic_checks, 4, |
| 28 "Maximum number of polymorphic check, otherwise it is megamorphic."); | 30 "Maximum number of polymorphic check, otherwise it is megamorphic."); |
| 29 DEFINE_FLAG(int, max_equality_polymorphic_checks, 32, | 31 DEFINE_FLAG(int, max_equality_polymorphic_checks, 32, |
| 30 "Maximum number of polymorphic checks in equality operator," | 32 "Maximum number of polymorphic checks in equality operator," |
| 31 " otherwise use megamorphic dispatch."); | 33 " otherwise use megamorphic dispatch."); |
| 32 DEFINE_FLAG(bool, remove_redundant_phis, true, "Remove redundant phis."); | 34 DEFINE_FLAG(bool, remove_redundant_phis, true, "Remove redundant phis."); |
| 33 DEFINE_FLAG(bool, trace_constant_propagation, false, | 35 DEFINE_FLAG(bool, trace_constant_propagation, false, |
| 34 "Print constant propagation and useless code elimination."); | 36 "Print constant propagation and useless code elimination."); |
| 37 DEFINE_FLAG(bool, trace_load_optimization, false, |
| 38 "Print live sets for load optimization pass."); |
| 35 DEFINE_FLAG(bool, trace_optimization, false, "Print optimization details."); | 39 DEFINE_FLAG(bool, trace_optimization, false, "Print optimization details."); |
| 36 DEFINE_FLAG(bool, trace_range_analysis, false, "Trace range analysis progress"); | 40 DEFINE_FLAG(bool, trace_range_analysis, false, "Trace range analysis progress"); |
| 37 DEFINE_FLAG(bool, truncating_left_shift, true, | 41 DEFINE_FLAG(bool, truncating_left_shift, true, |
| 38 "Optimize left shift to truncate if possible"); | 42 "Optimize left shift to truncate if possible"); |
| 39 DEFINE_FLAG(bool, use_cha, true, "Use class hierarchy analysis."); | 43 DEFINE_FLAG(bool, use_cha, true, "Use class hierarchy analysis."); |
| 40 DEFINE_FLAG(bool, trace_load_optimization, false, | |
| 41 "Print live sets for load optimization pass."); | |
| 42 DEFINE_FLAG(int, getter_setter_ratio, 13, | |
| 43 "Ratio of getter/setter usage used for double field unboxing heuristics"); | |
| 44 DECLARE_FLAG(bool, eliminate_type_checks); | 44 DECLARE_FLAG(bool, eliminate_type_checks); |
| 45 DECLARE_FLAG(bool, enable_type_checks); | 45 DECLARE_FLAG(bool, enable_type_checks); |
| 46 DECLARE_FLAG(bool, trace_type_check_elimination); | 46 DECLARE_FLAG(bool, trace_type_check_elimination); |
| 47 | 47 |
| 48 | 48 |
| 49 static bool ShouldInlineSimd() { | 49 static bool ShouldInlineSimd() { |
| 50 return FlowGraphCompiler::SupportsUnboxedFloat32x4(); | 50 return FlowGraphCompiler::SupportsUnboxedFloat32x4(); |
| 51 } | 51 } |
| 52 | 52 |
| 53 | 53 |
| (...skipping 4432 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4486 | 4486 |
| 4487 | 4487 |
| 4488 LICM::LICM(FlowGraph* flow_graph) : flow_graph_(flow_graph) { | 4488 LICM::LICM(FlowGraph* flow_graph) : flow_graph_(flow_graph) { |
| 4489 ASSERT(flow_graph->is_licm_allowed()); | 4489 ASSERT(flow_graph->is_licm_allowed()); |
| 4490 } | 4490 } |
| 4491 | 4491 |
| 4492 | 4492 |
| 4493 void LICM::Hoist(ForwardInstructionIterator* it, | 4493 void LICM::Hoist(ForwardInstructionIterator* it, |
| 4494 BlockEntryInstr* pre_header, | 4494 BlockEntryInstr* pre_header, |
| 4495 Instruction* current) { | 4495 Instruction* current) { |
| 4496 if (current->IsCheckClass()) { |
| 4497 current->AsCheckClass()->set_licm_hoisted(true); |
| 4498 } |
| 4496 // TODO(fschneider): Avoid repeated deoptimization when | 4499 // TODO(fschneider): Avoid repeated deoptimization when |
| 4497 // speculatively hoisting checks. | 4500 // speculatively hoisting checks. |
| 4498 if (FLAG_trace_optimization) { | 4501 if (FLAG_trace_optimization) { |
| 4499 OS::Print("Hoisting instruction %s:%" Pd " from B%" Pd " to B%" Pd "\n", | 4502 OS::Print("Hoisting instruction %s:%" Pd " from B%" Pd " to B%" Pd "\n", |
| 4500 current->DebugName(), | 4503 current->DebugName(), |
| 4501 current->GetDeoptId(), | 4504 current->GetDeoptId(), |
| 4502 current->GetBlock()->block_id(), | 4505 current->GetBlock()->block_id(), |
| 4503 pre_header->block_id()); | 4506 pre_header->block_id()); |
| 4504 } | 4507 } |
| 4505 // Move the instruction out of the loop. | 4508 // Move the instruction out of the loop. |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4573 Instruction* instr) { | 4576 Instruction* instr) { |
| 4574 return IsCandidateLoad(instr) && | 4577 return IsCandidateLoad(instr) && |
| 4575 (sets != NULL) && | 4578 (sets != NULL) && |
| 4576 instr->HasPlaceId() && | 4579 instr->HasPlaceId() && |
| 4577 ((*sets)[loop_header_index] != NULL) && | 4580 ((*sets)[loop_header_index] != NULL) && |
| 4578 (*sets)[loop_header_index]->Contains(instr->place_id()); | 4581 (*sets)[loop_header_index]->Contains(instr->place_id()); |
| 4579 } | 4582 } |
| 4580 | 4583 |
| 4581 | 4584 |
| 4582 void LICM::Optimize() { | 4585 void LICM::Optimize() { |
| 4586 if (!flow_graph()->parsed_function().function(). |
| 4587 allows_hoisting_check_class()) { |
| 4588 // Do not hoist any. |
| 4589 return; |
| 4590 } |
| 4591 |
| 4583 const ZoneGrowableArray<BlockEntryInstr*>& loop_headers = | 4592 const ZoneGrowableArray<BlockEntryInstr*>& loop_headers = |
| 4584 flow_graph()->loop_headers(); | 4593 flow_graph()->loop_headers(); |
| 4585 | 4594 |
| 4586 ZoneGrowableArray<BitVector*>* loop_invariant_loads = | 4595 ZoneGrowableArray<BitVector*>* loop_invariant_loads = |
| 4587 flow_graph()->loop_invariant_loads(); | 4596 flow_graph()->loop_invariant_loads(); |
| 4588 | 4597 |
| 4589 BlockEffects* block_effects = flow_graph()->block_effects(); | 4598 BlockEffects* block_effects = flow_graph()->block_effects(); |
| 4590 | 4599 |
| 4591 for (intptr_t i = 0; i < loop_headers.length(); ++i) { | 4600 for (intptr_t i = 0; i < loop_headers.length(); ++i) { |
| 4592 BlockEntryInstr* header = loop_headers[i]; | 4601 BlockEntryInstr* header = loop_headers[i]; |
| (...skipping 3874 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8467 } | 8476 } |
| 8468 | 8477 |
| 8469 // Insert materializations at environment uses. | 8478 // Insert materializations at environment uses. |
| 8470 for (intptr_t i = 0; i < exits.length(); i++) { | 8479 for (intptr_t i = 0; i < exits.length(); i++) { |
| 8471 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields); | 8480 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields); |
| 8472 } | 8481 } |
| 8473 } | 8482 } |
| 8474 | 8483 |
| 8475 | 8484 |
| 8476 } // namespace dart | 8485 } // namespace dart |
| OLD | NEW |