Home | History | Annotate | Download | only in crankshaft
      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 #include "src/objects-inl.h"
      7 
      8 namespace v8 {
      9 namespace internal {
     10 
     11 void HRedundantPhiEliminationPhase::Run() {
     12   // Gather all phis from all blocks first.
     13   const ZoneList<HBasicBlock*>* blocks(graph()->blocks());
     14   ZoneList<HPhi*> all_phis(blocks->length(), zone());
     15   for (int i = 0; i < blocks->length(); ++i) {
     16     HBasicBlock* block = blocks->at(i);
     17     for (int j = 0; j < block->phis()->length(); j++) {
     18       all_phis.Add(block->phis()->at(j), zone());
     19     }
     20   }
     21 
     22   // Iteratively reduce all phis in the list.
     23   ProcessPhis(&all_phis);
     24 
     25 #if DEBUG
     26   // Make sure that we *really* removed all redundant phis.
     27   for (int i = 0; i < blocks->length(); ++i) {
     28     for (int j = 0; j < blocks->at(i)->phis()->length(); j++) {
     29       DCHECK(blocks->at(i)->phis()->at(j)->GetRedundantReplacement() == NULL);
     30     }
     31   }
     32 #endif
     33 }
     34 
     35 
     36 void HRedundantPhiEliminationPhase::ProcessBlock(HBasicBlock* block) {
     37   ProcessPhis(block->phis());
     38 }
     39 
     40 
     41 void HRedundantPhiEliminationPhase::ProcessPhis(const ZoneList<HPhi*>* phis) {
     42   bool updated;
     43   do {
     44     // Iterately replace all redundant phis in the given list.
     45     updated = false;
     46     for (int i = 0; i < phis->length(); i++) {
     47       HPhi* phi = phis->at(i);
     48       if (phi->CheckFlag(HValue::kIsDead)) continue;  // Already replaced.
     49 
     50       HValue* replacement = phi->GetRedundantReplacement();
     51       if (replacement != NULL) {
     52         phi->SetFlag(HValue::kIsDead);
     53         for (HUseIterator it(phi->uses()); !it.Done(); it.Advance()) {
     54           HValue* value = it.value();
     55           value->SetOperandAt(it.index(), replacement);
     56           // Iterate again if used in another non-dead phi.
     57           updated |= value->IsPhi() && !value->CheckFlag(HValue::kIsDead);
     58         }
     59         phi->block()->RemovePhi(phi);
     60       }
     61     }
     62   } while (updated);
     63 }
     64 
     65 
     66 }  // namespace internal
     67 }  // namespace v8
     68