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 4549 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4560 new Value(flow_graph_->constant_null()), | 4560 new Value(flow_graph_->constant_null()), |
4561 kNoStoreBarrier, | 4561 kNoStoreBarrier, |
4562 instr->token_pos()); | 4562 instr->token_pos()); |
4563 store->set_is_initialization(true); // Won't be eliminated by DSE. | 4563 store->set_is_initialization(true); // Won't be eliminated by DSE. |
4564 flow_graph_->InsertAfter(cursor, store, NULL, FlowGraph::kEffect); | 4564 flow_graph_->InsertAfter(cursor, store, NULL, FlowGraph::kEffect); |
4565 cursor = store; | 4565 cursor = store; |
4566 } | 4566 } |
4567 } | 4567 } |
4568 | 4568 |
4569 | 4569 |
4570 void FlowGraphOptimizer::VisitLoadCodeUnits(LoadCodeUnitsInstr* instr) { | |
4571 // TODO(zerny): Use kUnboxedUint32 once it is fully supported/optimized. | |
4572 #if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_ARM) | |
4573 if (!instr->can_pack_into_smi()) | |
4574 instr->set_representation(kUnboxedMint); | |
4575 #endif | |
4576 } | |
4577 | |
4578 | |
4579 bool FlowGraphOptimizer::TryInlineInstanceSetter(InstanceCallInstr* instr, | 4570 bool FlowGraphOptimizer::TryInlineInstanceSetter(InstanceCallInstr* instr, |
4580 const ICData& unary_ic_data) { | 4571 const ICData& unary_ic_data) { |
4581 ASSERT((unary_ic_data.NumberOfChecks() > 0) && | 4572 ASSERT((unary_ic_data.NumberOfChecks() > 0) && |
4582 (unary_ic_data.NumArgsTested() == 1)); | 4573 (unary_ic_data.NumArgsTested() == 1)); |
4583 if (FLAG_enable_type_checks) { | 4574 if (FLAG_enable_type_checks) { |
4584 // Checked mode setters are inlined like normal methods by conventional | 4575 // Checked mode setters are inlined like normal methods by conventional |
4585 // inlining. | 4576 // inlining. |
4586 return false; | 4577 return false; |
4587 } | 4578 } |
4588 | 4579 |
(...skipping 3003 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7592 } | 7583 } |
7593 | 7584 |
7594 | 7585 |
7595 void ConstantPropagator::VisitTargetEntry(TargetEntryInstr* block) { | 7586 void ConstantPropagator::VisitTargetEntry(TargetEntryInstr* block) { |
7596 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) { | 7587 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) { |
7597 it.Current()->Accept(this); | 7588 it.Current()->Accept(this); |
7598 } | 7589 } |
7599 } | 7590 } |
7600 | 7591 |
7601 | 7592 |
7602 void ConstantPropagator::VisitIndirectEntry(IndirectEntryInstr* block) { | |
7603 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) { | |
7604 it.Current()->Accept(this); | |
7605 } | |
7606 } | |
7607 | |
7608 | |
7609 void ConstantPropagator::VisitCatchBlockEntry(CatchBlockEntryInstr* block) { | 7593 void ConstantPropagator::VisitCatchBlockEntry(CatchBlockEntryInstr* block) { |
7610 const GrowableArray<Definition*>& defs = *block->initial_definitions(); | 7594 const GrowableArray<Definition*>& defs = *block->initial_definitions(); |
7611 for (intptr_t i = 0; i < defs.length(); ++i) { | 7595 for (intptr_t i = 0; i < defs.length(); ++i) { |
7612 defs[i]->Accept(this); | 7596 defs[i]->Accept(this); |
7613 } | 7597 } |
7614 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) { | 7598 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) { |
7615 it.Current()->Accept(this); | 7599 it.Current()->Accept(this); |
7616 } | 7600 } |
7617 } | 7601 } |
7618 | 7602 |
(...skipping 27 matching lines...) Expand all Loading... |
7646 SetReachable(instr->successor()); | 7630 SetReachable(instr->successor()); |
7647 | 7631 |
7648 // Phi value depends on the reachability of a predecessor. We have | 7632 // Phi value depends on the reachability of a predecessor. We have |
7649 // to revisit phis every time a predecessor becomes reachable. | 7633 // to revisit phis every time a predecessor becomes reachable. |
7650 for (PhiIterator it(instr->successor()); !it.Done(); it.Advance()) { | 7634 for (PhiIterator it(instr->successor()); !it.Done(); it.Advance()) { |
7651 it.Current()->Accept(this); | 7635 it.Current()->Accept(this); |
7652 } | 7636 } |
7653 } | 7637 } |
7654 | 7638 |
7655 | 7639 |
7656 void ConstantPropagator::VisitIndirectGoto(IndirectGotoInstr* instr) { | |
7657 for (intptr_t i = 0; i < instr->SuccessorCount(); i++) { | |
7658 SetReachable(instr->SuccessorAt(i)); | |
7659 } | |
7660 } | |
7661 | |
7662 | |
7663 void ConstantPropagator::VisitBranch(BranchInstr* instr) { | 7640 void ConstantPropagator::VisitBranch(BranchInstr* instr) { |
7664 instr->comparison()->Accept(this); | 7641 instr->comparison()->Accept(this); |
7665 | 7642 |
7666 // The successors may be reachable, but only if this instruction is. (We | 7643 // The successors may be reachable, but only if this instruction is. (We |
7667 // might be analyzing it because the constant value of one of its inputs | 7644 // might be analyzing it because the constant value of one of its inputs |
7668 // has changed.) | 7645 // has changed.) |
7669 if (reachable_->Contains(instr->GetBlock()->preorder_number())) { | 7646 if (reachable_->Contains(instr->GetBlock()->preorder_number())) { |
7670 if (instr->constant_target() != NULL) { | 7647 if (instr->constant_target() != NULL) { |
7671 ASSERT((instr->constant_target() == instr->true_successor()) || | 7648 ASSERT((instr->constant_target() == instr->true_successor()) || |
7672 (instr->constant_target() == instr->false_successor())); | 7649 (instr->constant_target() == instr->false_successor())); |
(...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8115 SetValue(instr, result); | 8092 SetValue(instr, result); |
8116 return; | 8093 return; |
8117 } | 8094 } |
8118 } | 8095 } |
8119 } | 8096 } |
8120 SetValue(instr, non_constant_); | 8097 SetValue(instr, non_constant_); |
8121 } | 8098 } |
8122 } | 8099 } |
8123 | 8100 |
8124 | 8101 |
8125 void ConstantPropagator::VisitLoadCodeUnits(LoadCodeUnitsInstr* instr) { | |
8126 // TODO(zerny): Implement constant propagation. | |
8127 SetValue(instr, non_constant_); | |
8128 } | |
8129 | |
8130 | |
8131 void ConstantPropagator::VisitStoreIndexed(StoreIndexedInstr* instr) { | 8102 void ConstantPropagator::VisitStoreIndexed(StoreIndexedInstr* instr) { |
8132 SetValue(instr, instr->value()->definition()->constant_value()); | 8103 SetValue(instr, instr->value()->definition()->constant_value()); |
8133 } | 8104 } |
8134 | 8105 |
8135 | 8106 |
8136 void ConstantPropagator::VisitStoreInstanceField( | 8107 void ConstantPropagator::VisitStoreInstanceField( |
8137 StoreInstanceFieldInstr* instr) { | 8108 StoreInstanceFieldInstr* instr) { |
8138 SetValue(instr, instr->value()->definition()->constant_value()); | 8109 SetValue(instr, instr->value()->definition()->constant_value()); |
8139 } | 8110 } |
8140 | 8111 |
(...skipping 622 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8763 const Object& right = instr->right()->definition()->constant_value(); | 8734 const Object& right = instr->right()->definition()->constant_value(); |
8764 if (IsNonConstant(left) || IsNonConstant(right)) { | 8735 if (IsNonConstant(left) || IsNonConstant(right)) { |
8765 SetValue(instr, non_constant_); | 8736 SetValue(instr, non_constant_); |
8766 } else if (IsConstant(left) && IsConstant(right)) { | 8737 } else if (IsConstant(left) && IsConstant(right)) { |
8767 // TODO(srdjan): Handle min and max. | 8738 // TODO(srdjan): Handle min and max. |
8768 SetValue(instr, non_constant_); | 8739 SetValue(instr, non_constant_); |
8769 } | 8740 } |
8770 } | 8741 } |
8771 | 8742 |
8772 | 8743 |
8773 void ConstantPropagator::VisitCaseInsensitiveCompareUC16( | |
8774 CaseInsensitiveCompareUC16Instr *instr) { | |
8775 SetValue(instr, non_constant_); | |
8776 } | |
8777 | |
8778 | |
8779 void ConstantPropagator::VisitUnbox(UnboxInstr* instr) { | 8744 void ConstantPropagator::VisitUnbox(UnboxInstr* instr) { |
8780 const Object& value = instr->value()->definition()->constant_value(); | 8745 const Object& value = instr->value()->definition()->constant_value(); |
8781 if (IsNonConstant(value)) { | 8746 if (IsNonConstant(value)) { |
8782 SetValue(instr, non_constant_); | 8747 SetValue(instr, non_constant_); |
8783 } else if (IsConstant(value)) { | 8748 } else if (IsConstant(value)) { |
8784 // TODO(kmillikin): Handle conversion. | 8749 // TODO(kmillikin): Handle conversion. |
8785 SetValue(instr, non_constant_); | 8750 SetValue(instr, non_constant_); |
8786 } | 8751 } |
8787 } | 8752 } |
8788 | 8753 |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8851 } else { | 8816 } else { |
8852 BlockEntryInstr* block = block_worklist_.RemoveLast(); | 8817 BlockEntryInstr* block = block_worklist_.RemoveLast(); |
8853 block->Accept(this); | 8818 block->Accept(this); |
8854 } | 8819 } |
8855 } | 8820 } |
8856 } | 8821 } |
8857 | 8822 |
8858 | 8823 |
8859 static bool IsEmptyBlock(BlockEntryInstr* block) { | 8824 static bool IsEmptyBlock(BlockEntryInstr* block) { |
8860 return block->next()->IsGoto() && | 8825 return block->next()->IsGoto() && |
8861 (!block->IsJoinEntry() || (block->AsJoinEntry()->phis() == NULL)) && | 8826 (!block->IsJoinEntry() || (block->AsJoinEntry()->phis() == NULL)); |
8862 !block->IsIndirectEntry(); | |
8863 } | 8827 } |
8864 | 8828 |
8865 | 8829 |
8866 // Traverses a chain of empty blocks and returns the first reachable non-empty | 8830 // Traverses a chain of empty blocks and returns the first reachable non-empty |
8867 // block that is not dominated by the start block. The empty blocks are added | 8831 // block that is not dominated by the start block. The empty blocks are added |
8868 // to the supplied bit vector. | 8832 // to the supplied bit vector. |
8869 static BlockEntryInstr* FindFirstNonEmptySuccessor( | 8833 static BlockEntryInstr* FindFirstNonEmptySuccessor( |
8870 TargetEntryInstr* block, | 8834 TargetEntryInstr* block, |
8871 BitVector* empty_blocks) { | 8835 BitVector* empty_blocks) { |
8872 BlockEntryInstr* current = block; | 8836 BlockEntryInstr* current = block; |
(...skipping 1186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10059 | 10023 |
10060 // Insert materializations at environment uses. | 10024 // Insert materializations at environment uses. |
10061 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) { | 10025 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) { |
10062 CreateMaterializationAt( | 10026 CreateMaterializationAt( |
10063 exits_collector_.exits()[i], alloc, *slots); | 10027 exits_collector_.exits()[i], alloc, *slots); |
10064 } | 10028 } |
10065 } | 10029 } |
10066 | 10030 |
10067 | 10031 |
10068 } // namespace dart | 10032 } // namespace dart |
OLD | NEW |