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 |
11 namespace { | 11 namespace { |
12 | 12 |
13 typedef std::pair<InstructionOperand, InstructionOperand> MoveKey; | 13 struct MoveKey { |
| 14 InstructionOperand source; |
| 15 InstructionOperand destination; |
| 16 }; |
14 | 17 |
15 struct MoveKeyCompare { | 18 struct MoveKeyCompare { |
16 bool operator()(const MoveKey& a, const MoveKey& b) const { | 19 bool operator()(const MoveKey& a, const MoveKey& b) const { |
17 if (a.first.EqualsCanonicalized(b.first)) { | 20 if (a.source.EqualsCanonicalized(b.source)) { |
18 return a.second.CompareCanonicalized(b.second); | 21 return a.destination.CompareCanonicalized(b.destination); |
19 } | 22 } |
20 return a.first.CompareCanonicalized(b.first); | 23 return a.source.CompareCanonicalized(b.source); |
21 } | 24 } |
22 }; | 25 }; |
23 | 26 |
24 struct OperandCompare { | 27 struct OperandCompare { |
25 bool operator()(const InstructionOperand& a, | 28 bool operator()(const InstructionOperand& a, |
26 const InstructionOperand& b) const { | 29 const InstructionOperand& b) const { |
27 return a.CompareCanonicalized(b); | 30 return a.CompareCanonicalized(b); |
28 } | 31 } |
29 }; | 32 }; |
30 | 33 |
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
266 DCHECK_NOT_NULL(instr); | 269 DCHECK_NOT_NULL(instr); |
267 | 270 |
268 if (correct_counts != move_map.size()) { | 271 if (correct_counts != move_map.size()) { |
269 // Moves that are unique to each predecessor won't be pushed to the common | 272 // Moves that are unique to each predecessor won't be pushed to the common |
270 // successor. | 273 // successor. |
271 OperandSet conflicting_srcs(local_zone()); | 274 OperandSet conflicting_srcs(local_zone()); |
272 for (auto iter = move_map.begin(), end = move_map.end(); iter != end;) { | 275 for (auto iter = move_map.begin(), end = move_map.end(); iter != end;) { |
273 auto current = iter; | 276 auto current = iter; |
274 ++iter; | 277 ++iter; |
275 if (current->second != block->PredecessorCount()) { | 278 if (current->second != block->PredecessorCount()) { |
276 InstructionOperand dest = current->first.second; | 279 InstructionOperand dest = current->first.destination; |
277 // Not all the moves in all the gaps are the same. Maybe some are. If | 280 // Not all the moves in all the gaps are the same. Maybe some are. If |
278 // there are such moves, we could move them, but the destination of the | 281 // there are such moves, we could move them, but the destination of the |
279 // moves staying behind can't appear as a source of a common move, | 282 // moves staying behind can't appear as a source of a common move, |
280 // because the move staying behind will clobber this destination. | 283 // because the move staying behind will clobber this destination. |
281 conflicting_srcs.insert(dest); | 284 conflicting_srcs.insert(dest); |
282 move_map.erase(current); | 285 move_map.erase(current); |
283 } | 286 } |
284 } | 287 } |
285 | 288 |
286 bool changed = false; | 289 bool changed = false; |
287 do { | 290 do { |
288 // If a common move can't be pushed to the common successor, then its | 291 // If a common move can't be pushed to the common successor, then its |
289 // destination also can't appear as source to any move being pushed. | 292 // destination also can't appear as source to any move being pushed. |
290 changed = false; | 293 changed = false; |
291 for (auto iter = move_map.begin(), end = move_map.end(); iter != end;) { | 294 for (auto iter = move_map.begin(), end = move_map.end(); iter != end;) { |
292 auto current = iter; | 295 auto current = iter; |
293 ++iter; | 296 ++iter; |
294 DCHECK_EQ(block->PredecessorCount(), current->second); | 297 DCHECK_EQ(block->PredecessorCount(), current->second); |
295 if (conflicting_srcs.find(current->first.first) != | 298 if (conflicting_srcs.find(current->first.source) != |
296 conflicting_srcs.end()) { | 299 conflicting_srcs.end()) { |
297 conflicting_srcs.insert(current->first.second); | 300 conflicting_srcs.insert(current->first.destination); |
298 move_map.erase(current); | 301 move_map.erase(current); |
299 changed = true; | 302 changed = true; |
300 } | 303 } |
301 } | 304 } |
302 } while (changed); | 305 } while (changed); |
303 } | 306 } |
304 | 307 |
305 if (move_map.empty()) return; | 308 if (move_map.empty()) return; |
306 | 309 |
307 DCHECK_NOT_NULL(instr); | 310 DCHECK_NOT_NULL(instr); |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
391 static_cast<Instruction::GapPosition>(1), code_zone()); | 394 static_cast<Instruction::GapPosition>(1), code_zone()); |
392 slot_1->AddMove(group_begin->destination(), load->destination()); | 395 slot_1->AddMove(group_begin->destination(), load->destination()); |
393 load->Eliminate(); | 396 load->Eliminate(); |
394 } | 397 } |
395 loads.clear(); | 398 loads.clear(); |
396 } | 399 } |
397 | 400 |
398 } // namespace compiler | 401 } // namespace compiler |
399 } // namespace internal | 402 } // namespace internal |
400 } // namespace v8 | 403 } // namespace v8 |
OLD | NEW |