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 |