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

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

Issue 183303002: Fix bug in load elimination with multiple phis. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 9 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 | « no previous file | tests/language/vm/load_to_load_forwarding_vm_test.dart » ('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/cpu.h" 9 #include "vm/cpu.h"
10 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 5606 matching lines...) Expand 10 before | Expand all | Expand 10 after
5617 input_place.set_id(places->length()); 5617 input_place.set_id(places->length());
5618 result = Place::Wrap(input_place); 5618 result = Place::Wrap(input_place);
5619 map->Insert(result); 5619 map->Insert(result);
5620 places->Add(result); 5620 places->Add(result);
5621 if (FLAG_trace_optimization) { 5621 if (FLAG_trace_optimization) {
5622 OS::Print(" adding place %s as %" Pd "\n", 5622 OS::Print(" adding place %s as %" Pd "\n",
5623 result->ToCString(), 5623 result->ToCString(),
5624 result->id()); 5624 result->id());
5625 } 5625 }
5626 } 5626 }
5627
5628 phi_moves->CreateOutgoingMove(block->PredecessorAt(j), 5627 phi_moves->CreateOutgoingMove(block->PredecessorAt(j),
5629 result->id(), 5628 result->id(),
5630 place->id()); 5629 place->id());
5631 } 5630 }
5632 } 5631 }
5633 } 5632 }
5634 5633
5635 return phi_moves; 5634 return phi_moves;
5636 } 5635 }
5637 5636
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
5763 return forwarded_; 5762 return forwarded_;
5764 } 5763 }
5765 5764
5766 // Compute sets of loads generated and killed by each block. 5765 // Compute sets of loads generated and killed by each block.
5767 // Additionally compute upwards exposed and generated loads for each block. 5766 // Additionally compute upwards exposed and generated loads for each block.
5768 // Exposed loads are those that can be replaced if a corresponding 5767 // Exposed loads are those that can be replaced if a corresponding
5769 // reaching load will be found. 5768 // reaching load will be found.
5770 // Loads that are locally redundant will be replaced as we go through 5769 // Loads that are locally redundant will be replaced as we go through
5771 // instructions. 5770 // instructions.
5772 void ComputeInitialSets() { 5771 void ComputeInitialSets() {
5773 BitVector* forwarded_loads = new BitVector(aliased_set_->max_place_id());
5774
5775 for (BlockIterator block_it = graph_->reverse_postorder_iterator(); 5772 for (BlockIterator block_it = graph_->reverse_postorder_iterator();
5776 !block_it.Done(); 5773 !block_it.Done();
5777 block_it.Advance()) { 5774 block_it.Advance()) {
5778 BlockEntryInstr* block = block_it.Current(); 5775 BlockEntryInstr* block = block_it.Current();
5779 const intptr_t preorder_number = block->preorder_number(); 5776 const intptr_t preorder_number = block->preorder_number();
5780 5777
5781 BitVector* kill = kill_[preorder_number]; 5778 BitVector* kill = kill_[preorder_number];
5782 BitVector* gen = gen_[preorder_number]; 5779 BitVector* gen = gen_[preorder_number];
5783 5780
5784 ZoneGrowableArray<Definition*>* exposed_values = NULL; 5781 ZoneGrowableArray<Definition*>* exposed_values = NULL;
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
5923 5920
5924 exposed_values->Add(defn); 5921 exposed_values->Add(defn);
5925 } 5922 }
5926 5923
5927 gen->Add(place_id); 5924 gen->Add(place_id);
5928 5925
5929 if (out_values == NULL) out_values = CreateBlockOutValues(); 5926 if (out_values == NULL) out_values = CreateBlockOutValues();
5930 (*out_values)[place_id] = defn; 5927 (*out_values)[place_id] = defn;
5931 } 5928 }
5932 5929
5933 PhiPlaceMoves::MovesList phi_moves =
5934 aliased_set_->phi_moves()->GetOutgoingMoves(block);
5935 if (phi_moves != NULL) {
5936 PerformPhiMoves(phi_moves, gen, forwarded_loads);
5937 }
5938
5939 exposed_values_[preorder_number] = exposed_values; 5930 exposed_values_[preorder_number] = exposed_values;
5940 out_values_[preorder_number] = out_values; 5931 out_values_[preorder_number] = out_values;
5941 } 5932 }
5942 } 5933 }
5943 5934
5944 static void PerformPhiMoves(PhiPlaceMoves::MovesList phi_moves, 5935 static void PerformPhiMoves(PhiPlaceMoves::MovesList phi_moves,
5945 BitVector* out, 5936 BitVector* out,
5946 BitVector* forwarded_loads) { 5937 BitVector* forwarded_loads) {
5947 forwarded_loads->Clear(); 5938 forwarded_loads->Clear();
5948 5939
(...skipping 16 matching lines...) Expand all
5965 } 5956 }
5966 5957
5967 out->AddAll(forwarded_loads); 5958 out->AddAll(forwarded_loads);
5968 } 5959 }
5969 5960
5970 // Compute OUT sets by propagating them iteratively until fix point 5961 // Compute OUT sets by propagating them iteratively until fix point
5971 // is reached. 5962 // is reached.
5972 void ComputeOutSets() { 5963 void ComputeOutSets() {
5973 BitVector* temp = new BitVector(aliased_set_->max_place_id()); 5964 BitVector* temp = new BitVector(aliased_set_->max_place_id());
5974 BitVector* forwarded_loads = new BitVector(aliased_set_->max_place_id()); 5965 BitVector* forwarded_loads = new BitVector(aliased_set_->max_place_id());
5966 BitVector* temp_out = new BitVector(aliased_set_->max_place_id());
5975 5967
5976 bool changed = true; 5968 bool changed = true;
5977 while (changed) { 5969 while (changed) {
5978 changed = false; 5970 changed = false;
5979 5971
5980 for (BlockIterator block_it = graph_->reverse_postorder_iterator(); 5972 for (BlockIterator block_it = graph_->reverse_postorder_iterator();
5981 !block_it.Done(); 5973 !block_it.Done();
5982 block_it.Advance()) { 5974 block_it.Advance()) {
5983 BlockEntryInstr* block = block_it.Current(); 5975 BlockEntryInstr* block = block_it.Current();
5984 5976
5985 const intptr_t preorder_number = block->preorder_number(); 5977 const intptr_t preorder_number = block->preorder_number();
5986 5978
5987 BitVector* block_in = in_[preorder_number]; 5979 BitVector* block_in = in_[preorder_number];
5988 BitVector* block_out = out_[preorder_number]; 5980 BitVector* block_out = out_[preorder_number];
5989 BitVector* block_kill = kill_[preorder_number]; 5981 BitVector* block_kill = kill_[preorder_number];
5990 BitVector* block_gen = gen_[preorder_number]; 5982 BitVector* block_gen = gen_[preorder_number];
5991 5983
5992 // Compute block_in as the intersection of all out(p) where p 5984 // Compute block_in as the intersection of all out(p) where p
5993 // is a predecessor of the current block. 5985 // is a predecessor of the current block.
5994 if (block->IsGraphEntry()) { 5986 if (block->IsGraphEntry()) {
5995 temp->Clear(); 5987 temp->Clear();
5996 } else { 5988 } else {
5997 temp->SetAll(); 5989 temp->SetAll();
5998 ASSERT(block->PredecessorCount() > 0); 5990 ASSERT(block->PredecessorCount() > 0);
5999 for (intptr_t i = 0; i < block->PredecessorCount(); i++) { 5991 for (intptr_t i = 0; i < block->PredecessorCount(); i++) {
6000 BlockEntryInstr* pred = block->PredecessorAt(i); 5992 BlockEntryInstr* pred = block->PredecessorAt(i);
6001 BitVector* pred_out = out_[pred->preorder_number()]; 5993 BitVector* pred_out = out_[pred->preorder_number()];
6002 if (pred_out != NULL) { 5994 if (pred_out != NULL) {
Vyacheslav Egorov (Chromium) 2014/02/27 16:25:09 I would write it slightly differently: if (pred_o
Florian Schneider 2014/02/28 13:38:57 Done.
6003 temp->Intersect(pred_out); 5995 PhiPlaceMoves::MovesList phi_moves =
5996 aliased_set_->phi_moves()->GetOutgoingMoves(pred);
5997 if (phi_moves != NULL) {
5998 // If there are phi moves, perform intersection with
5999 // a copy of pred_out where the phi moves are applied.
6000 temp_out->CopyFrom(pred_out);
6001 PerformPhiMoves(phi_moves, temp_out, forwarded_loads);
6002 temp->Intersect(temp_out);
6003 } else {
6004 temp->Intersect(pred_out);
6005 }
6004 } 6006 }
6005 } 6007 }
6006 } 6008 }
6007 6009
6008 if (!temp->Equals(*block_in) || (block_out == NULL)) { 6010 if (!temp->Equals(*block_in) || (block_out == NULL)) {
6009 // If IN set has changed propagate the change to OUT set. 6011 // If IN set has changed propagate the change to OUT set.
6010 block_in->CopyFrom(temp); 6012 block_in->CopyFrom(temp);
6011 6013
6012 temp->RemoveAll(block_kill); 6014 temp->RemoveAll(block_kill);
6013 temp->AddAll(block_gen); 6015 temp->AddAll(block_gen);
6014 6016
6015 PhiPlaceMoves::MovesList phi_moves =
6016 aliased_set_->phi_moves()->GetOutgoingMoves(block);
6017 if (phi_moves != NULL) {
6018 PerformPhiMoves(phi_moves, temp, forwarded_loads);
6019 }
6020
6021 if ((block_out == NULL) || !block_out->Equals(*temp)) { 6017 if ((block_out == NULL) || !block_out->Equals(*temp)) {
6022 if (block_out == NULL) { 6018 if (block_out == NULL) {
6023 block_out = out_[preorder_number] = 6019 block_out = out_[preorder_number] =
6024 new BitVector(aliased_set_->max_place_id()); 6020 new BitVector(aliased_set_->max_place_id());
6025 } 6021 }
6026 block_out->CopyFrom(temp); 6022 block_out->CopyFrom(temp);
6027 changed = true; 6023 changed = true;
6028 } 6024 }
6029 } 6025 }
6030 } 6026 }
(...skipping 2585 matching lines...) Expand 10 before | Expand all | Expand 10 after
8616 } 8612 }
8617 8613
8618 // Insert materializations at environment uses. 8614 // Insert materializations at environment uses.
8619 for (intptr_t i = 0; i < exits.length(); i++) { 8615 for (intptr_t i = 0; i < exits.length(); i++) {
8620 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields); 8616 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields);
8621 } 8617 }
8622 } 8618 }
8623 8619
8624 8620
8625 } // namespace dart 8621 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | tests/language/vm/load_to_load_forwarding_vm_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698