1 // Copyright 2013 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "src/crankshaft/hydrogen-redundant-phi.h" 6 7 namespace v8 { 8 namespace internal { 9 10 void HRedundantPhiEliminationPhase::Run() { 11 // Gather all phis from all blocks first. 12 const ZoneList<HBasicBlock*>* blocks(graph()->blocks()); 13 ZoneList<HPhi*> all_phis(blocks->length(), zone()); 14 for (int i = 0; i < blocks->length(); ++i) { 15 HBasicBlock* block = blocks->at(i); 16 for (int j = 0; j < block->phis()->length(); j++) { 17 all_phis.Add(block->phis()->at(j), zone()); 18 } 19 } 20 21 // Iteratively reduce all phis in the list. 22 ProcessPhis(&all_phis); 23 24 #if DEBUG 25 // Make sure that we *really* removed all redundant phis. 26 for (int i = 0; i < blocks->length(); ++i) { 27 for (int j = 0; j < blocks->at(i)->phis()->length(); j++) { 28 DCHECK(blocks->at(i)->phis()->at(j)->GetRedundantReplacement() == NULL); 29 } 30 } 31 #endif 32 } 33 34 35 void HRedundantPhiEliminationPhase::ProcessBlock(HBasicBlock* block) { 36 ProcessPhis(block->phis()); 37 } 38 39 40 void HRedundantPhiEliminationPhase::ProcessPhis(const ZoneList<HPhi*>* phis) { 41 bool updated; 42 do { 43 // Iterately replace all redundant phis in the given list. 44 updated = false; 45 for (int i = 0; i < phis->length(); i++) { 46 HPhi* phi = phis->at(i); 47 if (phi->CheckFlag(HValue::kIsDead)) continue; // Already replaced. 48 49 HValue* replacement = phi->GetRedundantReplacement(); 50 if (replacement != NULL) { 51 phi->SetFlag(HValue::kIsDead); 52 for (HUseIterator it(phi->uses()); !it.Done(); it.Advance()) { 53 HValue* value = it.value(); 54 value->SetOperandAt(it.index(), replacement); 55 // Iterate again if used in another non-dead phi. 56 updated |= value->IsPhi() && !value->CheckFlag(HValue::kIsDead); 57 } 58 phi->block()->RemovePhi(phi); 59 } 60 } 61 } while (updated); 62 } 63 64 65 } // namespace internal 66 } // namespace v8 67