| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "hydrogen-flow-engine.h" | 5 #include "hydrogen-flow-engine.h" |
| 6 #include "hydrogen-instructions.h" | 6 #include "hydrogen-instructions.h" |
| 7 #include "hydrogen-removable-simulates.h" | 7 #include "hydrogen-removable-simulates.h" |
| 8 | 8 |
| 9 namespace v8 { | 9 namespace v8 { |
| 10 namespace internal { | 10 namespace internal { |
| 11 | 11 |
| 12 class State : public ZoneObject { | 12 class State : public ZoneObject { |
| 13 public: | 13 public: |
| 14 explicit State(Zone* zone) | 14 explicit State(Zone* zone) |
| 15 : zone_(zone), mergelist_(2, zone), first_(true), mode_(NORMAL) { } | 15 : zone_(zone), mergelist_(2, zone), first_(true), mode_(NORMAL) { } |
| 16 | 16 |
| 17 State* Process(HInstruction* instr, Zone* zone) { | 17 State* Process(HInstruction* instr, Zone* zone) { |
| 18 if (FLAG_trace_removable_simulates) { | 18 if (FLAG_trace_removable_simulates) { |
| 19 PrintF("[State::Process %s #%d %s]\n", | 19 PrintF("[%s with state %p in B%d: #%d %s]\n", |
| 20 mode_ == NORMAL ? "normal" : "collect", | 20 mode_ == NORMAL ? "processing" : "collecting", |
| 21 reinterpret_cast<void*>(this), instr->block()->block_id(), |
| 21 instr->id(), instr->Mnemonic()); | 22 instr->id(), instr->Mnemonic()); |
| 22 } | 23 } |
| 23 // Forward-merge "trains" of simulates after an instruction with observable | 24 // Forward-merge "trains" of simulates after an instruction with observable |
| 24 // side effects to keep live ranges short. | 25 // side effects to keep live ranges short. |
| 25 if (mode_ == COLLECT_CONSECUTIVE_SIMULATES) { | 26 if (mode_ == COLLECT_CONSECUTIVE_SIMULATES) { |
| 26 if (instr->IsSimulate()) { | 27 if (instr->IsSimulate()) { |
| 27 HSimulate* current_simulate = HSimulate::cast(instr); | 28 HSimulate* current_simulate = HSimulate::cast(instr); |
| 28 if (current_simulate->is_candidate_for_removal() && | 29 if (current_simulate->is_candidate_for_removal() && |
| 29 !current_simulate->ast_id().IsNone()) { | 30 !current_simulate->ast_id().IsNone()) { |
| 30 Remember(current_simulate); | 31 Remember(current_simulate); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 73 } | 74 } |
| 74 | 75 |
| 75 return this; | 76 return this; |
| 76 } | 77 } |
| 77 | 78 |
| 78 static State* Merge(State* succ_state, | 79 static State* Merge(State* succ_state, |
| 79 HBasicBlock* succ_block, | 80 HBasicBlock* succ_block, |
| 80 State* pred_state, | 81 State* pred_state, |
| 81 HBasicBlock* pred_block, | 82 HBasicBlock* pred_block, |
| 82 Zone* zone) { | 83 Zone* zone) { |
| 83 if (FLAG_trace_removable_simulates) { | 84 return (succ_state == NULL) |
| 84 PrintF("[State::Merge predecessor block %d, successor block %d\n", | 85 ? pred_state->Copy(succ_block, pred_block, zone) |
| 85 pred_block->block_id(), succ_block->block_id()); | 86 : succ_state->Merge(succ_block, pred_state, pred_block, zone); |
| 86 } | |
| 87 return pred_state; | |
| 88 } | 87 } |
| 89 | 88 |
| 90 static State* Finish(State* state, HBasicBlock* block, Zone* zone) { | 89 static State* Finish(State* state, HBasicBlock* block, Zone* zone) { |
| 91 if (FLAG_trace_removable_simulates) { | 90 if (FLAG_trace_removable_simulates) { |
| 92 PrintF("[State::Finish block %d]\n", block->block_id()); } | 91 PrintF("[preparing state %p for B%d]\n", reinterpret_cast<void*>(state), |
| 93 // Make sure the merge list is empty at the start of a block. | 92 block->block_id()); |
| 94 ASSERT(state->mergelist_.is_empty()); | 93 } |
| 94 // For our current local analysis, we should not remember simulates across |
| 95 // block boundaries. |
| 96 ASSERT(!state->HasRememberedSimulates()); |
| 95 // Nasty heuristic: Never remove the first simulate in a block. This | 97 // Nasty heuristic: Never remove the first simulate in a block. This |
| 96 // just so happens to have a beneficial effect on register allocation. | 98 // just so happens to have a beneficial effect on register allocation. |
| 97 state->first_ = true; | 99 state->first_ = true; |
| 98 return state; | 100 return state; |
| 99 } | 101 } |
| 100 | 102 |
| 101 private: | 103 private: |
| 104 explicit State(const State& other) |
| 105 : zone_(other.zone_), |
| 106 mergelist_(other.mergelist_, other.zone_), |
| 107 first_(other.first_), |
| 108 mode_(other.mode_) { } |
| 109 |
| 102 enum Mode { NORMAL, COLLECT_CONSECUTIVE_SIMULATES }; | 110 enum Mode { NORMAL, COLLECT_CONSECUTIVE_SIMULATES }; |
| 103 | 111 |
| 112 bool HasRememberedSimulates() const { return !mergelist_.is_empty(); } |
| 113 |
| 104 void Remember(HSimulate* sim) { | 114 void Remember(HSimulate* sim) { |
| 105 mergelist_.Add(sim, zone_); | 115 mergelist_.Add(sim, zone_); |
| 106 } | 116 } |
| 107 | 117 |
| 108 void FlushSimulates() { | 118 void FlushSimulates() { |
| 109 if (!mergelist_.is_empty()) { | 119 if (HasRememberedSimulates()) { |
| 110 mergelist_.RemoveLast()->MergeWith(&mergelist_); | 120 mergelist_.RemoveLast()->MergeWith(&mergelist_); |
| 111 } | 121 } |
| 112 } | 122 } |
| 113 | 123 |
| 114 void RemoveSimulates() { | 124 void RemoveSimulates() { |
| 115 while (!mergelist_.is_empty()) { | 125 while (HasRememberedSimulates()) { |
| 116 mergelist_.RemoveLast()->DeleteAndReplaceWith(NULL); | 126 mergelist_.RemoveLast()->DeleteAndReplaceWith(NULL); |
| 117 } | 127 } |
| 118 } | 128 } |
| 119 | 129 |
| 130 State* Copy(HBasicBlock* succ_block, HBasicBlock* pred_block, Zone* zone) { |
| 131 State* copy = new(zone) State(*this); |
| 132 if (FLAG_trace_removable_simulates) { |
| 133 PrintF("[copy state %p from B%d to new state %p for B%d]\n", |
| 134 reinterpret_cast<void*>(this), pred_block->block_id(), |
| 135 reinterpret_cast<void*>(copy), succ_block->block_id()); |
| 136 } |
| 137 return copy; |
| 138 } |
| 139 |
| 140 State* Merge(HBasicBlock* succ_block, |
| 141 State* pred_state, |
| 142 HBasicBlock* pred_block, |
| 143 Zone* zone) { |
| 144 // For our current local analysis, we should not remember simulates across |
| 145 // block boundaries. |
| 146 ASSERT(!pred_state->HasRememberedSimulates()); |
| 147 ASSERT(!HasRememberedSimulates()); |
| 148 if (FLAG_trace_removable_simulates) { |
| 149 PrintF("[merge state %p from B%d into %p for B%d]\n", |
| 150 reinterpret_cast<void*>(pred_state), pred_block->block_id(), |
| 151 reinterpret_cast<void*>(this), succ_block->block_id()); |
| 152 } |
| 153 return this; |
| 154 } |
| 155 |
| 120 Zone* zone_; | 156 Zone* zone_; |
| 121 ZoneList<HSimulate*> mergelist_; | 157 ZoneList<HSimulate*> mergelist_; |
| 122 bool first_; | 158 bool first_; |
| 123 Mode mode_; | 159 Mode mode_; |
| 124 }; | 160 }; |
| 125 | 161 |
| 126 | 162 |
| 127 // We don't use effects here. | 163 // We don't use effects here. |
| 128 class Effects : public ZoneObject { | 164 class Effects : public ZoneObject { |
| 129 public: | 165 public: |
| 130 explicit Effects(Zone* zone) { } | 166 explicit Effects(Zone* zone) { } |
| 131 bool Disabled() { return true; } | 167 bool Disabled() { return true; } |
| 132 void Process(HInstruction* instr, Zone* zone) { } | 168 void Process(HInstruction* instr, Zone* zone) { } |
| 133 void Apply(State* state) { } | 169 void Apply(State* state) { } |
| 134 void Union(Effects* that, Zone* zone) { } | 170 void Union(Effects* that, Zone* zone) { } |
| 135 }; | 171 }; |
| 136 | 172 |
| 137 | 173 |
| 138 void HMergeRemovableSimulatesPhase::Run() { | 174 void HMergeRemovableSimulatesPhase::Run() { |
| 139 HFlowEngine<State, Effects> engine(graph(), zone()); | 175 HFlowEngine<State, Effects> engine(graph(), zone()); |
| 140 State* state = new(zone()) State(zone()); | 176 State* state = new(zone()) State(zone()); |
| 141 engine.AnalyzeDominatedBlocks(graph()->blocks()->at(0), state); | 177 engine.AnalyzeDominatedBlocks(graph()->blocks()->at(0), state); |
| 142 } | 178 } |
| 143 | 179 |
| 144 } } // namespace v8::internal | 180 } } // namespace v8::internal |
| OLD | NEW |