Revision f230a1cf deps/v8/src/hydrogen-redundant-phi.cc

View differences:

deps/v8/src/hydrogen-redundant-phi.cc
31 31
namespace internal {
32 32

  
33 33
void HRedundantPhiEliminationPhase::Run() {
34
  // We do a simple fixed point iteration without any work list, because
35
  // machine-generated JavaScript can lead to a very dense Hydrogen graph with
36
  // an enormous work list and will consequently result in OOM. Experiments
37
  // showed that this simple algorithm is good enough, and even e.g. tracking
38
  // the set or range of blocks to consider is not a real improvement.
39
  bool need_another_iteration;
34
  // Gather all phis from all blocks first.
40 35
  const ZoneList<HBasicBlock*>* blocks(graph()->blocks());
41
  ZoneList<HPhi*> redundant_phis(blocks->length(), zone());
42
  do {
43
    need_another_iteration = false;
44
    for (int i = 0; i < blocks->length(); ++i) {
45
      HBasicBlock* block = blocks->at(i);
46
      for (int j = 0; j < block->phis()->length(); j++) {
47
        HPhi* phi = block->phis()->at(j);
48
        HValue* replacement = phi->GetRedundantReplacement();
49
        if (replacement != NULL) {
50
          // Remember phi to avoid concurrent modification of the block's phis.
51
          redundant_phis.Add(phi, zone());
52
          for (HUseIterator it(phi->uses()); !it.Done(); it.Advance()) {
53
            HValue* value = it.value();
54
            value->SetOperandAt(it.index(), replacement);
55
            need_another_iteration |= value->IsPhi();
56
          }
57
        }
58
      }
59
      for (int i = 0; i < redundant_phis.length(); i++) {
60
        block->RemovePhi(redundant_phis[i]);
61
      }
62
      redundant_phis.Clear();
36
  ZoneList<HPhi*> all_phis(blocks->length(), zone());
37
  for (int i = 0; i < blocks->length(); ++i) {
38
    HBasicBlock* block = blocks->at(i);
39
    for (int j = 0; j < block->phis()->length(); j++) {
40
      all_phis.Add(block->phis()->at(j), zone());
63 41
    }
64
  } while (need_another_iteration);
42
  }
43

  
44
  // Iteratively reduce all phis in the list.
45
  ProcessPhis(&all_phis);
65 46

  
66 47
#if DEBUG
67 48
  // Make sure that we *really* removed all redundant phis.
......
73 54
#endif
74 55
}
75 56

  
57

  
58
void HRedundantPhiEliminationPhase::ProcessBlock(HBasicBlock* block) {
59
  ProcessPhis(block->phis());
60
}
61

  
62

  
63
void HRedundantPhiEliminationPhase::ProcessPhis(const ZoneList<HPhi*>* phis) {
64
  bool updated;
65
  do {
66
    // Iterately replace all redundant phis in the given list.
67
    updated = false;
68
    for (int i = 0; i < phis->length(); i++) {
69
      HPhi* phi = phis->at(i);
70
      if (phi->CheckFlag(HValue::kIsDead)) continue;  // Already replaced.
71

  
72
      HValue* replacement = phi->GetRedundantReplacement();
73
      if (replacement != NULL) {
74
        phi->SetFlag(HValue::kIsDead);
75
        for (HUseIterator it(phi->uses()); !it.Done(); it.Advance()) {
76
          HValue* value = it.value();
77
          value->SetOperandAt(it.index(), replacement);
78
          // Iterate again if used in another non-dead phi.
79
          updated |= value->IsPhi() && !value->CheckFlag(HValue::kIsDead);
80
        }
81
        phi->block()->RemovePhi(phi);
82
      }
83
    }
84
  } while (updated);
85
}
86

  
87

  
76 88
} }  // namespace v8::internal

Also available in: Unified diff