OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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/compiler/move-optimizer.h" | 5 #include "src/compiler/move-optimizer.h" |
6 | 6 |
7 namespace v8 { | 7 namespace v8 { |
8 namespace internal { | 8 namespace internal { |
9 namespace compiler { | 9 namespace compiler { |
10 | 10 |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
111 } | 111 } |
112 OptimizeMerge(block); | 112 OptimizeMerge(block); |
113 } | 113 } |
114 for (Instruction* gap : to_finalize_) { | 114 for (Instruction* gap : to_finalize_) { |
115 FinalizeMoves(gap); | 115 FinalizeMoves(gap); |
116 } | 116 } |
117 } | 117 } |
118 | 118 |
119 | 119 |
120 void MoveOptimizer::CompressMoves(ParallelMove* left, ParallelMove* right) { | 120 void MoveOptimizer::CompressMoves(ParallelMove* left, ParallelMove* right) { |
| 121 if (right == nullptr) return; |
| 122 |
121 MoveOpVector& eliminated = local_vector(); | 123 MoveOpVector& eliminated = local_vector(); |
122 DCHECK(eliminated.empty()); | 124 DCHECK(eliminated.empty()); |
123 | 125 |
124 if (!left->empty()) { | 126 if (!left->empty()) { |
125 // Modify the right moves in place and collect moves that will be killed by | 127 // Modify the right moves in place and collect moves that will be killed by |
126 // merging the two gaps. | 128 // merging the two gaps. |
127 for (MoveOperands* move : *right) { | 129 for (MoveOperands* move : *right) { |
128 if (move->IsRedundant()) continue; | 130 if (move->IsRedundant()) continue; |
129 MoveOperands* to_eliminate = left->PrepareInsertAfter(move); | 131 MoveOperands* to_eliminate = left->PrepareInsertAfter(move); |
130 if (to_eliminate != nullptr) eliminated.push_back(to_eliminate); | 132 if (to_eliminate != nullptr) eliminated.push_back(to_eliminate); |
(...skipping 15 matching lines...) Expand all Loading... |
146 } | 148 } |
147 | 149 |
148 | 150 |
149 // Smash all consecutive moves into the left most move slot and accumulate them | 151 // Smash all consecutive moves into the left most move slot and accumulate them |
150 // as much as possible across instructions. | 152 // as much as possible across instructions. |
151 void MoveOptimizer::CompressBlock(InstructionBlock* block) { | 153 void MoveOptimizer::CompressBlock(InstructionBlock* block) { |
152 Instruction* prev_instr = nullptr; | 154 Instruction* prev_instr = nullptr; |
153 for (int index = block->code_start(); index < block->code_end(); ++index) { | 155 for (int index = block->code_start(); index < block->code_end(); ++index) { |
154 Instruction* instr = code()->instructions()[index]; | 156 Instruction* instr = code()->instructions()[index]; |
155 int i = FindFirstNonEmptySlot(instr); | 157 int i = FindFirstNonEmptySlot(instr); |
156 if (i <= Instruction::LAST_GAP_POSITION) { | 158 bool has_moves = i <= Instruction::LAST_GAP_POSITION; |
157 // Move the first non-empty gap to position 0. | 159 |
158 std::swap(instr->parallel_moves()[0], instr->parallel_moves()[i]); | 160 if (i == Instruction::LAST_GAP_POSITION) { |
159 ParallelMove* left = instr->parallel_moves()[0]; | 161 std::swap(instr->parallel_moves()[Instruction::FIRST_GAP_POSITION], |
160 // Compress everything into position 0. | 162 instr->parallel_moves()[Instruction::LAST_GAP_POSITION]); |
161 for (++i; i <= Instruction::LAST_GAP_POSITION; ++i) { | 163 } else if (i == Instruction::FIRST_GAP_POSITION) { |
162 ParallelMove* move = instr->parallel_moves()[i]; | 164 CompressMoves(instr->parallel_moves()[Instruction::FIRST_GAP_POSITION], |
163 if (move == nullptr) continue; | 165 instr->parallel_moves()[Instruction::LAST_GAP_POSITION]); |
164 CompressMoves(left, move); | 166 } |
| 167 // We either have no moves, or, after swapping or compressing, we have |
| 168 // all the moves in the first gap position, and none in the second/end gap |
| 169 // position. |
| 170 ParallelMove* first = |
| 171 instr->parallel_moves()[Instruction::FIRST_GAP_POSITION]; |
| 172 ParallelMove* last = |
| 173 instr->parallel_moves()[Instruction::LAST_GAP_POSITION]; |
| 174 USE(last); |
| 175 |
| 176 DCHECK(!has_moves || |
| 177 (first != nullptr && (last == nullptr || last->empty()))); |
| 178 |
| 179 if (prev_instr != nullptr) { |
| 180 if (has_moves) { |
| 181 // Smash first into prev_instr, killing left. |
| 182 ParallelMove* pred_moves = prev_instr->parallel_moves()[0]; |
| 183 CompressMoves(pred_moves, first); |
165 } | 184 } |
166 if (prev_instr != nullptr) { | |
167 // Smash left into prev_instr, killing left. | |
168 ParallelMove* pred_moves = prev_instr->parallel_moves()[0]; | |
169 CompressMoves(pred_moves, left); | |
170 } | |
171 } | |
172 if (prev_instr != nullptr) { | |
173 // Slide prev_instr down so we always know where to look for it. | 185 // Slide prev_instr down so we always know where to look for it. |
174 std::swap(prev_instr->parallel_moves()[0], instr->parallel_moves()[0]); | 186 std::swap(prev_instr->parallel_moves()[0], instr->parallel_moves()[0]); |
175 } | 187 } |
| 188 |
176 prev_instr = instr->parallel_moves()[0] == nullptr ? nullptr : instr; | 189 prev_instr = instr->parallel_moves()[0] == nullptr ? nullptr : instr; |
177 if (GapsCanMoveOver(instr, local_zone())) continue; | 190 if (GapsCanMoveOver(instr, local_zone())) continue; |
178 if (prev_instr != nullptr) { | 191 if (prev_instr != nullptr) { |
179 to_finalize_.push_back(prev_instr); | 192 to_finalize_.push_back(prev_instr); |
180 prev_instr = nullptr; | 193 prev_instr = nullptr; |
181 } | 194 } |
182 } | 195 } |
183 if (prev_instr != nullptr) { | 196 if (prev_instr != nullptr) { |
184 to_finalize_.push_back(prev_instr); | 197 to_finalize_.push_back(prev_instr); |
185 } | 198 } |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
329 static_cast<Instruction::GapPosition>(1), code_zone()); | 342 static_cast<Instruction::GapPosition>(1), code_zone()); |
330 slot_1->AddMove(group_begin->destination(), load->destination()); | 343 slot_1->AddMove(group_begin->destination(), load->destination()); |
331 load->Eliminate(); | 344 load->Eliminate(); |
332 } | 345 } |
333 loads.clear(); | 346 loads.clear(); |
334 } | 347 } |
335 | 348 |
336 } // namespace compiler | 349 } // namespace compiler |
337 } // namespace internal | 350 } // namespace internal |
338 } // namespace v8 | 351 } // namespace v8 |
OLD | NEW |