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

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

Issue 25277002: Revert r28050 due to crashes with --optimization-counter-threshold=5. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 2 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') | runtime/vm/intermediate_language.h » ('j') | 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/dart_entry.h" 9 #include "vm/dart_entry.h"
10 #include "vm/flow_graph_builder.h" 10 #include "vm/flow_graph_builder.h"
(...skipping 5750 matching lines...) Expand 10 before | Expand all | Expand 10 after
5761 cp.Transform(); 5761 cp.Transform();
5762 } 5762 }
5763 5763
5764 5764
5765 void ConstantPropagator::OptimizeBranches(FlowGraph* graph) { 5765 void ConstantPropagator::OptimizeBranches(FlowGraph* graph) {
5766 GrowableArray<BlockEntryInstr*> ignored; 5766 GrowableArray<BlockEntryInstr*> ignored;
5767 ConstantPropagator cp(graph, ignored); 5767 ConstantPropagator cp(graph, ignored);
5768 cp.Analyze(); 5768 cp.Analyze();
5769 cp.VisitBranches(); 5769 cp.VisitBranches();
5770 cp.Transform(); 5770 cp.Transform();
5771 cp.EliminateRedundantBranches();
5772 } 5771 }
5773 5772
5774 5773
5775 void ConstantPropagator::SetReachable(BlockEntryInstr* block) { 5774 void ConstantPropagator::SetReachable(BlockEntryInstr* block) {
5776 if (!reachable_->Contains(block->preorder_number())) { 5775 if (!reachable_->Contains(block->preorder_number())) {
5777 reachable_->Add(block->preorder_number()); 5776 reachable_->Add(block->preorder_number());
5778 block_worklist_.Add(block); 5777 block_worklist_.Add(block);
5779 } 5778 }
5780 } 5779 }
5781 5780
(...skipping 1062 matching lines...) Expand 10 before | Expand all | Expand 10 after
6844 } else { 6843 } else {
6845 // No new information: Assume both targets are reachable. 6844 // No new information: Assume both targets are reachable.
6846 SetReachable(branch->true_successor()); 6845 SetReachable(branch->true_successor());
6847 SetReachable(branch->false_successor()); 6846 SetReachable(branch->false_successor());
6848 } 6847 }
6849 } 6848 }
6850 } 6849 }
6851 } 6850 }
6852 6851
6853 6852
6854 // Traverses a chain of empty blocks and returns the first reachable non-empty
6855 // block. Empty blocks are added to the supplied bit vector.
6856 static BlockEntryInstr* FindFirstNonEmptySuccessor(
6857 TargetEntryInstr* block,
6858 BitVector* empty_blocks) {
6859 BlockEntryInstr* current = block;
6860 while (current->IsEmptyBlock()) {
Florian Schneider 2013/09/30 14:58:00 There is a bug: I need to check for (#predecessors
6861 empty_blocks->Add(current->preorder_number());
6862 current = current->next()->AsGoto()->successor();
6863 }
6864 return current;
6865 }
6866
6867
6868 void ConstantPropagator::EliminateRedundantBranches() {
6869 // Canonicalize branches that have no side-effects and where true- and
6870 // false-targets are the same.
6871 BitVector* empty_blocks = new BitVector(graph_->preorder().length());
6872 for (BlockIterator b = graph_->postorder_iterator();
6873 !b.Done();
6874 b.Advance()) {
6875 BlockEntryInstr* block = b.Current();
6876 BranchInstr* branch = block->last_instruction()->AsBranch();
6877 empty_blocks->Clear();
6878 if ((branch != NULL) && branch->Effects().IsNone()) {
6879 ASSERT(branch->previous() != NULL); // Not already eliminated.
6880 BlockEntryInstr* if_true =
6881 FindFirstNonEmptySuccessor(branch->true_successor(), empty_blocks);
6882 BlockEntryInstr* if_false =
6883 FindFirstNonEmptySuccessor(branch->false_successor(), empty_blocks);
6884 if (if_true == if_false) {
6885 // Replace the branch with a jump to the common successor.
6886 // Drop the comparison, which does not have side effects
6887 JoinEntryInstr* join = if_true->AsJoinEntry();
6888 if (join->phis() == NULL) {
6889 GotoInstr* jump = new GotoInstr(if_true->AsJoinEntry());
6890 jump->InheritDeoptTarget(branch);
6891
6892 Instruction* previous = branch->previous();
6893 branch->set_previous(NULL);
6894 previous->LinkTo(jump);
6895
6896 // Remove uses from branch and all the empty blocks that
6897 // are now unreachable.
6898 branch->UnuseAllInputs();
6899 for (BitVector::Iterator it(empty_blocks); !it.Done(); it.Advance()) {
6900 BlockEntryInstr* empty_block = graph_->preorder()[it.Current()];
6901 empty_block->ClearAllInstructions();
6902 }
6903
6904 if (FLAG_trace_constant_propagation) {
6905 OS::Print("Eliminated branch in B%"Pd" common target B%"Pd"\n",
6906 block->block_id(), join->block_id());
6907 }
6908 }
6909 }
6910 }
6911 }
6912
6913 graph_->DiscoverBlocks();
6914 GrowableArray<BitVector*> dominance_frontier;
6915 graph_->ComputeDominators(&dominance_frontier);
6916 }
6917
6918
6919 void ConstantPropagator::Transform() { 6853 void ConstantPropagator::Transform() {
6920 if (FLAG_trace_constant_propagation) { 6854 if (FLAG_trace_constant_propagation) {
6921 OS::Print("\n==== Before constant propagation ====\n"); 6855 OS::Print("\n==== Before constant propagation ====\n");
6922 FlowGraphPrinter printer(*graph_); 6856 FlowGraphPrinter printer(*graph_);
6923 printer.PrintBlocks(); 6857 printer.PrintBlocks();
6924 } 6858 }
6925 6859
6926 GrowableArray<PhiInstr*> redundant_phis(10); 6860 GrowableArray<PhiInstr*> redundant_phis(10);
6927 6861
6928 // We will recompute dominators, block ordering, block ids, block last 6862 // We will recompute dominators, block ordering, block ids, block last
6929 // instructions, previous pointers, predecessors, etc. after eliminating 6863 // instructions, previous pointers, predecessors, etc. after eliminating
6930 // unreachable code. We do not maintain those properties during the 6864 // unreachable code. We do not maintain those properties during the
6931 // transformation. 6865 // transformation.
6932 for (BlockIterator b = graph_->reverse_postorder_iterator(); 6866 for (BlockIterator b = graph_->reverse_postorder_iterator();
6933 !b.Done(); 6867 !b.Done();
6934 b.Advance()) { 6868 b.Advance()) {
6935 BlockEntryInstr* block = b.Current(); 6869 BlockEntryInstr* block = b.Current();
6870 JoinEntryInstr* join = block->AsJoinEntry();
6936 if (!reachable_->Contains(block->preorder_number())) { 6871 if (!reachable_->Contains(block->preorder_number())) {
6937 if (FLAG_trace_constant_propagation) { 6872 if (FLAG_trace_constant_propagation) {
6938 OS::Print("Unreachable B%" Pd "\n", block->block_id()); 6873 OS::Print("Unreachable B%" Pd "\n", block->block_id());
6939 } 6874 }
6940 // Remove all uses in unreachable blocks. 6875 // Remove all uses in unreachable blocks.
6941 block->ClearAllInstructions(); 6876 if (join != NULL) {
6877 for (PhiIterator it(join); !it.Done(); it.Advance()) {
6878 it.Current()->UnuseAllInputs();
6879 }
6880 }
6881 block->UnuseAllInputs();
6882 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
6883 it.Current()->UnuseAllInputs();
6884 }
6942 continue; 6885 continue;
6943 } 6886 }
6944 6887
6945 JoinEntryInstr* join = block->AsJoinEntry();
6946 if (join != NULL) { 6888 if (join != NULL) {
6947 // Remove phi inputs corresponding to unreachable predecessor blocks. 6889 // Remove phi inputs corresponding to unreachable predecessor blocks.
6948 // Predecessors will be recomputed (in block id order) after removing 6890 // Predecessors will be recomputed (in block id order) after removing
6949 // unreachable code so we merely have to keep the phi inputs in order. 6891 // unreachable code so we merely have to keep the phi inputs in order.
6950 ZoneGrowableArray<PhiInstr*>* phis = join->phis(); 6892 ZoneGrowableArray<PhiInstr*>* phis = join->phis();
6951 if ((phis != NULL) && !phis->is_empty()) { 6893 if ((phis != NULL) && !phis->is_empty()) {
6952 intptr_t pred_count = join->PredecessorCount(); 6894 intptr_t pred_count = join->PredecessorCount();
6953 intptr_t live_count = 0; 6895 intptr_t live_count = 0;
6954 for (intptr_t pred_idx = 0; pred_idx < pred_count; ++pred_idx) { 6896 for (intptr_t pred_idx = 0; pred_idx < pred_count; ++pred_idx) {
6955 if (reachable_->Contains( 6897 if (reachable_->Contains(
(...skipping 737 matching lines...) Expand 10 before | Expand all | Expand 10 after
7693 } 7635 }
7694 7636
7695 // Insert materializations at environment uses. 7637 // Insert materializations at environment uses.
7696 for (intptr_t i = 0; i < exits.length(); i++) { 7638 for (intptr_t i = 0; i < exits.length(); i++) {
7697 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields); 7639 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields);
7698 } 7640 }
7699 } 7641 }
7700 7642
7701 7643
7702 } // namespace dart 7644 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_optimizer.h ('k') | runtime/vm/intermediate_language.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698