| 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 "src/hydrogen-flow-engine.h" | 5 #include "src/hydrogen-flow-engine.h" |
| 6 #include "src/hydrogen-instructions.h" | 6 #include "src/hydrogen-instructions.h" |
| 7 #include "src/hydrogen-removable-simulates.h" | 7 #include "src/hydrogen-removable-simulates.h" |
| 8 | 8 |
| 9 namespace v8 { | 9 namespace v8 { |
| 10 namespace internal { | 10 namespace internal { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 30 !current_simulate->ast_id().IsNone()) { | 30 !current_simulate->ast_id().IsNone()) { |
| 31 Remember(current_simulate); | 31 Remember(current_simulate); |
| 32 return this; | 32 return this; |
| 33 } | 33 } |
| 34 } | 34 } |
| 35 FlushSimulates(); | 35 FlushSimulates(); |
| 36 mode_ = NORMAL; | 36 mode_ = NORMAL; |
| 37 } | 37 } |
| 38 // Ensure there's a non-foldable HSimulate before an HEnterInlined to avoid | 38 // Ensure there's a non-foldable HSimulate before an HEnterInlined to avoid |
| 39 // folding across HEnterInlined. | 39 // folding across HEnterInlined. |
| 40 ASSERT(!(instr->IsEnterInlined() && | 40 DCHECK(!(instr->IsEnterInlined() && |
| 41 HSimulate::cast(instr->previous())->is_candidate_for_removal())); | 41 HSimulate::cast(instr->previous())->is_candidate_for_removal())); |
| 42 if (instr->IsLeaveInlined() || instr->IsReturn()) { | 42 if (instr->IsLeaveInlined() || instr->IsReturn()) { |
| 43 // Never fold simulates from inlined environments into simulates in the | 43 // Never fold simulates from inlined environments into simulates in the |
| 44 // outer environment. Simply remove all accumulated simulates without | 44 // outer environment. Simply remove all accumulated simulates without |
| 45 // merging. This is safe because simulates after instructions with side | 45 // merging. This is safe because simulates after instructions with side |
| 46 // effects are never added to the merge list. The same reasoning holds for | 46 // effects are never added to the merge list. The same reasoning holds for |
| 47 // return instructions. | 47 // return instructions. |
| 48 RemoveSimulates(); | 48 RemoveSimulates(); |
| 49 return this; | 49 return this; |
| 50 } | 50 } |
| 51 if (instr->IsControlInstruction()) { | 51 if (instr->IsControlInstruction()) { |
| 52 // Merge the accumulated simulates at the end of the block. | 52 // Merge the accumulated simulates at the end of the block. |
| 53 FlushSimulates(); | 53 FlushSimulates(); |
| 54 return this; | 54 return this; |
| 55 } | 55 } |
| 56 // Skip the non-simulates and the first simulate. | 56 // Skip the non-simulates and the first simulate. |
| 57 if (!instr->IsSimulate()) return this; | 57 if (!instr->IsSimulate()) return this; |
| 58 if (first_) { | 58 if (first_) { |
| 59 first_ = false; | 59 first_ = false; |
| 60 return this; | 60 return this; |
| 61 } | 61 } |
| 62 HSimulate* current_simulate = HSimulate::cast(instr); | 62 HSimulate* current_simulate = HSimulate::cast(instr); |
| 63 if (!current_simulate->is_candidate_for_removal()) { | 63 if (!current_simulate->is_candidate_for_removal()) { |
| 64 Remember(current_simulate); | 64 Remember(current_simulate); |
| 65 FlushSimulates(); | 65 FlushSimulates(); |
| 66 } else if (current_simulate->ast_id().IsNone()) { | 66 } else if (current_simulate->ast_id().IsNone()) { |
| 67 ASSERT(current_simulate->next()->IsEnterInlined()); | 67 DCHECK(current_simulate->next()->IsEnterInlined()); |
| 68 FlushSimulates(); | 68 FlushSimulates(); |
| 69 } else if (current_simulate->previous()->HasObservableSideEffects()) { | 69 } else if (current_simulate->previous()->HasObservableSideEffects()) { |
| 70 Remember(current_simulate); | 70 Remember(current_simulate); |
| 71 mode_ = COLLECT_CONSECUTIVE_SIMULATES; | 71 mode_ = COLLECT_CONSECUTIVE_SIMULATES; |
| 72 } else { | 72 } else { |
| 73 Remember(current_simulate); | 73 Remember(current_simulate); |
| 74 } | 74 } |
| 75 | 75 |
| 76 return this; | 76 return this; |
| 77 } | 77 } |
| 78 | 78 |
| 79 static State* Merge(State* succ_state, | 79 static State* Merge(State* succ_state, |
| 80 HBasicBlock* succ_block, | 80 HBasicBlock* succ_block, |
| 81 State* pred_state, | 81 State* pred_state, |
| 82 HBasicBlock* pred_block, | 82 HBasicBlock* pred_block, |
| 83 Zone* zone) { | 83 Zone* zone) { |
| 84 return (succ_state == NULL) | 84 return (succ_state == NULL) |
| 85 ? pred_state->Copy(succ_block, pred_block, zone) | 85 ? pred_state->Copy(succ_block, pred_block, zone) |
| 86 : succ_state->Merge(succ_block, pred_state, pred_block, zone); | 86 : succ_state->Merge(succ_block, pred_state, pred_block, zone); |
| 87 } | 87 } |
| 88 | 88 |
| 89 static State* Finish(State* state, HBasicBlock* block, Zone* zone) { | 89 static State* Finish(State* state, HBasicBlock* block, Zone* zone) { |
| 90 if (FLAG_trace_removable_simulates) { | 90 if (FLAG_trace_removable_simulates) { |
| 91 PrintF("[preparing state %p for B%d]\n", reinterpret_cast<void*>(state), | 91 PrintF("[preparing state %p for B%d]\n", reinterpret_cast<void*>(state), |
| 92 block->block_id()); | 92 block->block_id()); |
| 93 } | 93 } |
| 94 // For our current local analysis, we should not remember simulates across | 94 // For our current local analysis, we should not remember simulates across |
| 95 // block boundaries. | 95 // block boundaries. |
| 96 ASSERT(!state->HasRememberedSimulates()); | 96 DCHECK(!state->HasRememberedSimulates()); |
| 97 // Nasty heuristic: Never remove the first simulate in a block. This | 97 // Nasty heuristic: Never remove the first simulate in a block. This |
| 98 // just so happens to have a beneficial effect on register allocation. | 98 // just so happens to have a beneficial effect on register allocation. |
| 99 state->first_ = true; | 99 state->first_ = true; |
| 100 return state; | 100 return state; |
| 101 } | 101 } |
| 102 | 102 |
| 103 private: | 103 private: |
| 104 explicit State(const State& other) | 104 explicit State(const State& other) |
| 105 : zone_(other.zone_), | 105 : zone_(other.zone_), |
| 106 mergelist_(other.mergelist_, other.zone_), | 106 mergelist_(other.mergelist_, other.zone_), |
| (...skipping 29 matching lines...) Expand all Loading... |
| 136 } | 136 } |
| 137 return copy; | 137 return copy; |
| 138 } | 138 } |
| 139 | 139 |
| 140 State* Merge(HBasicBlock* succ_block, | 140 State* Merge(HBasicBlock* succ_block, |
| 141 State* pred_state, | 141 State* pred_state, |
| 142 HBasicBlock* pred_block, | 142 HBasicBlock* pred_block, |
| 143 Zone* zone) { | 143 Zone* zone) { |
| 144 // For our current local analysis, we should not remember simulates across | 144 // For our current local analysis, we should not remember simulates across |
| 145 // block boundaries. | 145 // block boundaries. |
| 146 ASSERT(!pred_state->HasRememberedSimulates()); | 146 DCHECK(!pred_state->HasRememberedSimulates()); |
| 147 ASSERT(!HasRememberedSimulates()); | 147 DCHECK(!HasRememberedSimulates()); |
| 148 if (FLAG_trace_removable_simulates) { | 148 if (FLAG_trace_removable_simulates) { |
| 149 PrintF("[merge state %p from B%d into %p for B%d]\n", | 149 PrintF("[merge state %p from B%d into %p for B%d]\n", |
| 150 reinterpret_cast<void*>(pred_state), pred_block->block_id(), | 150 reinterpret_cast<void*>(pred_state), pred_block->block_id(), |
| 151 reinterpret_cast<void*>(this), succ_block->block_id()); | 151 reinterpret_cast<void*>(this), succ_block->block_id()); |
| 152 } | 152 } |
| 153 return this; | 153 return this; |
| 154 } | 154 } |
| 155 | 155 |
| 156 Zone* zone_; | 156 Zone* zone_; |
| 157 ZoneList<HSimulate*> mergelist_; | 157 ZoneList<HSimulate*> mergelist_; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 171 }; | 171 }; |
| 172 | 172 |
| 173 | 173 |
| 174 void HMergeRemovableSimulatesPhase::Run() { | 174 void HMergeRemovableSimulatesPhase::Run() { |
| 175 HFlowEngine<State, Effects> engine(graph(), zone()); | 175 HFlowEngine<State, Effects> engine(graph(), zone()); |
| 176 State* state = new(zone()) State(zone()); | 176 State* state = new(zone()) State(zone()); |
| 177 engine.AnalyzeDominatedBlocks(graph()->blocks()->at(0), state); | 177 engine.AnalyzeDominatedBlocks(graph()->blocks()->at(0), state); |
| 178 } | 178 } |
| 179 | 179 |
| 180 } } // namespace v8::internal | 180 } } // namespace v8::internal |
| OLD | NEW |