1958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Copyright 2014 the V8 project authors. All rights reserved. 2958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Use of this source code is governed by a BSD-style license that can be 3958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// found in the LICENSE file. 4958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 5958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/compiler/move-optimizer.h" 6342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch#include "src/compiler/pipeline.h" 7958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "test/unittests/compiler/instruction-sequence-unittest.h" 8958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 9958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniernamespace v8 { 10958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniernamespace internal { 11958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniernamespace compiler { 12958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 13958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierclass MoveOptimizerTest : public InstructionSequenceTest { 14958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier public: 15014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Instruction* LastInstruction() { return sequence()->instructions().back(); } 16958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 17014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void AddMove(Instruction* instr, TestOperand from, TestOperand to, 18014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Instruction::GapPosition pos = Instruction::START) { 19014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch auto parallel_move = instr->GetOrCreateParallelMove(pos, zone()); 20014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch parallel_move->AddMove(ConvertMoveArg(from), ConvertMoveArg(to)); 21958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 22958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 23014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int NonRedundantSize(ParallelMove* moves) { 24958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int i = 0; 25014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (auto move : *moves) { 26014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (move->IsRedundant()) continue; 27958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier i++; 28958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 29958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return i; 30958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 31958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 32014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool Contains(ParallelMove* moves, TestOperand from_op, TestOperand to_op) { 33958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto from = ConvertMoveArg(from_op); 34958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto to = ConvertMoveArg(to_op); 35014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (auto move : *moves) { 36014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (move->IsRedundant()) continue; 37014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (move->source().Equals(from) && move->destination().Equals(to)) { 38958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return true; 39958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 40958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 41958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return false; 42958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 43958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 44958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // TODO(dcarney): add a verifier. 45958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void Optimize() { 46958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier WireBlocks(); 47958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (FLAG_trace_turbo) { 48958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier OFStream os(stdout); 49958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintableInstructionSequence printable = {config(), sequence()}; 50958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier os << "----- Instruction sequence before move optimization -----\n" 51958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier << printable; 52958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 53958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier MoveOptimizer move_optimizer(zone(), sequence()); 54958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier move_optimizer.Run(); 55958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (FLAG_trace_turbo) { 56958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier OFStream os(stdout); 57958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintableInstructionSequence printable = {config(), sequence()}; 58958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier os << "----- Instruction sequence after move optimization -----\n" 59958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier << printable; 60958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 61958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 62958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 63958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier private: 64014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand ConvertMoveArg(TestOperand op) { 65958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK_EQ(kNoValue, op.vreg_.value_); 66958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK_NE(kNoValue, op.value_); 67958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier switch (op.type_) { 68958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case kConstant: 69014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return ConstantOperand(op.value_); 70958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case kFixedSlot: 71014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return AllocatedOperand(LocationOperand::STACK_SLOT, 72014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineRepresentation::kWord32, op.value_); 73958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case kFixedRegister: 74958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK(0 <= op.value_ && op.value_ < num_general_registers()); 75014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return AllocatedOperand(LocationOperand::REGISTER, 76014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineRepresentation::kWord32, op.value_); 77014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kExplicit: 78014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK(0 <= op.value_ && op.value_ < num_general_registers()); 79014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return ExplicitOperand(LocationOperand::REGISTER, 80014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineRepresentation::kWord32, op.value_); 81958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier default: 82958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 83958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 84958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK(false); 85014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return InstructionOperand(); 86958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 87958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}; 88958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 89958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 90958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierTEST_F(MoveOptimizerTest, RemovesRedundant) { 91958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier StartBlock(); 92014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch auto first_instr = EmitNop(); 93014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AddMove(first_instr, Reg(0), Reg(1)); 94014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch auto last_instr = EmitNop(); 95014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AddMove(last_instr, Reg(1), Reg(0)); 96958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier EndBlock(Last()); 97958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 98958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Optimize(); 99958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK_EQ(0, NonRedundantSize(first_instr->parallel_moves()[0])); 101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch auto move = last_instr->parallel_moves()[0]; 102958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK_EQ(1, NonRedundantSize(move)); 103958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK(Contains(move, Reg(0), Reg(1))); 104958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 105958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 106958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_F(MoveOptimizerTest, RemovesRedundantExplicit) { 108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int first_reg_index = 10921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch RegisterConfiguration::Turbofan()->GetAllocatableGeneralCode(0); 110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int second_reg_index = 11121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch RegisterConfiguration::Turbofan()->GetAllocatableGeneralCode(1); 112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch StartBlock(); 114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch auto first_instr = EmitNop(); 115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AddMove(first_instr, Reg(first_reg_index), ExplicitReg(second_reg_index)); 116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch auto last_instr = EmitNop(); 117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AddMove(last_instr, Reg(second_reg_index), Reg(first_reg_index)); 118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch EndBlock(Last()); 119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Optimize(); 121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK_EQ(0, NonRedundantSize(first_instr->parallel_moves()[0])); 123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch auto move = last_instr->parallel_moves()[0]; 124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK_EQ(1, NonRedundantSize(move)); 125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK(Contains(move, Reg(first_reg_index), ExplicitReg(second_reg_index))); 126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 129958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierTEST_F(MoveOptimizerTest, SplitsConstants) { 130958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier StartBlock(); 131958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier EndBlock(Last()); 132958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch auto gap = LastInstruction(); 134958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier AddMove(gap, Const(1), Slot(0)); 135958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier AddMove(gap, Const(1), Slot(1)); 136958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier AddMove(gap, Const(1), Reg(0)); 137958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier AddMove(gap, Const(1), Slot(2)); 138958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 139958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Optimize(); 140958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 141958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto move = gap->parallel_moves()[0]; 142958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK_EQ(1, NonRedundantSize(move)); 143958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK(Contains(move, Const(1), Reg(0))); 144958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 145958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier move = gap->parallel_moves()[1]; 146958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK_EQ(3, NonRedundantSize(move)); 147958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK(Contains(move, Reg(0), Slot(0))); 148958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK(Contains(move, Reg(0), Slot(1))); 149958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK(Contains(move, Reg(0), Slot(2))); 150958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 151958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_F(MoveOptimizerTest, SimpleMerge) { 154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch StartBlock(); 155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch EndBlock(Branch(Imm(), 1, 2)); 156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch StartBlock(); 158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch EndBlock(Jump(2)); 159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AddMove(LastInstruction(), Reg(0), Reg(1)); 160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch StartBlock(); 162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch EndBlock(Jump(1)); 163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AddMove(LastInstruction(), Reg(0), Reg(1)); 164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch StartBlock(); 166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch EndBlock(Last()); 167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch auto last = LastInstruction(); 169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Optimize(); 171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch auto move = last->parallel_moves()[0]; 173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK_EQ(1, NonRedundantSize(move)); 174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK(Contains(move, Reg(0), Reg(1))); 175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_F(MoveOptimizerTest, SimpleMergeCycle) { 179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch StartBlock(); 180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch EndBlock(Branch(Imm(), 1, 2)); 181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch StartBlock(); 183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch EndBlock(Jump(2)); 184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch auto gap_0 = LastInstruction(); 185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AddMove(gap_0, Reg(0), Reg(1)); 186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AddMove(LastInstruction(), Reg(1), Reg(0)); 187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch StartBlock(); 189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch EndBlock(Jump(1)); 190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch auto gap_1 = LastInstruction(); 191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AddMove(gap_1, Reg(0), Reg(1)); 192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AddMove(gap_1, Reg(1), Reg(0)); 193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch StartBlock(); 195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch EndBlock(Last()); 196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch auto last = LastInstruction(); 198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Optimize(); 200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK(gap_0->AreMovesRedundant()); 202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK(gap_1->AreMovesRedundant()); 203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch auto move = last->parallel_moves()[0]; 204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK_EQ(2, NonRedundantSize(move)); 205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK(Contains(move, Reg(0), Reg(1))); 206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK(Contains(move, Reg(1), Reg(0))); 207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_F(MoveOptimizerTest, GapsCanMoveOverInstruction) { 211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch StartBlock(); 212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int const_index = 1; 213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DefineConstant(const_index); 214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Instruction* ctant_def = LastInstruction(); 215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AddMove(ctant_def, Reg(1), Reg(0)); 216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 217014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Instruction* last = EmitNop(); 218014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AddMove(last, Const(const_index), Reg(0)); 219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AddMove(last, Reg(0), Reg(1)); 220014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch EndBlock(Last()); 221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Optimize(); 222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ParallelMove* inst1_start = 224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ctant_def->GetParallelMove(Instruction::GapPosition::START); 225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ParallelMove* inst1_end = 226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ctant_def->GetParallelMove(Instruction::GapPosition::END); 227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ParallelMove* last_start = 228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch last->GetParallelMove(Instruction::GapPosition::START); 229342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch CHECK(inst1_start == nullptr || NonRedundantSize(inst1_start) == 0); 230342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch CHECK(inst1_end == nullptr || NonRedundantSize(inst1_end) == 0); 231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK(last_start->size() == 2); 232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int redundants = 0; 233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int assignment = 0; 234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (MoveOperands* move : *last_start) { 235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (move->IsRedundant()) { 236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ++redundants; 237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ++assignment; 239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK(move->destination().IsRegister()); 240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK(move->source().IsConstant()); 241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK_EQ(1, redundants); 244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK_EQ(1, assignment); 245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 248342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen MurdochTEST_F(MoveOptimizerTest, SubsetMovesMerge) { 249342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch StartBlock(); 250342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch EndBlock(Branch(Imm(), 1, 2)); 251342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 252342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch StartBlock(); 253342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch EndBlock(Jump(2)); 254342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch Instruction* last_move_b1 = LastInstruction(); 255342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch AddMove(last_move_b1, Reg(0), Reg(1)); 256342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch AddMove(last_move_b1, Reg(2), Reg(3)); 257342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 258342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch StartBlock(); 259342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch EndBlock(Jump(1)); 260342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch Instruction* last_move_b2 = LastInstruction(); 261342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch AddMove(last_move_b2, Reg(0), Reg(1)); 262342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch AddMove(last_move_b2, Reg(4), Reg(5)); 263342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 264342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch StartBlock(); 265342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch EndBlock(Last()); 266342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 267342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch Instruction* last = LastInstruction(); 268342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 269342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch Optimize(); 270342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 271342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch ParallelMove* last_move = last->parallel_moves()[0]; 272342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch CHECK_EQ(1, NonRedundantSize(last_move)); 273342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch CHECK(Contains(last_move, Reg(0), Reg(1))); 274342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 275342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch ParallelMove* b1_move = last_move_b1->parallel_moves()[0]; 276342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch CHECK_EQ(1, NonRedundantSize(b1_move)); 277342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch CHECK(Contains(b1_move, Reg(2), Reg(3))); 278342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 279342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch ParallelMove* b2_move = last_move_b2->parallel_moves()[0]; 280342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch CHECK_EQ(1, NonRedundantSize(b2_move)); 281342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch CHECK(Contains(b2_move, Reg(4), Reg(5))); 282342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch} 283342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 284342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 285342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen MurdochTEST_F(MoveOptimizerTest, GapConflictSubsetMovesDoNotMerge) { 286342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch StartBlock(); 287342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch EndBlock(Branch(Imm(), 1, 2)); 288342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 289342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch StartBlock(); 290342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch EndBlock(Jump(2)); 291342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch Instruction* last_move_b1 = LastInstruction(); 292342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch AddMove(last_move_b1, Reg(0), Reg(1)); 293342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch AddMove(last_move_b1, Reg(2), Reg(0)); 294342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch AddMove(last_move_b1, Reg(4), Reg(5)); 295342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 296342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch StartBlock(); 297342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch EndBlock(Jump(1)); 298342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch Instruction* last_move_b2 = LastInstruction(); 299342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch AddMove(last_move_b2, Reg(0), Reg(1)); 300342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch AddMove(last_move_b2, Reg(4), Reg(5)); 301342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 302342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch StartBlock(); 303342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch EndBlock(Last()); 304342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 305342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch Instruction* last = LastInstruction(); 306342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 307342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch Optimize(); 308342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 309342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch ParallelMove* last_move = last->parallel_moves()[0]; 310342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch CHECK_EQ(1, NonRedundantSize(last_move)); 311342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch CHECK(Contains(last_move, Reg(4), Reg(5))); 312342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 313342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch ParallelMove* b1_move = last_move_b1->parallel_moves()[0]; 314342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch CHECK_EQ(2, NonRedundantSize(b1_move)); 315342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch CHECK(Contains(b1_move, Reg(0), Reg(1))); 316342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch CHECK(Contains(b1_move, Reg(2), Reg(0))); 317342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 318342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch ParallelMove* b2_move = last_move_b2->parallel_moves()[0]; 319342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch CHECK_EQ(1, NonRedundantSize(b2_move)); 320342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch CHECK(Contains(b1_move, Reg(0), Reg(1))); 321342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch} 322342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 323342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen MurdochTEST_F(MoveOptimizerTest, ClobberedDestinationsAreEliminated) { 324342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch StartBlock(); 325342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch EmitNop(); 326342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch Instruction* first_instr = LastInstruction(); 327342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch AddMove(first_instr, Reg(0), Reg(1)); 328342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch EmitOI(Reg(1), 0, nullptr); 329342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch Instruction* last_instr = LastInstruction(); 330342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch EndBlock(); 331342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch Optimize(); 332342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 333342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch ParallelMove* first_move = first_instr->parallel_moves()[0]; 334342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch CHECK_EQ(0, NonRedundantSize(first_move)); 335342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 336342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch ParallelMove* last_move = last_instr->parallel_moves()[0]; 337342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch CHECK_EQ(0, NonRedundantSize(last_move)); 338342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch} 339342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 340958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} // namespace compiler 341958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} // namespace internal 342958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} // namespace v8 343