| 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 struct MoveKey { | 13 struct MoveKey { | 
| 14   InstructionOperand source; | 14   InstructionOperand source; | 
| 15   InstructionOperand destination; | 15   InstructionOperand destination; | 
| 16 }; | 16 }; | 
| 17 | 17 | 
| 18 struct MoveKeyCompare { | 18 struct MoveKeyCompare { | 
| 19   bool operator()(const MoveKey& a, const MoveKey& b) const { | 19   bool operator()(const MoveKey& a, const MoveKey& b) const { | 
| 20     if (a.source.EqualsCanonicalized(b.source)) { | 20     if (a.source.EqualsCanonicalized(b.source)) { | 
| 21       return a.destination.CompareCanonicalized(b.destination); | 21       return a.destination.CompareCanonicalized(b.destination); | 
| 22     } | 22     } | 
| 23     return a.source.CompareCanonicalized(b.source); | 23     return a.source.CompareCanonicalized(b.source); | 
| 24   } | 24   } | 
| 25 }; | 25 }; | 
| 26 | 26 | 
| 27 typedef ZoneMap<MoveKey, unsigned, MoveKeyCompare> MoveMap; | 27 typedef ZoneMap<MoveKey, unsigned, MoveKeyCompare> MoveMap; | 
| 28 typedef ZoneSet<InstructionOperand, CompareOperandModuloType> OperandSet; | 28 typedef ZoneSet<InstructionOperand, CompareOperandModuloType> OperandSet; | 
| 29 | 29 | 
|  | 30 bool Blocks(const OperandSet& set, const InstructionOperand& operand) { | 
|  | 31   if (!operand.IsFPRegister()) return set.find(operand) != set.end(); | 
|  | 32 | 
|  | 33   const LocationOperand& loc = LocationOperand::cast(operand); | 
|  | 34   if (loc.representation() == MachineRepresentation::kFloat64) { | 
|  | 35     return set.find(operand) != set.end() || | 
|  | 36            set.find(LocationOperand(loc.kind(), loc.location_kind(), | 
|  | 37                                     MachineRepresentation::kFloat32, | 
|  | 38                                     loc.register_code())) != set.end(); | 
|  | 39   } | 
|  | 40   DCHECK_EQ(MachineRepresentation::kFloat32, loc.representation()); | 
|  | 41   return set.find(operand) != set.end() || | 
|  | 42          set.find(LocationOperand(loc.kind(), loc.location_kind(), | 
|  | 43                                   MachineRepresentation::kFloat64, | 
|  | 44                                   loc.register_code())) != set.end(); | 
|  | 45 } | 
| 30 | 46 | 
| 31 int FindFirstNonEmptySlot(const Instruction* instr) { | 47 int FindFirstNonEmptySlot(const Instruction* instr) { | 
| 32   int i = Instruction::FIRST_GAP_POSITION; | 48   int i = Instruction::FIRST_GAP_POSITION; | 
| 33   for (; i <= Instruction::LAST_GAP_POSITION; i++) { | 49   for (; i <= Instruction::LAST_GAP_POSITION; i++) { | 
| 34     ParallelMove* moves = instr->parallel_moves()[i]; | 50     ParallelMove* moves = instr->parallel_moves()[i]; | 
| 35     if (moves == nullptr) continue; | 51     if (moves == nullptr) continue; | 
| 36     for (MoveOperands* move : *moves) { | 52     for (MoveOperands* move : *moves) { | 
| 37       if (!move->IsRedundant()) return i; | 53       if (!move->IsRedundant()) return i; | 
| 38       move->Eliminate(); | 54       move->Eliminate(); | 
| 39     } | 55     } | 
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 158     // We assume CompressMoves has happened before this, which means we don't | 174     // We assume CompressMoves has happened before this, which means we don't | 
| 159     // have more than one assignment to dest. | 175     // have more than one assignment to dest. | 
| 160     src_cant_be.insert(move->destination()); | 176     src_cant_be.insert(move->destination()); | 
| 161   } | 177   } | 
| 162 | 178 | 
| 163   ZoneSet<MoveKey, MoveKeyCompare> move_candidates(local_zone()); | 179   ZoneSet<MoveKey, MoveKeyCompare> move_candidates(local_zone()); | 
| 164   // We start with all the moves that don't have conflicting source or | 180   // We start with all the moves that don't have conflicting source or | 
| 165   // destination operands are eligible for being moved down. | 181   // destination operands are eligible for being moved down. | 
| 166   for (MoveOperands* move : *from_moves) { | 182   for (MoveOperands* move : *from_moves) { | 
| 167     if (move->IsRedundant()) continue; | 183     if (move->IsRedundant()) continue; | 
| 168     if (dst_cant_be.find(move->destination()) == dst_cant_be.end()) { | 184     if (!Blocks(dst_cant_be, move->destination())) { | 
| 169       MoveKey key = {move->source(), move->destination()}; | 185       MoveKey key = {move->source(), move->destination()}; | 
| 170       move_candidates.insert(key); | 186       move_candidates.insert(key); | 
| 171     } | 187     } | 
| 172   } | 188   } | 
| 173   if (move_candidates.empty()) return; | 189   if (move_candidates.empty()) return; | 
| 174 | 190 | 
| 175   // Stabilize the candidate set. | 191   // Stabilize the candidate set. | 
| 176   bool changed = false; | 192   bool changed = false; | 
| 177   do { | 193   do { | 
| 178     changed = false; | 194     changed = false; | 
| 179     for (auto iter = move_candidates.begin(); iter != move_candidates.end();) { | 195     for (auto iter = move_candidates.begin(); iter != move_candidates.end();) { | 
| 180       auto current = iter; | 196       auto current = iter; | 
| 181       ++iter; | 197       ++iter; | 
| 182       InstructionOperand src = current->source; | 198       InstructionOperand src = current->source; | 
| 183       if (src_cant_be.find(src) != src_cant_be.end()) { | 199       if (Blocks(src_cant_be, src)) { | 
| 184         src_cant_be.insert(current->destination); | 200         src_cant_be.insert(current->destination); | 
| 185         move_candidates.erase(current); | 201         move_candidates.erase(current); | 
| 186         changed = true; | 202         changed = true; | 
| 187       } | 203       } | 
| 188     } | 204     } | 
| 189   } while (changed); | 205   } while (changed); | 
| 190 | 206 | 
| 191   ParallelMove to_move(local_zone()); | 207   ParallelMove to_move(local_zone()); | 
| 192   for (MoveOperands* move : *from_moves) { | 208   for (MoveOperands* move : *from_moves) { | 
| 193     if (move->IsRedundant()) continue; | 209     if (move->IsRedundant()) continue; | 
| (...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 471         static_cast<Instruction::GapPosition>(1), code_zone()); | 487         static_cast<Instruction::GapPosition>(1), code_zone()); | 
| 472     slot_1->AddMove(group_begin->destination(), load->destination()); | 488     slot_1->AddMove(group_begin->destination(), load->destination()); | 
| 473     load->Eliminate(); | 489     load->Eliminate(); | 
| 474   } | 490   } | 
| 475   loads.clear(); | 491   loads.clear(); | 
| 476 } | 492 } | 
| 477 | 493 | 
| 478 }  // namespace compiler | 494 }  // namespace compiler | 
| 479 }  // namespace internal | 495 }  // namespace internal | 
| 480 }  // namespace v8 | 496 }  // namespace v8 | 
| OLD | NEW | 
|---|