Index: src/compiler/move-optimizer.cc |
diff --git a/src/compiler/move-optimizer.cc b/src/compiler/move-optimizer.cc |
index 2c4c720d263b50bd909acd5800b2eccd8df6bc48..7c2911e7f5aea03f9a87bc1257088ab43826fe14 100644 |
--- a/src/compiler/move-optimizer.cc |
+++ b/src/compiler/move-optimizer.cc |
@@ -16,15 +16,14 @@ typedef ZoneSet<InstructionOperand> OperandSet; |
bool GapsCanMoveOver(Instruction* instr) { |
- DCHECK(!instr->IsGapMoves()); |
return instr->IsSourcePosition() || instr->IsNop(); |
} |
-int FindFirstNonEmptySlot(GapInstruction* gap) { |
- int i = GapInstruction::FIRST_INNER_POSITION; |
- for (; i <= GapInstruction::LAST_INNER_POSITION; i++) { |
- auto move = gap->parallel_moves()[i]; |
+int FindFirstNonEmptySlot(Instruction* instr) { |
+ int i = Instruction::FIRST_GAP_POSITION; |
+ for (; i <= Instruction::LAST_GAP_POSITION; i++) { |
+ auto move = instr->parallel_moves()[i]; |
if (move == nullptr) continue; |
auto move_ops = move->move_operands(); |
auto op = move_ops->begin(); |
@@ -97,52 +96,45 @@ void MoveOptimizer::CompressMoves(MoveOpVector* eliminated, ParallelMove* left, |
void MoveOptimizer::CompressBlock(InstructionBlock* block) { |
auto temp_vector = temp_vector_0(); |
DCHECK(temp_vector.empty()); |
- GapInstruction* prev_gap = nullptr; |
+ Instruction* prev_instr = nullptr; |
for (int index = block->code_start(); index < block->code_end(); ++index) { |
auto instr = code()->instructions()[index]; |
- if (!instr->IsGapMoves()) { |
- if (GapsCanMoveOver(instr)) continue; |
- if (prev_gap != nullptr) to_finalize_.push_back(prev_gap); |
- prev_gap = nullptr; |
- continue; |
- } |
- auto gap = GapInstruction::cast(instr); |
- int i = FindFirstNonEmptySlot(gap); |
- // Nothing to do here. |
- if (i == GapInstruction::LAST_INNER_POSITION + 1) { |
- if (prev_gap != nullptr) { |
- // Slide prev_gap down so we always know where to look for it. |
- std::swap(prev_gap->parallel_moves()[0], gap->parallel_moves()[0]); |
- prev_gap = gap; |
+ 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]); |
+ auto left = instr->parallel_moves()[0]; |
+ // Compress everything into position 0. |
+ for (++i; i <= Instruction::LAST_GAP_POSITION; ++i) { |
+ auto move = instr->parallel_moves()[i]; |
+ if (move == nullptr) continue; |
+ CompressMoves(&temp_vector, left, move); |
+ } |
+ if (prev_instr != nullptr) { |
+ // Smash left into prev_instr, killing left. |
+ auto pred_moves = prev_instr->parallel_moves()[0]; |
+ CompressMoves(&temp_vector, pred_moves, left); |
} |
- continue; |
} |
- // Move the first non-empty gap to position 0. |
- std::swap(gap->parallel_moves()[0], gap->parallel_moves()[i]); |
- auto left = gap->parallel_moves()[0]; |
- // Compress everything into position 0. |
- for (++i; i <= GapInstruction::LAST_INNER_POSITION; ++i) { |
- auto move = gap->parallel_moves()[i]; |
- if (move == nullptr) continue; |
- CompressMoves(&temp_vector, left, move); |
+ if (prev_instr != nullptr) { |
+ // Slide prev_instr down so we always know where to look for it. |
+ std::swap(prev_instr->parallel_moves()[0], instr->parallel_moves()[0]); |
} |
- if (prev_gap != nullptr) { |
- // Smash left into prev_gap, killing left. |
- auto pred_moves = prev_gap->parallel_moves()[0]; |
- CompressMoves(&temp_vector, pred_moves, left); |
- // Slide prev_gap down so we always know where to look for it. |
- std::swap(prev_gap->parallel_moves()[0], gap->parallel_moves()[0]); |
+ prev_instr = instr->parallel_moves()[0] == nullptr ? nullptr : instr; |
+ if (GapsCanMoveOver(instr)) continue; |
+ if (prev_instr != nullptr) { |
+ to_finalize_.push_back(prev_instr); |
+ prev_instr = nullptr; |
} |
- prev_gap = gap; |
} |
- if (prev_gap != nullptr) to_finalize_.push_back(prev_gap); |
+ if (prev_instr != nullptr) { |
+ to_finalize_.push_back(prev_instr); |
+ } |
} |
-GapInstruction* MoveOptimizer::LastGap(InstructionBlock* block) { |
- int gap_index = block->last_instruction_index() - 1; |
- auto instr = code()->instructions()[gap_index]; |
- return GapInstruction::cast(instr); |
+Instruction* MoveOptimizer::LastInstruction(InstructionBlock* block) { |
+ return code()->instructions()[block->last_instruction_index()]; |
} |
@@ -153,7 +145,6 @@ void MoveOptimizer::OptimizeMerge(InstructionBlock* block) { |
for (auto pred_index : block->predecessors()) { |
auto pred = code()->InstructionBlockAt(pred_index); |
auto last_instr = code()->instructions()[pred->last_instruction_index()]; |
- DCHECK(!last_instr->IsGapMoves()); |
if (last_instr->IsSourcePosition()) continue; |
if (last_instr->IsCall()) return; |
if (last_instr->TempCount() != 0) return; |
@@ -169,12 +160,12 @@ void MoveOptimizer::OptimizeMerge(InstructionBlock* block) { |
// Accumulate set of shared moves. |
for (auto pred_index : block->predecessors()) { |
auto pred = code()->InstructionBlockAt(pred_index); |
- auto gap = LastGap(pred); |
- if (gap->parallel_moves()[0] == nullptr || |
- gap->parallel_moves()[0]->move_operands()->is_empty()) { |
+ auto instr = LastInstruction(pred); |
+ if (instr->parallel_moves()[0] == nullptr || |
+ instr->parallel_moves()[0]->move_operands()->is_empty()) { |
return; |
} |
- auto move_ops = gap->parallel_moves()[0]->move_operands(); |
+ auto move_ops = instr->parallel_moves()[0]->move_operands(); |
for (auto op = move_ops->begin(); op != move_ops->end(); ++op) { |
if (op->IsRedundant()) continue; |
auto src = *op->source(); |
@@ -191,34 +182,30 @@ void MoveOptimizer::OptimizeMerge(InstructionBlock* block) { |
} |
if (move_map.empty() || correct_counts != move_map.size()) return; |
// Find insertion point. |
- GapInstruction* gap = nullptr; |
+ Instruction* instr = nullptr; |
for (int i = block->first_instruction_index(); |
i <= block->last_instruction_index(); ++i) { |
- auto instr = code()->instructions()[i]; |
- if (instr->IsGapMoves()) { |
- gap = GapInstruction::cast(instr); |
- continue; |
- } |
- if (!GapsCanMoveOver(instr)) break; |
+ instr = code()->instructions()[i]; |
+ if (!GapsCanMoveOver(instr) || !instr->AreMovesRedundant()) break; |
} |
- DCHECK(gap != nullptr); |
+ DCHECK(instr != nullptr); |
bool gap_initialized = true; |
- if (gap->parallel_moves()[0] == nullptr || |
- gap->parallel_moves()[0]->move_operands()->is_empty()) { |
- to_finalize_.push_back(gap); |
+ if (instr->parallel_moves()[0] == nullptr || |
+ instr->parallel_moves()[0]->move_operands()->is_empty()) { |
+ to_finalize_.push_back(instr); |
} else { |
// Will compress after insertion. |
gap_initialized = false; |
- std::swap(gap->parallel_moves()[0], gap->parallel_moves()[1]); |
+ std::swap(instr->parallel_moves()[0], instr->parallel_moves()[1]); |
} |
- auto move = gap->GetOrCreateParallelMove( |
- static_cast<GapInstruction::InnerPosition>(0), code_zone()); |
+ auto move = instr->GetOrCreateParallelMove( |
+ static_cast<Instruction::GapPosition>(0), code_zone()); |
// Delete relevant entries in predecessors and move everything to block. |
bool first_iteration = true; |
for (auto pred_index : block->predecessors()) { |
auto pred = code()->InstructionBlockAt(pred_index); |
- auto gap = LastGap(pred); |
- auto move_ops = gap->parallel_moves()[0]->move_operands(); |
+ auto instr = LastInstruction(pred); |
+ auto move_ops = instr->parallel_moves()[0]->move_operands(); |
for (auto op = move_ops->begin(); op != move_ops->end(); ++op) { |
if (op->IsRedundant()) continue; |
MoveKey key = {*op->source(), *op->destination()}; |
@@ -234,20 +221,20 @@ void MoveOptimizer::OptimizeMerge(InstructionBlock* block) { |
} |
// Compress. |
if (!gap_initialized) { |
- CompressMoves(&temp_vector_0(), gap->parallel_moves()[0], |
- gap->parallel_moves()[1]); |
+ CompressMoves(&temp_vector_0(), instr->parallel_moves()[0], |
+ instr->parallel_moves()[1]); |
} |
} |
// Split multiple loads of the same constant or stack slot off into the second |
// slot and keep remaining moves in the first slot. |
-void MoveOptimizer::FinalizeMoves(GapInstruction* gap) { |
+void MoveOptimizer::FinalizeMoves(Instruction* instr) { |
auto loads = temp_vector_0(); |
DCHECK(loads.empty()); |
auto new_moves = temp_vector_1(); |
DCHECK(new_moves.empty()); |
- auto move_ops = gap->parallel_moves()[0]->move_operands(); |
+ auto move_ops = instr->parallel_moves()[0]->move_operands(); |
for (auto move = move_ops->begin(); move != move_ops->end(); ++move) { |
if (move->IsRedundant()) { |
move->Eliminate(); |
@@ -294,8 +281,8 @@ void MoveOptimizer::FinalizeMoves(GapInstruction* gap) { |
loads.clear(); |
if (new_moves.empty()) return; |
// Insert all new moves into slot 1. |
- auto slot_1 = gap->GetOrCreateParallelMove( |
- static_cast<GapInstruction::InnerPosition>(1), code_zone()); |
+ auto slot_1 = instr->GetOrCreateParallelMove( |
+ static_cast<Instruction::GapPosition>(1), code_zone()); |
DCHECK(slot_1->move_operands()->is_empty()); |
slot_1->move_operands()->AddBlock(MoveOperands(nullptr, nullptr), |
static_cast<int>(new_moves.size()), |