| 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 #include "src/compiler/pipeline.h" | 6 #include "src/compiler/pipeline.h" |
| 7 #include "test/unittests/compiler/instruction-sequence-unittest.h" | 7 #include "test/unittests/compiler/instruction-sequence-unittest.h" |
| 8 | 8 |
| 9 namespace v8 { | 9 namespace v8 { |
| 10 namespace internal { | 10 namespace internal { |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 91 return ExplicitOperand(LocationOperand::REGISTER, rep, op.value_); | 91 return ExplicitOperand(LocationOperand::REGISTER, rep, op.value_); |
| 92 } | 92 } |
| 93 default: | 93 default: |
| 94 break; | 94 break; |
| 95 } | 95 } |
| 96 CHECK(false); | 96 CHECK(false); |
| 97 return InstructionOperand(); | 97 return InstructionOperand(); |
| 98 } | 98 } |
| 99 }; | 99 }; |
| 100 | 100 |
| 101 | |
| 102 TEST_F(MoveOptimizerTest, RemovesRedundant) { | 101 TEST_F(MoveOptimizerTest, RemovesRedundant) { |
| 103 StartBlock(); | 102 StartBlock(); |
| 104 auto first_instr = EmitNop(); | 103 auto first_instr = EmitNop(); |
| 105 auto last_instr = EmitNop(); | 104 auto last_instr = EmitNop(); |
| 106 | 105 |
| 107 AddMove(first_instr, Reg(0), Reg(1)); | 106 AddMove(first_instr, Reg(0), Reg(1)); |
| 108 AddMove(last_instr, Reg(1), Reg(0)); | 107 AddMove(last_instr, Reg(1), Reg(0)); |
| 109 | 108 |
| 110 AddMove(first_instr, FPReg(kS128_1, kSimd128), FPReg(kS128_2, kSimd128)); | 109 AddMove(first_instr, FPReg(kS128_1, kSimd128), FPReg(kS128_2, kSimd128)); |
| 111 AddMove(last_instr, FPReg(kS128_2, kSimd128), FPReg(kS128_1, kSimd128)); | 110 AddMove(last_instr, FPReg(kS128_2, kSimd128), FPReg(kS128_1, kSimd128)); |
| 112 AddMove(first_instr, FPReg(kF64_1, kFloat64), FPReg(kF64_2, kFloat64)); | 111 AddMove(first_instr, FPReg(kF64_1, kFloat64), FPReg(kF64_2, kFloat64)); |
| 113 AddMove(last_instr, FPReg(kF64_2, kFloat64), FPReg(kF64_1, kFloat64)); | 112 AddMove(last_instr, FPReg(kF64_2, kFloat64), FPReg(kF64_1, kFloat64)); |
| 114 AddMove(first_instr, FPReg(kF32_1, kFloat32), FPReg(kF32_2, kFloat32)); | 113 AddMove(first_instr, FPReg(kF32_1, kFloat32), FPReg(kF32_2, kFloat32)); |
| 115 AddMove(last_instr, FPReg(kF32_2, kFloat32), FPReg(kF32_1, kFloat32)); | 114 AddMove(last_instr, FPReg(kF32_2, kFloat32), FPReg(kF32_1, kFloat32)); |
| 116 | 115 |
| 117 EndBlock(Last()); | 116 EndBlock(Last()); |
| 118 | 117 |
| 119 Optimize(); | 118 Optimize(); |
| 120 | 119 |
| 121 CHECK_EQ(0, NonRedundantSize(first_instr->parallel_moves()[0])); | 120 CHECK_EQ(0, NonRedundantSize(first_instr->parallel_moves()[0])); |
| 122 auto move = last_instr->parallel_moves()[0]; | 121 auto move = last_instr->parallel_moves()[0]; |
| 123 CHECK_EQ(4, NonRedundantSize(move)); | 122 CHECK_EQ(4, NonRedundantSize(move)); |
| 124 CHECK(Contains(move, Reg(0), Reg(1))); | 123 CHECK(Contains(move, Reg(0), Reg(1))); |
| 125 CHECK(Contains(move, FPReg(kS128_1, kSimd128), FPReg(kS128_2, kSimd128))); | 124 CHECK(Contains(move, FPReg(kS128_1, kSimd128), FPReg(kS128_2, kSimd128))); |
| 126 CHECK(Contains(move, FPReg(kF64_1, kFloat64), FPReg(kF64_2, kFloat64))); | 125 CHECK(Contains(move, FPReg(kF64_1, kFloat64), FPReg(kF64_2, kFloat64))); |
| 127 CHECK(Contains(move, FPReg(kF32_1, kFloat32), FPReg(kF32_2, kFloat32))); | 126 CHECK(Contains(move, FPReg(kF32_1, kFloat32), FPReg(kF32_2, kFloat32))); |
| 128 } | 127 } |
| 129 | 128 |
| 130 | |
| 131 TEST_F(MoveOptimizerTest, RemovesRedundantExplicit) { | 129 TEST_F(MoveOptimizerTest, RemovesRedundantExplicit) { |
| 132 int index1 = GetAllocatableCode(0); | 130 int index1 = GetAllocatableCode(0); |
| 133 int index2 = GetAllocatableCode(1); | 131 int index2 = GetAllocatableCode(1); |
| 134 int s128_1 = GetAllocatableCode(kS128_1, kSimd128); | 132 int s128_1 = GetAllocatableCode(kS128_1, kSimd128); |
| 135 int s128_2 = GetAllocatableCode(kS128_2, kSimd128); | 133 int s128_2 = GetAllocatableCode(kS128_2, kSimd128); |
| 136 int f64_1 = GetAllocatableCode(kF64_1, kFloat64); | 134 int f64_1 = GetAllocatableCode(kF64_1, kFloat64); |
| 137 int f64_2 = GetAllocatableCode(kF64_2, kFloat64); | 135 int f64_2 = GetAllocatableCode(kF64_2, kFloat64); |
| 138 int f32_1 = GetAllocatableCode(kF32_1, kFloat32); | 136 int f32_1 = GetAllocatableCode(kF32_1, kFloat32); |
| 139 int f32_2 = GetAllocatableCode(kF32_2, kFloat32); | 137 int f32_2 = GetAllocatableCode(kF32_2, kFloat32); |
| 140 | 138 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 160 CHECK_EQ(0, NonRedundantSize(first_instr->parallel_moves()[0])); | 158 CHECK_EQ(0, NonRedundantSize(first_instr->parallel_moves()[0])); |
| 161 auto move = last_instr->parallel_moves()[0]; | 159 auto move = last_instr->parallel_moves()[0]; |
| 162 CHECK_EQ(4, NonRedundantSize(move)); | 160 CHECK_EQ(4, NonRedundantSize(move)); |
| 163 CHECK(Contains(move, Reg(index1), ExplicitReg(index2))); | 161 CHECK(Contains(move, Reg(index1), ExplicitReg(index2))); |
| 164 CHECK( | 162 CHECK( |
| 165 Contains(move, FPReg(s128_1, kSimd128), ExplicitFPReg(s128_2, kSimd128))); | 163 Contains(move, FPReg(s128_1, kSimd128), ExplicitFPReg(s128_2, kSimd128))); |
| 166 CHECK(Contains(move, FPReg(f64_1, kFloat64), ExplicitFPReg(f64_2, kFloat64))); | 164 CHECK(Contains(move, FPReg(f64_1, kFloat64), ExplicitFPReg(f64_2, kFloat64))); |
| 167 CHECK(Contains(move, FPReg(f32_1, kFloat32), ExplicitFPReg(f32_2, kFloat32))); | 165 CHECK(Contains(move, FPReg(f32_1, kFloat32), ExplicitFPReg(f32_2, kFloat32))); |
| 168 } | 166 } |
| 169 | 167 |
| 170 | |
| 171 TEST_F(MoveOptimizerTest, SplitsConstants) { | 168 TEST_F(MoveOptimizerTest, SplitsConstants) { |
| 172 StartBlock(); | 169 StartBlock(); |
| 173 EndBlock(Last()); | 170 EndBlock(Last()); |
| 174 | 171 |
| 175 auto gap = LastInstruction(); | 172 auto gap = LastInstruction(); |
| 176 AddMove(gap, Const(1), Slot(0)); | 173 AddMove(gap, Const(1), Slot(0)); |
| 177 AddMove(gap, Const(1), Slot(1)); | 174 AddMove(gap, Const(1), Slot(1)); |
| 178 AddMove(gap, Const(1), Reg(0)); | 175 AddMove(gap, Const(1), Reg(0)); |
| 179 AddMove(gap, Const(1), Slot(2)); | 176 AddMove(gap, Const(1), Slot(2)); |
| 180 | 177 |
| 181 Optimize(); | 178 Optimize(); |
| 182 | 179 |
| 183 auto move = gap->parallel_moves()[0]; | 180 auto move = gap->parallel_moves()[0]; |
| 184 CHECK_EQ(1, NonRedundantSize(move)); | 181 CHECK_EQ(1, NonRedundantSize(move)); |
| 185 CHECK(Contains(move, Const(1), Reg(0))); | 182 CHECK(Contains(move, Const(1), Reg(0))); |
| 186 | 183 |
| 187 move = gap->parallel_moves()[1]; | 184 move = gap->parallel_moves()[1]; |
| 188 CHECK_EQ(3, NonRedundantSize(move)); | 185 CHECK_EQ(3, NonRedundantSize(move)); |
| 189 CHECK(Contains(move, Reg(0), Slot(0))); | 186 CHECK(Contains(move, Reg(0), Slot(0))); |
| 190 CHECK(Contains(move, Reg(0), Slot(1))); | 187 CHECK(Contains(move, Reg(0), Slot(1))); |
| 191 CHECK(Contains(move, Reg(0), Slot(2))); | 188 CHECK(Contains(move, Reg(0), Slot(2))); |
| 192 } | 189 } |
| 193 | 190 |
| 194 | |
| 195 TEST_F(MoveOptimizerTest, SimpleMerge) { | 191 TEST_F(MoveOptimizerTest, SimpleMerge) { |
| 196 StartBlock(); | 192 StartBlock(); |
| 197 EndBlock(Branch(Imm(), 1, 2)); | 193 EndBlock(Branch(Imm(), 1, 2)); |
| 198 | 194 |
| 199 StartBlock(); | 195 StartBlock(); |
| 200 EndBlock(Jump(2)); | 196 EndBlock(Jump(2)); |
| 201 AddMove(LastInstruction(), Reg(0), Reg(1)); | 197 AddMove(LastInstruction(), Reg(0), Reg(1)); |
| 202 AddMove(LastInstruction(), FPReg(kS128_1, kSimd128), | 198 AddMove(LastInstruction(), FPReg(kS128_1, kSimd128), |
| 203 FPReg(kS128_2, kSimd128)); | 199 FPReg(kS128_2, kSimd128)); |
| 204 AddMove(LastInstruction(), FPReg(kF64_1, kFloat64), FPReg(kF64_2, kFloat64)); | 200 AddMove(LastInstruction(), FPReg(kF64_1, kFloat64), FPReg(kF64_2, kFloat64)); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 220 Optimize(); | 216 Optimize(); |
| 221 | 217 |
| 222 auto move = last->parallel_moves()[0]; | 218 auto move = last->parallel_moves()[0]; |
| 223 CHECK_EQ(4, NonRedundantSize(move)); | 219 CHECK_EQ(4, NonRedundantSize(move)); |
| 224 CHECK(Contains(move, Reg(0), Reg(1))); | 220 CHECK(Contains(move, Reg(0), Reg(1))); |
| 225 CHECK(Contains(move, FPReg(kS128_1, kSimd128), FPReg(kS128_2, kSimd128))); | 221 CHECK(Contains(move, FPReg(kS128_1, kSimd128), FPReg(kS128_2, kSimd128))); |
| 226 CHECK(Contains(move, FPReg(kF64_1, kFloat64), FPReg(kF64_2, kFloat64))); | 222 CHECK(Contains(move, FPReg(kF64_1, kFloat64), FPReg(kF64_2, kFloat64))); |
| 227 CHECK(Contains(move, FPReg(kF32_1, kFloat32), FPReg(kF32_2, kFloat32))); | 223 CHECK(Contains(move, FPReg(kF32_1, kFloat32), FPReg(kF32_2, kFloat32))); |
| 228 } | 224 } |
| 229 | 225 |
| 230 | |
| 231 TEST_F(MoveOptimizerTest, SimpleMergeCycle) { | 226 TEST_F(MoveOptimizerTest, SimpleMergeCycle) { |
| 232 StartBlock(); | 227 StartBlock(); |
| 233 EndBlock(Branch(Imm(), 1, 2)); | 228 EndBlock(Branch(Imm(), 1, 2)); |
| 234 | 229 |
| 235 StartBlock(); | 230 StartBlock(); |
| 236 EndBlock(Jump(2)); | 231 EndBlock(Jump(2)); |
| 237 auto gap_0 = LastInstruction(); | 232 auto gap_0 = LastInstruction(); |
| 238 AddMove(gap_0, Reg(0), Reg(1)); | 233 AddMove(gap_0, Reg(0), Reg(1)); |
| 239 AddMove(LastInstruction(), Reg(1), Reg(0)); | 234 AddMove(LastInstruction(), Reg(1), Reg(0)); |
| 240 | 235 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 272 CHECK(Contains(move, Reg(0), Reg(1))); | 267 CHECK(Contains(move, Reg(0), Reg(1))); |
| 273 CHECK(Contains(move, Reg(1), Reg(0))); | 268 CHECK(Contains(move, Reg(1), Reg(0))); |
| 274 CHECK(Contains(move, FPReg(kS128_1, kSimd128), FPReg(kS128_2, kSimd128))); | 269 CHECK(Contains(move, FPReg(kS128_1, kSimd128), FPReg(kS128_2, kSimd128))); |
| 275 CHECK(Contains(move, FPReg(kS128_2, kSimd128), FPReg(kS128_1, kSimd128))); | 270 CHECK(Contains(move, FPReg(kS128_2, kSimd128), FPReg(kS128_1, kSimd128))); |
| 276 CHECK(Contains(move, FPReg(kF64_1, kFloat64), FPReg(kF64_2, kFloat64))); | 271 CHECK(Contains(move, FPReg(kF64_1, kFloat64), FPReg(kF64_2, kFloat64))); |
| 277 CHECK(Contains(move, FPReg(kF64_2, kFloat64), FPReg(kF64_1, kFloat64))); | 272 CHECK(Contains(move, FPReg(kF64_2, kFloat64), FPReg(kF64_1, kFloat64))); |
| 278 CHECK(Contains(move, FPReg(kF32_1, kFloat32), FPReg(kF32_2, kFloat32))); | 273 CHECK(Contains(move, FPReg(kF32_1, kFloat32), FPReg(kF32_2, kFloat32))); |
| 279 CHECK(Contains(move, FPReg(kF32_2, kFloat32), FPReg(kF32_1, kFloat32))); | 274 CHECK(Contains(move, FPReg(kF32_2, kFloat32), FPReg(kF32_1, kFloat32))); |
| 280 } | 275 } |
| 281 | 276 |
| 282 | |
| 283 TEST_F(MoveOptimizerTest, GapsCanMoveOverInstruction) { | 277 TEST_F(MoveOptimizerTest, GapsCanMoveOverInstruction) { |
| 284 StartBlock(); | 278 StartBlock(); |
| 285 int const_index = 1; | 279 int const_index = 1; |
| 286 DefineConstant(const_index); | 280 DefineConstant(const_index); |
| 287 Instruction* ctant_def = LastInstruction(); | 281 Instruction* ctant_def = LastInstruction(); |
| 288 AddMove(ctant_def, Reg(1), Reg(0)); | 282 AddMove(ctant_def, Reg(1), Reg(0)); |
| 289 | 283 |
| 290 Instruction* last = EmitNop(); | 284 Instruction* last = EmitNop(); |
| 291 AddMove(last, Const(const_index), Reg(0)); | 285 AddMove(last, Const(const_index), Reg(0)); |
| 292 AddMove(last, Reg(0), Reg(1)); | 286 AddMove(last, Reg(0), Reg(1)); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 310 } else { | 304 } else { |
| 311 ++assignment; | 305 ++assignment; |
| 312 CHECK(move->destination().IsRegister()); | 306 CHECK(move->destination().IsRegister()); |
| 313 CHECK(move->source().IsConstant()); | 307 CHECK(move->source().IsConstant()); |
| 314 } | 308 } |
| 315 } | 309 } |
| 316 CHECK_EQ(1, redundants); | 310 CHECK_EQ(1, redundants); |
| 317 CHECK_EQ(1, assignment); | 311 CHECK_EQ(1, assignment); |
| 318 } | 312 } |
| 319 | 313 |
| 320 | |
| 321 TEST_F(MoveOptimizerTest, SubsetMovesMerge) { | 314 TEST_F(MoveOptimizerTest, SubsetMovesMerge) { |
| 322 StartBlock(); | 315 StartBlock(); |
| 323 EndBlock(Branch(Imm(), 1, 2)); | 316 EndBlock(Branch(Imm(), 1, 2)); |
| 324 | 317 |
| 325 StartBlock(); | 318 StartBlock(); |
| 326 EndBlock(Jump(2)); | 319 EndBlock(Jump(2)); |
| 327 Instruction* last_move_b1 = LastInstruction(); | 320 Instruction* last_move_b1 = LastInstruction(); |
| 328 AddMove(last_move_b1, Reg(0), Reg(1)); | 321 AddMove(last_move_b1, Reg(0), Reg(1)); |
| 329 AddMove(last_move_b1, Reg(2), Reg(3)); | 322 AddMove(last_move_b1, Reg(2), Reg(3)); |
| 330 | 323 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 347 | 340 |
| 348 ParallelMove* b1_move = last_move_b1->parallel_moves()[0]; | 341 ParallelMove* b1_move = last_move_b1->parallel_moves()[0]; |
| 349 CHECK_EQ(1, NonRedundantSize(b1_move)); | 342 CHECK_EQ(1, NonRedundantSize(b1_move)); |
| 350 CHECK(Contains(b1_move, Reg(2), Reg(3))); | 343 CHECK(Contains(b1_move, Reg(2), Reg(3))); |
| 351 | 344 |
| 352 ParallelMove* b2_move = last_move_b2->parallel_moves()[0]; | 345 ParallelMove* b2_move = last_move_b2->parallel_moves()[0]; |
| 353 CHECK_EQ(1, NonRedundantSize(b2_move)); | 346 CHECK_EQ(1, NonRedundantSize(b2_move)); |
| 354 CHECK(Contains(b2_move, Reg(4), Reg(5))); | 347 CHECK(Contains(b2_move, Reg(4), Reg(5))); |
| 355 } | 348 } |
| 356 | 349 |
| 357 | |
| 358 TEST_F(MoveOptimizerTest, GapConflictSubsetMovesDoNotMerge) { | 350 TEST_F(MoveOptimizerTest, GapConflictSubsetMovesDoNotMerge) { |
| 359 StartBlock(); | 351 StartBlock(); |
| 360 EndBlock(Branch(Imm(), 1, 2)); | 352 EndBlock(Branch(Imm(), 1, 2)); |
| 361 | 353 |
| 362 StartBlock(); | 354 StartBlock(); |
| 363 EndBlock(Jump(2)); | 355 EndBlock(Jump(2)); |
| 364 Instruction* last_move_b1 = LastInstruction(); | 356 Instruction* last_move_b1 = LastInstruction(); |
| 365 AddMove(last_move_b1, Reg(0), Reg(1)); | 357 AddMove(last_move_b1, Reg(0), Reg(1)); |
| 366 AddMove(last_move_b1, Reg(2), Reg(0)); | 358 AddMove(last_move_b1, Reg(2), Reg(0)); |
| 367 AddMove(last_move_b1, Reg(4), Reg(5)); | 359 AddMove(last_move_b1, Reg(4), Reg(5)); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 430 ParallelMove* first_move = first_instr->parallel_moves()[0]; | 422 ParallelMove* first_move = first_instr->parallel_moves()[0]; |
| 431 CHECK_EQ(0, NonRedundantSize(first_move)); | 423 CHECK_EQ(0, NonRedundantSize(first_move)); |
| 432 | 424 |
| 433 ParallelMove* last_move = last_instr->parallel_moves()[0]; | 425 ParallelMove* last_move = last_instr->parallel_moves()[0]; |
| 434 CHECK_EQ(0, NonRedundantSize(last_move)); | 426 CHECK_EQ(0, NonRedundantSize(last_move)); |
| 435 } | 427 } |
| 436 | 428 |
| 437 } // namespace compiler | 429 } // namespace compiler |
| 438 } // namespace internal | 430 } // namespace internal |
| 439 } // namespace v8 | 431 } // namespace v8 |
| OLD | NEW |