| 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 7544 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7555 } | 7555 } |
| 7556 | 7556 |
| 7557 | 7557 |
| 7558 void ConstantPropagator::VisitTargetEntry(TargetEntryInstr* block) { | 7558 void ConstantPropagator::VisitTargetEntry(TargetEntryInstr* block) { |
| 7559 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) { | 7559 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) { |
| 7560 it.Current()->Accept(this); | 7560 it.Current()->Accept(this); |
| 7561 } | 7561 } |
| 7562 } | 7562 } |
| 7563 | 7563 |
| 7564 | 7564 |
| 7565 void ConstantPropagator::VisitIndirectEntry(IndirectEntryInstr* block) { |
| 7566 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) { |
| 7567 it.Current()->Accept(this); |
| 7568 } |
| 7569 } |
| 7570 |
| 7571 |
| 7565 void ConstantPropagator::VisitCatchBlockEntry(CatchBlockEntryInstr* block) { | 7572 void ConstantPropagator::VisitCatchBlockEntry(CatchBlockEntryInstr* block) { |
| 7566 const GrowableArray<Definition*>& defs = *block->initial_definitions(); | 7573 const GrowableArray<Definition*>& defs = *block->initial_definitions(); |
| 7567 for (intptr_t i = 0; i < defs.length(); ++i) { | 7574 for (intptr_t i = 0; i < defs.length(); ++i) { |
| 7568 defs[i]->Accept(this); | 7575 defs[i]->Accept(this); |
| 7569 } | 7576 } |
| 7570 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) { | 7577 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) { |
| 7571 it.Current()->Accept(this); | 7578 it.Current()->Accept(this); |
| 7572 } | 7579 } |
| 7573 } | 7580 } |
| 7574 | 7581 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 7602 SetReachable(instr->successor()); | 7609 SetReachable(instr->successor()); |
| 7603 | 7610 |
| 7604 // Phi value depends on the reachability of a predecessor. We have | 7611 // Phi value depends on the reachability of a predecessor. We have |
| 7605 // to revisit phis every time a predecessor becomes reachable. | 7612 // to revisit phis every time a predecessor becomes reachable. |
| 7606 for (PhiIterator it(instr->successor()); !it.Done(); it.Advance()) { | 7613 for (PhiIterator it(instr->successor()); !it.Done(); it.Advance()) { |
| 7607 it.Current()->Accept(this); | 7614 it.Current()->Accept(this); |
| 7608 } | 7615 } |
| 7609 } | 7616 } |
| 7610 | 7617 |
| 7611 | 7618 |
| 7619 void ConstantPropagator::VisitIndirectGoto(IndirectGotoInstr* instr) { |
| 7620 for (intptr_t i = 0; i < instr->SuccessorCount(); i++) { |
| 7621 SetReachable(instr->SuccessorAt(i)); |
| 7622 } |
| 7623 } |
| 7624 |
| 7625 |
| 7612 void ConstantPropagator::VisitBranch(BranchInstr* instr) { | 7626 void ConstantPropagator::VisitBranch(BranchInstr* instr) { |
| 7613 instr->comparison()->Accept(this); | 7627 instr->comparison()->Accept(this); |
| 7614 | 7628 |
| 7615 // The successors may be reachable, but only if this instruction is. (We | 7629 // The successors may be reachable, but only if this instruction is. (We |
| 7616 // might be analyzing it because the constant value of one of its inputs | 7630 // might be analyzing it because the constant value of one of its inputs |
| 7617 // has changed.) | 7631 // has changed.) |
| 7618 if (reachable_->Contains(instr->GetBlock()->preorder_number())) { | 7632 if (reachable_->Contains(instr->GetBlock()->preorder_number())) { |
| 7619 if (instr->constant_target() != NULL) { | 7633 if (instr->constant_target() != NULL) { |
| 7620 ASSERT((instr->constant_target() == instr->true_successor()) || | 7634 ASSERT((instr->constant_target() == instr->true_successor()) || |
| 7621 (instr->constant_target() == instr->false_successor())); | 7635 (instr->constant_target() == instr->false_successor())); |
| (...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8010 SetValue(instr, result); | 8024 SetValue(instr, result); |
| 8011 return; | 8025 return; |
| 8012 } | 8026 } |
| 8013 } | 8027 } |
| 8014 } | 8028 } |
| 8015 SetValue(instr, non_constant_); | 8029 SetValue(instr, non_constant_); |
| 8016 } | 8030 } |
| 8017 } | 8031 } |
| 8018 | 8032 |
| 8019 | 8033 |
| 8034 void ConstantPropagator::VisitLoadCodeUnits(LoadCodeUnitsInstr* instr) { |
| 8035 // TODO(zerny): Implement constant propagation. |
| 8036 SetValue(instr, non_constant_); |
| 8037 } |
| 8038 |
| 8039 |
| 8020 void ConstantPropagator::VisitStoreIndexed(StoreIndexedInstr* instr) { | 8040 void ConstantPropagator::VisitStoreIndexed(StoreIndexedInstr* instr) { |
| 8021 SetValue(instr, instr->value()->definition()->constant_value()); | 8041 SetValue(instr, instr->value()->definition()->constant_value()); |
| 8022 } | 8042 } |
| 8023 | 8043 |
| 8024 | 8044 |
| 8025 void ConstantPropagator::VisitStoreInstanceField( | 8045 void ConstantPropagator::VisitStoreInstanceField( |
| 8026 StoreInstanceFieldInstr* instr) { | 8046 StoreInstanceFieldInstr* instr) { |
| 8027 SetValue(instr, instr->value()->definition()->constant_value()); | 8047 SetValue(instr, instr->value()->definition()->constant_value()); |
| 8028 } | 8048 } |
| 8029 | 8049 |
| (...skipping 622 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8652 const Object& right = instr->right()->definition()->constant_value(); | 8672 const Object& right = instr->right()->definition()->constant_value(); |
| 8653 if (IsNonConstant(left) || IsNonConstant(right)) { | 8673 if (IsNonConstant(left) || IsNonConstant(right)) { |
| 8654 SetValue(instr, non_constant_); | 8674 SetValue(instr, non_constant_); |
| 8655 } else if (IsConstant(left) && IsConstant(right)) { | 8675 } else if (IsConstant(left) && IsConstant(right)) { |
| 8656 // TODO(srdjan): Handle min and max. | 8676 // TODO(srdjan): Handle min and max. |
| 8657 SetValue(instr, non_constant_); | 8677 SetValue(instr, non_constant_); |
| 8658 } | 8678 } |
| 8659 } | 8679 } |
| 8660 | 8680 |
| 8661 | 8681 |
| 8682 void ConstantPropagator::VisitCaseInsensitiveCompareUC16( |
| 8683 CaseInsensitiveCompareUC16Instr *instr) { |
| 8684 SetValue(instr, non_constant_); |
| 8685 } |
| 8686 |
| 8687 |
| 8662 void ConstantPropagator::VisitUnbox(UnboxInstr* instr) { | 8688 void ConstantPropagator::VisitUnbox(UnboxInstr* instr) { |
| 8663 const Object& value = instr->value()->definition()->constant_value(); | 8689 const Object& value = instr->value()->definition()->constant_value(); |
| 8664 if (IsNonConstant(value)) { | 8690 if (IsNonConstant(value)) { |
| 8665 SetValue(instr, non_constant_); | 8691 SetValue(instr, non_constant_); |
| 8666 } else if (IsConstant(value)) { | 8692 } else if (IsConstant(value)) { |
| 8667 // TODO(kmillikin): Handle conversion. | 8693 // TODO(kmillikin): Handle conversion. |
| 8668 SetValue(instr, non_constant_); | 8694 SetValue(instr, non_constant_); |
| 8669 } | 8695 } |
| 8670 } | 8696 } |
| 8671 | 8697 |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8735 } else { | 8761 } else { |
| 8736 BlockEntryInstr* block = block_worklist_.RemoveLast(); | 8762 BlockEntryInstr* block = block_worklist_.RemoveLast(); |
| 8737 block->Accept(this); | 8763 block->Accept(this); |
| 8738 } | 8764 } |
| 8739 } | 8765 } |
| 8740 } | 8766 } |
| 8741 | 8767 |
| 8742 | 8768 |
| 8743 static bool IsEmptyBlock(BlockEntryInstr* block) { | 8769 static bool IsEmptyBlock(BlockEntryInstr* block) { |
| 8744 return block->next()->IsGoto() && | 8770 return block->next()->IsGoto() && |
| 8745 (!block->IsJoinEntry() || (block->AsJoinEntry()->phis() == NULL)); | 8771 (!block->IsJoinEntry() || (block->AsJoinEntry()->phis() == NULL)) && |
| 8772 !block->IsIndirectEntry(); |
| 8746 } | 8773 } |
| 8747 | 8774 |
| 8748 | 8775 |
| 8749 // Traverses a chain of empty blocks and returns the first reachable non-empty | 8776 // Traverses a chain of empty blocks and returns the first reachable non-empty |
| 8750 // block that is not dominated by the start block. The empty blocks are added | 8777 // block that is not dominated by the start block. The empty blocks are added |
| 8751 // to the supplied bit vector. | 8778 // to the supplied bit vector. |
| 8752 static BlockEntryInstr* FindFirstNonEmptySuccessor( | 8779 static BlockEntryInstr* FindFirstNonEmptySuccessor( |
| 8753 TargetEntryInstr* block, | 8780 TargetEntryInstr* block, |
| 8754 BitVector* empty_blocks) { | 8781 BitVector* empty_blocks) { |
| 8755 BlockEntryInstr* current = block; | 8782 BlockEntryInstr* current = block; |
| (...skipping 1168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9924 | 9951 |
| 9925 // Insert materializations at environment uses. | 9952 // Insert materializations at environment uses. |
| 9926 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) { | 9953 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) { |
| 9927 CreateMaterializationAt( | 9954 CreateMaterializationAt( |
| 9928 exits_collector_.exits()[i], alloc, alloc->cls(), *slots); | 9955 exits_collector_.exits()[i], alloc, alloc->cls(), *slots); |
| 9929 } | 9956 } |
| 9930 } | 9957 } |
| 9931 | 9958 |
| 9932 | 9959 |
| 9933 } // namespace dart | 9960 } // namespace dart |
| OLD | NEW |