| 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 7641 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7652 } | 7652 } |
| 7653 | 7653 |
| 7654 | 7654 |
| 7655 void ConstantPropagator::VisitTargetEntry(TargetEntryInstr* block) { | 7655 void ConstantPropagator::VisitTargetEntry(TargetEntryInstr* block) { |
| 7656 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) { | 7656 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) { |
| 7657 it.Current()->Accept(this); | 7657 it.Current()->Accept(this); |
| 7658 } | 7658 } |
| 7659 } | 7659 } |
| 7660 | 7660 |
| 7661 | 7661 |
| 7662 void ConstantPropagator::VisitIndirectEntry(IndirectEntryInstr* block) { |
| 7663 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) { |
| 7664 it.Current()->Accept(this); |
| 7665 } |
| 7666 } |
| 7667 |
| 7668 |
| 7662 void ConstantPropagator::VisitCatchBlockEntry(CatchBlockEntryInstr* block) { | 7669 void ConstantPropagator::VisitCatchBlockEntry(CatchBlockEntryInstr* block) { |
| 7663 const GrowableArray<Definition*>& defs = *block->initial_definitions(); | 7670 const GrowableArray<Definition*>& defs = *block->initial_definitions(); |
| 7664 for (intptr_t i = 0; i < defs.length(); ++i) { | 7671 for (intptr_t i = 0; i < defs.length(); ++i) { |
| 7665 defs[i]->Accept(this); | 7672 defs[i]->Accept(this); |
| 7666 } | 7673 } |
| 7667 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) { | 7674 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) { |
| 7668 it.Current()->Accept(this); | 7675 it.Current()->Accept(this); |
| 7669 } | 7676 } |
| 7670 } | 7677 } |
| 7671 | 7678 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 7699 SetReachable(instr->successor()); | 7706 SetReachable(instr->successor()); |
| 7700 | 7707 |
| 7701 // Phi value depends on the reachability of a predecessor. We have | 7708 // Phi value depends on the reachability of a predecessor. We have |
| 7702 // to revisit phis every time a predecessor becomes reachable. | 7709 // to revisit phis every time a predecessor becomes reachable. |
| 7703 for (PhiIterator it(instr->successor()); !it.Done(); it.Advance()) { | 7710 for (PhiIterator it(instr->successor()); !it.Done(); it.Advance()) { |
| 7704 it.Current()->Accept(this); | 7711 it.Current()->Accept(this); |
| 7705 } | 7712 } |
| 7706 } | 7713 } |
| 7707 | 7714 |
| 7708 | 7715 |
| 7716 void ConstantPropagator::VisitIndirectGoto(IndirectGotoInstr* instr) { |
| 7717 for (intptr_t i = 0; i < instr->SuccessorCount(); i++) { |
| 7718 SetReachable(instr->SuccessorAt(i)); |
| 7719 } |
| 7720 } |
| 7721 |
| 7722 |
| 7709 void ConstantPropagator::VisitBranch(BranchInstr* instr) { | 7723 void ConstantPropagator::VisitBranch(BranchInstr* instr) { |
| 7710 instr->comparison()->Accept(this); | 7724 instr->comparison()->Accept(this); |
| 7711 | 7725 |
| 7712 // The successors may be reachable, but only if this instruction is. (We | 7726 // The successors may be reachable, but only if this instruction is. (We |
| 7713 // might be analyzing it because the constant value of one of its inputs | 7727 // might be analyzing it because the constant value of one of its inputs |
| 7714 // has changed.) | 7728 // has changed.) |
| 7715 if (reachable_->Contains(instr->GetBlock()->preorder_number())) { | 7729 if (reachable_->Contains(instr->GetBlock()->preorder_number())) { |
| 7716 if (instr->constant_target() != NULL) { | 7730 if (instr->constant_target() != NULL) { |
| 7717 ASSERT((instr->constant_target() == instr->true_successor()) || | 7731 ASSERT((instr->constant_target() == instr->true_successor()) || |
| 7718 (instr->constant_target() == instr->false_successor())); | 7732 (instr->constant_target() == instr->false_successor())); |
| (...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8107 SetValue(instr, result); | 8121 SetValue(instr, result); |
| 8108 return; | 8122 return; |
| 8109 } | 8123 } |
| 8110 } | 8124 } |
| 8111 } | 8125 } |
| 8112 SetValue(instr, non_constant_); | 8126 SetValue(instr, non_constant_); |
| 8113 } | 8127 } |
| 8114 } | 8128 } |
| 8115 | 8129 |
| 8116 | 8130 |
| 8131 void ConstantPropagator::VisitLoadCodeUnits(LoadCodeUnitsInstr* instr) { |
| 8132 // TODO(zerny): Implement constant propagation. |
| 8133 SetValue(instr, non_constant_); |
| 8134 } |
| 8135 |
| 8136 |
| 8117 void ConstantPropagator::VisitStoreIndexed(StoreIndexedInstr* instr) { | 8137 void ConstantPropagator::VisitStoreIndexed(StoreIndexedInstr* instr) { |
| 8118 SetValue(instr, instr->value()->definition()->constant_value()); | 8138 SetValue(instr, instr->value()->definition()->constant_value()); |
| 8119 } | 8139 } |
| 8120 | 8140 |
| 8121 | 8141 |
| 8122 void ConstantPropagator::VisitStoreInstanceField( | 8142 void ConstantPropagator::VisitStoreInstanceField( |
| 8123 StoreInstanceFieldInstr* instr) { | 8143 StoreInstanceFieldInstr* instr) { |
| 8124 SetValue(instr, instr->value()->definition()->constant_value()); | 8144 SetValue(instr, instr->value()->definition()->constant_value()); |
| 8125 } | 8145 } |
| 8126 | 8146 |
| (...skipping 622 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8749 const Object& right = instr->right()->definition()->constant_value(); | 8769 const Object& right = instr->right()->definition()->constant_value(); |
| 8750 if (IsNonConstant(left) || IsNonConstant(right)) { | 8770 if (IsNonConstant(left) || IsNonConstant(right)) { |
| 8751 SetValue(instr, non_constant_); | 8771 SetValue(instr, non_constant_); |
| 8752 } else if (IsConstant(left) && IsConstant(right)) { | 8772 } else if (IsConstant(left) && IsConstant(right)) { |
| 8753 // TODO(srdjan): Handle min and max. | 8773 // TODO(srdjan): Handle min and max. |
| 8754 SetValue(instr, non_constant_); | 8774 SetValue(instr, non_constant_); |
| 8755 } | 8775 } |
| 8756 } | 8776 } |
| 8757 | 8777 |
| 8758 | 8778 |
| 8779 void ConstantPropagator::VisitCaseInsensitiveCompareUC16( |
| 8780 CaseInsensitiveCompareUC16Instr *instr) { |
| 8781 SetValue(instr, non_constant_); |
| 8782 } |
| 8783 |
| 8784 |
| 8759 void ConstantPropagator::VisitUnboxDouble(UnboxDoubleInstr* instr) { | 8785 void ConstantPropagator::VisitUnboxDouble(UnboxDoubleInstr* instr) { |
| 8760 const Object& value = instr->value()->definition()->constant_value(); | 8786 const Object& value = instr->value()->definition()->constant_value(); |
| 8761 if (IsNonConstant(value)) { | 8787 if (IsNonConstant(value)) { |
| 8762 SetValue(instr, non_constant_); | 8788 SetValue(instr, non_constant_); |
| 8763 } else if (IsConstant(value)) { | 8789 } else if (IsConstant(value)) { |
| 8764 // TODO(kmillikin): Handle conversion. | 8790 // TODO(kmillikin): Handle conversion. |
| 8765 SetValue(instr, non_constant_); | 8791 SetValue(instr, non_constant_); |
| 8766 } | 8792 } |
| 8767 } | 8793 } |
| 8768 | 8794 |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8898 } else { | 8924 } else { |
| 8899 BlockEntryInstr* block = block_worklist_.RemoveLast(); | 8925 BlockEntryInstr* block = block_worklist_.RemoveLast(); |
| 8900 block->Accept(this); | 8926 block->Accept(this); |
| 8901 } | 8927 } |
| 8902 } | 8928 } |
| 8903 } | 8929 } |
| 8904 | 8930 |
| 8905 | 8931 |
| 8906 static bool IsEmptyBlock(BlockEntryInstr* block) { | 8932 static bool IsEmptyBlock(BlockEntryInstr* block) { |
| 8907 return block->next()->IsGoto() && | 8933 return block->next()->IsGoto() && |
| 8908 (!block->IsJoinEntry() || (block->AsJoinEntry()->phis() == NULL)); | 8934 (!block->IsJoinEntry() || (block->AsJoinEntry()->phis() == NULL)) && |
| 8935 !block->IsIndirectEntry(); |
| 8909 } | 8936 } |
| 8910 | 8937 |
| 8911 | 8938 |
| 8912 // Traverses a chain of empty blocks and returns the first reachable non-empty | 8939 // Traverses a chain of empty blocks and returns the first reachable non-empty |
| 8913 // block that is not dominated by the start block. The empty blocks are added | 8940 // block that is not dominated by the start block. The empty blocks are added |
| 8914 // to the supplied bit vector. | 8941 // to the supplied bit vector. |
| 8915 static BlockEntryInstr* FindFirstNonEmptySuccessor( | 8942 static BlockEntryInstr* FindFirstNonEmptySuccessor( |
| 8916 TargetEntryInstr* block, | 8943 TargetEntryInstr* block, |
| 8917 BitVector* empty_blocks) { | 8944 BitVector* empty_blocks) { |
| 8918 BlockEntryInstr* current = block; | 8945 BlockEntryInstr* current = block; |
| (...skipping 1170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10089 | 10116 |
| 10090 // Insert materializations at environment uses. | 10117 // Insert materializations at environment uses. |
| 10091 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) { | 10118 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) { |
| 10092 CreateMaterializationAt( | 10119 CreateMaterializationAt( |
| 10093 exits_collector_.exits()[i], alloc, alloc->cls(), *slots); | 10120 exits_collector_.exits()[i], alloc, alloc->cls(), *slots); |
| 10094 } | 10121 } |
| 10095 } | 10122 } |
| 10096 | 10123 |
| 10097 | 10124 |
| 10098 } // namespace dart | 10125 } // namespace dart |
| OLD | NEW |