Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(634)

Side by Side Diff: runtime/vm/flow_graph_optimizer.cc

Issue 374093003: Fix branch optimizations based on range analysis. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/flow_graph_optimizer.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_optimizer.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698