| 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/gap-resolver.h" | 5 #include "src/compiler/gap-resolver.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <functional> | 8 #include <functional> |
| 9 #include <set> | 9 #include <set> |
| 10 | 10 |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 141 DCHECK(!move->IsRedundant()); | 141 DCHECK(!move->IsRedundant()); |
| 142 | 142 |
| 143 // Clear this move's destination to indicate a pending move. The actual | 143 // Clear this move's destination to indicate a pending move. The actual |
| 144 // destination is saved on the side. | 144 // destination is saved on the side. |
| 145 InstructionOperand source = move->source(); | 145 InstructionOperand source = move->source(); |
| 146 DCHECK(!source.IsInvalid()); // Or else it will look eliminated. | 146 DCHECK(!source.IsInvalid()); // Or else it will look eliminated. |
| 147 InstructionOperand destination = move->destination(); | 147 InstructionOperand destination = move->destination(); |
| 148 move->SetPending(); | 148 move->SetPending(); |
| 149 | 149 |
| 150 // We may need to split moves between FP locations differently. | 150 // We may need to split moves between FP locations differently. |
| 151 bool is_fp_loc_move = !kSimpleFPAliasing && destination.IsFPLocationOperand(); | 151 const bool is_fp_loc_move = |
| 152 !kSimpleFPAliasing && destination.IsFPLocationOperand(); |
| 152 | 153 |
| 153 // Perform a depth-first traversal of the move graph to resolve dependencies. | 154 // Perform a depth-first traversal of the move graph to resolve dependencies. |
| 154 // Any unperformed, unpending move with a source the same as this one's | 155 // Any unperformed, unpending move with a source the same as this one's |
| 155 // destination blocks this one so recursively perform all such moves. | 156 // destination blocks this one so recursively perform all such moves. |
| 156 for (size_t i = 0; i < moves->size(); ++i) { | 157 for (size_t i = 0; i < moves->size(); ++i) { |
| 157 auto other = (*moves)[i]; | 158 auto other = (*moves)[i]; |
| 158 if (other->IsEliminated()) continue; | 159 if (other->IsEliminated()) continue; |
| 159 if (other->IsPending()) continue; | 160 if (other->IsPending()) continue; |
| 160 if (other->source().InterferesWith(destination)) { | 161 if (other->source().InterferesWith(destination)) { |
| 161 if (!kSimpleFPAliasing && is_fp_loc_move && | 162 if (is_fp_loc_move && |
| 162 LocationOperand::cast(other->source()).representation() > | 163 LocationOperand::cast(other->source()).representation() > |
| 163 split_rep_) { | 164 split_rep_) { |
| 164 // 'other' must also be an FP location move. Break it into fragments | 165 // 'other' must also be an FP location move. Break it into fragments |
| 165 // of the same size as 'move'. 'other' is set to one of the fragments, | 166 // of the same size as 'move'. 'other' is set to one of the fragments, |
| 166 // and the rest are appended to 'moves'. | 167 // and the rest are appended to 'moves'. |
| 167 other = Split(other, split_rep_, moves); | 168 other = Split(other, split_rep_, moves); |
| 168 // 'other' may not block destination now. | 169 // 'other' may not block destination now. |
| 169 if (!other->source().InterferesWith(destination)) continue; | 170 if (!other->source().InterferesWith(destination)) continue; |
| 170 } | 171 } |
| 171 // Though PerformMove can change any source operand in the move graph, | 172 // Though PerformMove can change any source operand in the move graph, |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 206 } | 207 } |
| 207 | 208 |
| 208 // Ensure source is a register or both are stack slots, to limit swap cases. | 209 // Ensure source is a register or both are stack slots, to limit swap cases. |
| 209 if (source.IsStackSlot() || source.IsFPStackSlot()) { | 210 if (source.IsStackSlot() || source.IsFPStackSlot()) { |
| 210 std::swap(source, destination); | 211 std::swap(source, destination); |
| 211 } | 212 } |
| 212 assembler_->AssembleSwap(&source, &destination); | 213 assembler_->AssembleSwap(&source, &destination); |
| 213 move->Eliminate(); | 214 move->Eliminate(); |
| 214 | 215 |
| 215 // Update outstanding moves whose source may now have been moved. | 216 // Update outstanding moves whose source may now have been moved. |
| 216 if (!kSimpleFPAliasing && is_fp_loc_move) { | 217 if (is_fp_loc_move) { |
| 217 // We may have to split larger moves. | 218 // We may have to split larger moves. |
| 218 for (size_t i = 0; i < moves->size(); ++i) { | 219 for (size_t i = 0; i < moves->size(); ++i) { |
| 219 auto other = (*moves)[i]; | 220 auto other = (*moves)[i]; |
| 220 if (other->IsEliminated()) continue; | 221 if (other->IsEliminated()) continue; |
| 221 if (source.InterferesWith(other->source())) { | 222 if (source.InterferesWith(other->source())) { |
| 222 if (LocationOperand::cast(other->source()).representation() > | 223 if (LocationOperand::cast(other->source()).representation() > |
| 223 split_rep_) { | 224 split_rep_) { |
| 224 other = Split(other, split_rep_, moves); | 225 other = Split(other, split_rep_, moves); |
| 225 if (!source.InterferesWith(other->source())) continue; | 226 if (!source.InterferesWith(other->source())) continue; |
| 226 } | 227 } |
| (...skipping 14 matching lines...) Expand all Loading... |
| 241 other->set_source(destination); | 242 other->set_source(destination); |
| 242 } else if (destination.EqualsCanonicalized(other->source())) { | 243 } else if (destination.EqualsCanonicalized(other->source())) { |
| 243 other->set_source(source); | 244 other->set_source(source); |
| 244 } | 245 } |
| 245 } | 246 } |
| 246 } | 247 } |
| 247 } | 248 } |
| 248 } // namespace compiler | 249 } // namespace compiler |
| 249 } // namespace internal | 250 } // namespace internal |
| 250 } // namespace v8 | 251 } // namespace v8 |
| OLD | NEW |