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 7623 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7634 } | 7634 } |
7635 | 7635 |
7636 | 7636 |
7637 void ConstantPropagator::VisitTargetEntry(TargetEntryInstr* block) { | 7637 void ConstantPropagator::VisitTargetEntry(TargetEntryInstr* block) { |
7638 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) { | 7638 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) { |
7639 it.Current()->Accept(this); | 7639 it.Current()->Accept(this); |
7640 } | 7640 } |
7641 } | 7641 } |
7642 | 7642 |
7643 | 7643 |
| 7644 void ConstantPropagator::VisitIndirectEntry(IndirectEntryInstr* block) { |
| 7645 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) { |
| 7646 it.Current()->Accept(this); |
| 7647 } |
| 7648 } |
| 7649 |
| 7650 |
7644 void ConstantPropagator::VisitCatchBlockEntry(CatchBlockEntryInstr* block) { | 7651 void ConstantPropagator::VisitCatchBlockEntry(CatchBlockEntryInstr* block) { |
7645 const GrowableArray<Definition*>& defs = *block->initial_definitions(); | 7652 const GrowableArray<Definition*>& defs = *block->initial_definitions(); |
7646 for (intptr_t i = 0; i < defs.length(); ++i) { | 7653 for (intptr_t i = 0; i < defs.length(); ++i) { |
7647 defs[i]->Accept(this); | 7654 defs[i]->Accept(this); |
7648 } | 7655 } |
7649 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) { | 7656 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) { |
7650 it.Current()->Accept(this); | 7657 it.Current()->Accept(this); |
7651 } | 7658 } |
7652 } | 7659 } |
7653 | 7660 |
(...skipping 27 matching lines...) Expand all Loading... |
7681 SetReachable(instr->successor()); | 7688 SetReachable(instr->successor()); |
7682 | 7689 |
7683 // Phi value depends on the reachability of a predecessor. We have | 7690 // Phi value depends on the reachability of a predecessor. We have |
7684 // to revisit phis every time a predecessor becomes reachable. | 7691 // to revisit phis every time a predecessor becomes reachable. |
7685 for (PhiIterator it(instr->successor()); !it.Done(); it.Advance()) { | 7692 for (PhiIterator it(instr->successor()); !it.Done(); it.Advance()) { |
7686 it.Current()->Accept(this); | 7693 it.Current()->Accept(this); |
7687 } | 7694 } |
7688 } | 7695 } |
7689 | 7696 |
7690 | 7697 |
| 7698 void ConstantPropagator::VisitIndirectGoto(IndirectGotoInstr* instr) { |
| 7699 for (intptr_t i = 0; i < instr->SuccessorCount(); i++) { |
| 7700 SetReachable(instr->SuccessorAt(i)); |
| 7701 } |
| 7702 } |
| 7703 |
| 7704 |
7691 void ConstantPropagator::VisitBranch(BranchInstr* instr) { | 7705 void ConstantPropagator::VisitBranch(BranchInstr* instr) { |
7692 instr->comparison()->Accept(this); | 7706 instr->comparison()->Accept(this); |
7693 | 7707 |
7694 // The successors may be reachable, but only if this instruction is. (We | 7708 // The successors may be reachable, but only if this instruction is. (We |
7695 // might be analyzing it because the constant value of one of its inputs | 7709 // might be analyzing it because the constant value of one of its inputs |
7696 // has changed.) | 7710 // has changed.) |
7697 if (reachable_->Contains(instr->GetBlock()->preorder_number())) { | 7711 if (reachable_->Contains(instr->GetBlock()->preorder_number())) { |
7698 if (instr->constant_target() != NULL) { | 7712 if (instr->constant_target() != NULL) { |
7699 ASSERT((instr->constant_target() == instr->true_successor()) || | 7713 ASSERT((instr->constant_target() == instr->true_successor()) || |
7700 (instr->constant_target() == instr->false_successor())); | 7714 (instr->constant_target() == instr->false_successor())); |
(...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8143 SetValue(instr, result); | 8157 SetValue(instr, result); |
8144 return; | 8158 return; |
8145 } | 8159 } |
8146 } | 8160 } |
8147 } | 8161 } |
8148 SetValue(instr, non_constant_); | 8162 SetValue(instr, non_constant_); |
8149 } | 8163 } |
8150 } | 8164 } |
8151 | 8165 |
8152 | 8166 |
| 8167 void ConstantPropagator::VisitLoadCodeUnits(LoadCodeUnitsInstr* instr) { |
| 8168 // TODO(zerny): Implement constant propagation. |
| 8169 SetValue(instr, non_constant_); |
| 8170 } |
| 8171 |
| 8172 |
8153 void ConstantPropagator::VisitStoreIndexed(StoreIndexedInstr* instr) { | 8173 void ConstantPropagator::VisitStoreIndexed(StoreIndexedInstr* instr) { |
8154 SetValue(instr, instr->value()->definition()->constant_value()); | 8174 SetValue(instr, instr->value()->definition()->constant_value()); |
8155 } | 8175 } |
8156 | 8176 |
8157 | 8177 |
8158 void ConstantPropagator::VisitStoreInstanceField( | 8178 void ConstantPropagator::VisitStoreInstanceField( |
8159 StoreInstanceFieldInstr* instr) { | 8179 StoreInstanceFieldInstr* instr) { |
8160 SetValue(instr, instr->value()->definition()->constant_value()); | 8180 SetValue(instr, instr->value()->definition()->constant_value()); |
8161 } | 8181 } |
8162 | 8182 |
(...skipping 622 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8785 const Object& right = instr->right()->definition()->constant_value(); | 8805 const Object& right = instr->right()->definition()->constant_value(); |
8786 if (IsNonConstant(left) || IsNonConstant(right)) { | 8806 if (IsNonConstant(left) || IsNonConstant(right)) { |
8787 SetValue(instr, non_constant_); | 8807 SetValue(instr, non_constant_); |
8788 } else if (IsConstant(left) && IsConstant(right)) { | 8808 } else if (IsConstant(left) && IsConstant(right)) { |
8789 // TODO(srdjan): Handle min and max. | 8809 // TODO(srdjan): Handle min and max. |
8790 SetValue(instr, non_constant_); | 8810 SetValue(instr, non_constant_); |
8791 } | 8811 } |
8792 } | 8812 } |
8793 | 8813 |
8794 | 8814 |
| 8815 void ConstantPropagator::VisitCaseInsensitiveCompareUC16( |
| 8816 CaseInsensitiveCompareUC16Instr *instr) { |
| 8817 SetValue(instr, non_constant_); |
| 8818 } |
| 8819 |
| 8820 |
8795 void ConstantPropagator::VisitUnbox(UnboxInstr* instr) { | 8821 void ConstantPropagator::VisitUnbox(UnboxInstr* instr) { |
8796 const Object& value = instr->value()->definition()->constant_value(); | 8822 const Object& value = instr->value()->definition()->constant_value(); |
8797 if (IsNonConstant(value)) { | 8823 if (IsNonConstant(value)) { |
8798 SetValue(instr, non_constant_); | 8824 SetValue(instr, non_constant_); |
8799 } else if (IsConstant(value)) { | 8825 } else if (IsConstant(value)) { |
8800 // TODO(kmillikin): Handle conversion. | 8826 // TODO(kmillikin): Handle conversion. |
8801 SetValue(instr, non_constant_); | 8827 SetValue(instr, non_constant_); |
8802 } | 8828 } |
8803 } | 8829 } |
8804 | 8830 |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8867 } else { | 8893 } else { |
8868 BlockEntryInstr* block = block_worklist_.RemoveLast(); | 8894 BlockEntryInstr* block = block_worklist_.RemoveLast(); |
8869 block->Accept(this); | 8895 block->Accept(this); |
8870 } | 8896 } |
8871 } | 8897 } |
8872 } | 8898 } |
8873 | 8899 |
8874 | 8900 |
8875 static bool IsEmptyBlock(BlockEntryInstr* block) { | 8901 static bool IsEmptyBlock(BlockEntryInstr* block) { |
8876 return block->next()->IsGoto() && | 8902 return block->next()->IsGoto() && |
8877 (!block->IsJoinEntry() || (block->AsJoinEntry()->phis() == NULL)); | 8903 (!block->IsJoinEntry() || (block->AsJoinEntry()->phis() == NULL)) && |
| 8904 !block->IsIndirectEntry(); |
8878 } | 8905 } |
8879 | 8906 |
8880 | 8907 |
8881 // Traverses a chain of empty blocks and returns the first reachable non-empty | 8908 // Traverses a chain of empty blocks and returns the first reachable non-empty |
8882 // block that is not dominated by the start block. The empty blocks are added | 8909 // block that is not dominated by the start block. The empty blocks are added |
8883 // to the supplied bit vector. | 8910 // to the supplied bit vector. |
8884 static BlockEntryInstr* FindFirstNonEmptySuccessor( | 8911 static BlockEntryInstr* FindFirstNonEmptySuccessor( |
8885 TargetEntryInstr* block, | 8912 TargetEntryInstr* block, |
8886 BitVector* empty_blocks) { | 8913 BitVector* empty_blocks) { |
8887 BlockEntryInstr* current = block; | 8914 BlockEntryInstr* current = block; |
(...skipping 1186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10074 | 10101 |
10075 // Insert materializations at environment uses. | 10102 // Insert materializations at environment uses. |
10076 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) { | 10103 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) { |
10077 CreateMaterializationAt( | 10104 CreateMaterializationAt( |
10078 exits_collector_.exits()[i], alloc, *slots); | 10105 exits_collector_.exits()[i], alloc, *slots); |
10079 } | 10106 } |
10080 } | 10107 } |
10081 | 10108 |
10082 | 10109 |
10083 } // namespace dart | 10110 } // namespace dart |
OLD | NEW |