| 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 |