Index: src/compiler/move-optimizer.cc |
diff --git a/src/compiler/move-optimizer.cc b/src/compiler/move-optimizer.cc |
index bf5e3c116f2be7bcf9b3247dff294736bb984d0a..c81766ed0b13cac20245b421be0e042904396c80 100644 |
--- a/src/compiler/move-optimizer.cc |
+++ b/src/compiler/move-optimizer.cc |
@@ -118,6 +118,8 @@ void MoveOptimizer::Run() { |
void MoveOptimizer::CompressMoves(ParallelMove* left, ParallelMove* right) { |
+ if (right == nullptr) return; |
+ |
MoveOpVector& eliminated = local_vector(); |
DCHECK(eliminated.empty()); |
@@ -153,26 +155,37 @@ void MoveOptimizer::CompressBlock(InstructionBlock* block) { |
for (int index = block->code_start(); index < block->code_end(); ++index) { |
Instruction* instr = code()->instructions()[index]; |
int i = FindFirstNonEmptySlot(instr); |
- if (i <= Instruction::LAST_GAP_POSITION) { |
- // Move the first non-empty gap to position 0. |
- std::swap(instr->parallel_moves()[0], instr->parallel_moves()[i]); |
- ParallelMove* left = instr->parallel_moves()[0]; |
- // Compress everything into position 0. |
- for (++i; i <= Instruction::LAST_GAP_POSITION; ++i) { |
- ParallelMove* move = instr->parallel_moves()[i]; |
- if (move == nullptr) continue; |
- CompressMoves(left, move); |
- } |
- if (prev_instr != nullptr) { |
- // Smash left into prev_instr, killing left. |
- ParallelMove* pred_moves = prev_instr->parallel_moves()[0]; |
- CompressMoves(pred_moves, left); |
- } |
+ bool has_moves = i <= Instruction::LAST_GAP_POSITION; |
+ |
+ if (i == Instruction::LAST_GAP_POSITION) { |
+ std::swap(instr->parallel_moves()[Instruction::FIRST_GAP_POSITION], |
+ instr->parallel_moves()[Instruction::LAST_GAP_POSITION]); |
+ } else if (i == Instruction::FIRST_GAP_POSITION) { |
+ CompressMoves(instr->parallel_moves()[Instruction::FIRST_GAP_POSITION], |
+ instr->parallel_moves()[Instruction::LAST_GAP_POSITION]); |
} |
+ // We either have no moves, or, after swapping or compressing, we have |
+ // all the moves in the first gap position, and none in the second/end gap |
+ // position. |
+ ParallelMove* first = |
+ instr->parallel_moves()[Instruction::FIRST_GAP_POSITION]; |
+ ParallelMove* last = |
+ instr->parallel_moves()[Instruction::LAST_GAP_POSITION]; |
+ USE(last); |
+ |
+ DCHECK(!has_moves || |
+ (first != nullptr && (last == nullptr || last->empty()))); |
+ |
if (prev_instr != nullptr) { |
+ if (has_moves) { |
+ // Smash first into prev_instr, killing left. |
+ ParallelMove* pred_moves = prev_instr->parallel_moves()[0]; |
+ CompressMoves(pred_moves, first); |
+ } |
// Slide prev_instr down so we always know where to look for it. |
std::swap(prev_instr->parallel_moves()[0], instr->parallel_moves()[0]); |
} |
+ |
prev_instr = instr->parallel_moves()[0] == nullptr ? nullptr : instr; |
if (GapsCanMoveOver(instr, local_zone())) continue; |
if (prev_instr != nullptr) { |