| 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 7669 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7680 ConstantPropagator cp(graph, ignored); | 7680 ConstantPropagator cp(graph, ignored); |
| 7681 cp.Analyze(); | 7681 cp.Analyze(); |
| 7682 cp.Transform(); | 7682 cp.Transform(); |
| 7683 } | 7683 } |
| 7684 | 7684 |
| 7685 | 7685 |
| 7686 void ConstantPropagator::OptimizeBranches(FlowGraph* graph) { | 7686 void ConstantPropagator::OptimizeBranches(FlowGraph* graph) { |
| 7687 GrowableArray<BlockEntryInstr*> ignored; | 7687 GrowableArray<BlockEntryInstr*> ignored; |
| 7688 ConstantPropagator cp(graph, ignored); | 7688 ConstantPropagator cp(graph, ignored); |
| 7689 cp.Analyze(); | 7689 cp.Analyze(); |
| 7690 cp.VisitBranches(); | |
| 7691 cp.Transform(); | 7690 cp.Transform(); |
| 7692 cp.EliminateRedundantBranches(); | 7691 cp.EliminateRedundantBranches(); |
| 7693 } | 7692 } |
| 7694 | 7693 |
| 7695 | 7694 |
| 7696 void ConstantPropagator::SetReachable(BlockEntryInstr* block) { | 7695 void ConstantPropagator::SetReachable(BlockEntryInstr* block) { |
| 7697 if (!reachable_->Contains(block->preorder_number())) { | 7696 if (!reachable_->Contains(block->preorder_number())) { |
| 7698 reachable_->Add(block->preorder_number()); | 7697 reachable_->Add(block->preorder_number()); |
| 7699 block_worklist_.Add(block); | 7698 block_worklist_.Add(block); |
| 7700 } | 7699 } |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7825 } | 7824 } |
| 7826 | 7825 |
| 7827 | 7826 |
| 7828 void ConstantPropagator::VisitBranch(BranchInstr* instr) { | 7827 void ConstantPropagator::VisitBranch(BranchInstr* instr) { |
| 7829 instr->comparison()->Accept(this); | 7828 instr->comparison()->Accept(this); |
| 7830 | 7829 |
| 7831 // The successors may be reachable, but only if this instruction is. (We | 7830 // The successors may be reachable, but only if this instruction is. (We |
| 7832 // might be analyzing it because the constant value of one of its inputs | 7831 // might be analyzing it because the constant value of one of its inputs |
| 7833 // has changed.) | 7832 // has changed.) |
| 7834 if (reachable_->Contains(instr->GetBlock()->preorder_number())) { | 7833 if (reachable_->Contains(instr->GetBlock()->preorder_number())) { |
| 7835 const Object& value = instr->comparison()->constant_value(); | 7834 if (instr->constant_target() != NULL) { |
| 7836 if (IsNonConstant(value)) { | 7835 ASSERT((instr->constant_target() == instr->true_successor()) || |
| 7837 SetReachable(instr->true_successor()); | 7836 (instr->constant_target() == instr->false_successor())); |
| 7838 SetReachable(instr->false_successor()); | 7837 SetReachable(instr->constant_target()); |
| 7839 } else if (value.raw() == Bool::True().raw()) { | 7838 } else { |
| 7840 SetReachable(instr->true_successor()); | 7839 const Object& value = instr->comparison()->constant_value(); |
| 7841 } else if (!IsUnknown(value)) { // Any other constant. | 7840 if (IsNonConstant(value)) { |
| 7842 SetReachable(instr->false_successor()); | 7841 SetReachable(instr->true_successor()); |
| 7842 SetReachable(instr->false_successor()); |
| 7843 } else if (value.raw() == Bool::True().raw()) { |
| 7844 SetReachable(instr->true_successor()); |
| 7845 } else if (!IsUnknown(value)) { // Any other constant. |
| 7846 SetReachable(instr->false_successor()); |
| 7847 } |
| 7843 } | 7848 } |
| 7844 } | 7849 } |
| 7845 } | 7850 } |
| 7846 | 7851 |
| 7847 | 7852 |
| 7848 // -------------------------------------------------------------------------- | 7853 // -------------------------------------------------------------------------- |
| 7849 // Analysis of non-definition instructions. They do not have values so they | 7854 // Analysis of non-definition instructions. They do not have values so they |
| 7850 // cannot have constant values. | 7855 // cannot have constant values. |
| 7851 void ConstantPropagator::VisitStoreContext(StoreContextInstr* instr) { } | 7856 void ConstantPropagator::VisitStoreContext(StoreContextInstr* instr) { } |
| 7852 | 7857 |
| (...skipping 1075 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8928 use = use->next_use(); | 8933 use = use->next_use(); |
| 8929 } | 8934 } |
| 8930 } else { | 8935 } else { |
| 8931 BlockEntryInstr* block = block_worklist_.RemoveLast(); | 8936 BlockEntryInstr* block = block_worklist_.RemoveLast(); |
| 8932 block->Accept(this); | 8937 block->Accept(this); |
| 8933 } | 8938 } |
| 8934 } | 8939 } |
| 8935 } | 8940 } |
| 8936 | 8941 |
| 8937 | 8942 |
| 8938 void ConstantPropagator::VisitBranches() { | |
| 8939 GraphEntryInstr* entry = graph_->graph_entry(); | |
| 8940 reachable_->Add(entry->preorder_number()); | |
| 8941 block_worklist_.Add(entry); | |
| 8942 | |
| 8943 while (!block_worklist_.is_empty()) { | |
| 8944 BlockEntryInstr* block = block_worklist_.RemoveLast(); | |
| 8945 if (block->IsGraphEntry()) { | |
| 8946 // TODO(fschneider): Improve this approximation. Catch entries are only | |
| 8947 // reachable if a call in the corresponding try-block is reachable. | |
| 8948 for (intptr_t i = 0; i < block->SuccessorCount(); ++i) { | |
| 8949 SetReachable(block->SuccessorAt(i)); | |
| 8950 } | |
| 8951 continue; | |
| 8952 } | |
| 8953 Instruction* last = block->last_instruction(); | |
| 8954 if (last->IsGoto()) { | |
| 8955 SetReachable(last->AsGoto()->successor()); | |
| 8956 } else if (last->IsBranch()) { | |
| 8957 BranchInstr* branch = last->AsBranch(); | |
| 8958 // The current block must be reachable. | |
| 8959 ASSERT(reachable_->Contains(branch->GetBlock()->preorder_number())); | |
| 8960 if (branch->constant_target() != NULL) { | |
| 8961 // Found constant target computed by range analysis. | |
| 8962 if (branch->constant_target() == branch->true_successor()) { | |
| 8963 SetReachable(branch->true_successor()); | |
| 8964 } else { | |
| 8965 ASSERT(branch->constant_target() == branch->false_successor()); | |
| 8966 SetReachable(branch->false_successor()); | |
| 8967 } | |
| 8968 } else { | |
| 8969 // No new information: Assume both targets are reachable. | |
| 8970 SetReachable(branch->true_successor()); | |
| 8971 SetReachable(branch->false_successor()); | |
| 8972 } | |
| 8973 } | |
| 8974 } | |
| 8975 } | |
| 8976 | |
| 8977 | |
| 8978 static bool IsEmptyBlock(BlockEntryInstr* block) { | 8943 static bool IsEmptyBlock(BlockEntryInstr* block) { |
| 8979 return block->next()->IsGoto() && | 8944 return block->next()->IsGoto() && |
| 8980 (!block->IsJoinEntry() || (block->AsJoinEntry()->phis() == NULL)); | 8945 (!block->IsJoinEntry() || (block->AsJoinEntry()->phis() == NULL)); |
| 8981 } | 8946 } |
| 8982 | 8947 |
| 8983 | 8948 |
| 8984 // Traverses a chain of empty blocks and returns the first reachable non-empty | 8949 // Traverses a chain of empty blocks and returns the first reachable non-empty |
| 8985 // block that is not dominated by the start block. The empty blocks are added | 8950 // block that is not dominated by the start block. The empty blocks are added |
| 8986 // to the supplied bit vector. | 8951 // to the supplied bit vector. |
| 8987 static BlockEntryInstr* FindFirstNonEmptySuccessor( | 8952 static BlockEntryInstr* FindFirstNonEmptySuccessor( |
| (...skipping 830 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9818 } | 9783 } |
| 9819 | 9784 |
| 9820 // Insert materializations at environment uses. | 9785 // Insert materializations at environment uses. |
| 9821 for (intptr_t i = 0; i < exits.length(); i++) { | 9786 for (intptr_t i = 0; i < exits.length(); i++) { |
| 9822 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *slots); | 9787 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *slots); |
| 9823 } | 9788 } |
| 9824 } | 9789 } |
| 9825 | 9790 |
| 9826 | 9791 |
| 9827 } // namespace dart | 9792 } // namespace dart |
| OLD | NEW |