| 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 |