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 |