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/pipeline.h" | 5 #include "src/compiler/pipeline.h" |
6 #include "test/unittests/compiler/instruction-sequence-unittest.h" | 6 #include "test/unittests/compiler/instruction-sequence-unittest.h" |
7 | 7 |
8 namespace v8 { | 8 namespace v8 { |
9 namespace internal { | 9 namespace internal { |
10 namespace compiler { | 10 namespace compiler { |
11 | 11 |
12 class RegisterAllocatorTest : public InstructionSequenceTest { | 12 class RegisterAllocatorTest : public InstructionSequenceTest { |
13 public: | 13 public: |
14 void Allocate() { | 14 void Allocate() { |
15 WireBlocks(); | 15 WireBlocks(); |
16 Pipeline::AllocateRegistersForTesting(config(), sequence(), true); | 16 Pipeline::AllocateRegistersForTesting(config(), sequence(), true); |
17 } | 17 } |
18 }; | 18 }; |
19 | 19 |
20 | 20 |
21 TEST_F(RegisterAllocatorTest, CanAllocateThreeRegisters) { | 21 TEST_F(RegisterAllocatorTest, CanAllocateThreeRegisters) { |
22 // return p0 + p1; | 22 // return p0 + p1; |
23 StartBlock(); | 23 StartBlock(); |
24 auto a_reg = Parameter(); | 24 auto a_reg = Parameter(); |
25 auto b_reg = Parameter(); | 25 auto b_reg = Parameter(); |
26 auto c_reg = EmitOII(Reg(1), Reg(a_reg, 1), Reg(b_reg, 0)); | 26 auto c_reg = EmitOI(Reg(1), Reg(a_reg, 1), Reg(b_reg, 0)); |
27 Return(c_reg); | 27 Return(c_reg); |
28 EndBlock(Last()); | 28 EndBlock(Last()); |
29 | 29 |
30 Allocate(); | 30 Allocate(); |
31 } | 31 } |
32 | 32 |
33 | 33 |
34 TEST_F(RegisterAllocatorTest, SimpleLoop) { | 34 TEST_F(RegisterAllocatorTest, SimpleLoop) { |
35 // i = K; | 35 // i = K; |
36 // while(true) { i++ } | 36 // while(true) { i++ } |
37 StartBlock(); | 37 StartBlock(); |
38 auto i_reg = DefineConstant(); | 38 auto i_reg = DefineConstant(); |
39 EndBlock(); | 39 EndBlock(); |
40 | 40 |
41 { | 41 { |
42 StartLoop(1); | 42 StartLoop(1); |
43 | 43 |
44 StartBlock(); | 44 StartBlock(); |
45 auto phi = Phi(i_reg); | 45 auto phi = Phi(i_reg); |
46 auto ipp = EmitOII(Same(), Reg(phi), Use(DefineConstant())); | 46 auto ipp = EmitOI(Same(), Reg(phi), Use(DefineConstant())); |
47 Extend(phi, ipp); | 47 Extend(phi, ipp); |
48 EndBlock(Jump(0)); | 48 EndBlock(Jump(0)); |
49 | 49 |
50 EndLoop(); | 50 EndLoop(); |
51 } | 51 } |
52 | 52 |
53 Allocate(); | 53 Allocate(); |
54 } | 54 } |
55 | 55 |
56 | 56 |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
205 // Loop header. | 205 // Loop header. |
206 StartBlock(); | 206 StartBlock(); |
207 | 207 |
208 for (size_t i = 0; i < arraysize(parameters); ++i) { | 208 for (size_t i = 0; i < arraysize(parameters); ++i) { |
209 phis[i] = Phi(parameters[i]); | 209 phis[i] = Phi(parameters[i]); |
210 } | 210 } |
211 | 211 |
212 // Perform some computations. | 212 // Perform some computations. |
213 // something like phi[i] += const | 213 // something like phi[i] += const |
214 for (size_t i = 0; i < arraysize(parameters); ++i) { | 214 for (size_t i = 0; i < arraysize(parameters); ++i) { |
215 auto result = EmitOII(Same(), Reg(phis[i]), Use(constant)); | 215 auto result = EmitOI(Same(), Reg(phis[i]), Use(constant)); |
216 Extend(phis[i], result); | 216 Extend(phis[i], result); |
217 } | 217 } |
218 | 218 |
219 EndBlock(Branch(Reg(DefineConstant()), 1, 2)); | 219 EndBlock(Branch(Reg(DefineConstant()), 1, 2)); |
220 | 220 |
221 // Jump back to loop header. | 221 // Jump back to loop header. |
222 StartBlock(); | 222 StartBlock(); |
223 EndBlock(Jump(-1)); | 223 EndBlock(Jump(-1)); |
224 | 224 |
225 EndLoop(); | 225 EndLoop(); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
267 } | 267 } |
268 for (int i = 0; i < kDefaultNRegs; ++i) { | 268 for (int i = 0; i < kDefaultNRegs; ++i) { |
269 call_ops[i + kDefaultNRegs] = Slot(constants[i], i); | 269 call_ops[i + kDefaultNRegs] = Slot(constants[i], i); |
270 } | 270 } |
271 EmitCall(Slot(-1), arraysize(call_ops), call_ops); | 271 EmitCall(Slot(-1), arraysize(call_ops), call_ops); |
272 EndBlock(Last()); | 272 EndBlock(Last()); |
273 | 273 |
274 Allocate(); | 274 Allocate(); |
275 } | 275 } |
276 | 276 |
| 277 |
| 278 TEST_F(RegisterAllocatorTest, SplitBeforeInstruction) { |
| 279 const int kNumRegs = 6; |
| 280 SetNumRegs(kNumRegs, kNumRegs); |
| 281 |
| 282 StartBlock(); |
| 283 |
| 284 // Stack parameters/spilled values. |
| 285 auto p_0 = Define(Slot(-1)); |
| 286 auto p_1 = Define(Slot(-2)); |
| 287 |
| 288 // Fill registers. |
| 289 VReg values[kNumRegs]; |
| 290 for (size_t i = 0; i < arraysize(values); ++i) { |
| 291 values[i] = Define(Reg(static_cast<int>(i))); |
| 292 } |
| 293 |
| 294 // values[0] will be split in the second half of this instruction. |
| 295 // Models Intel mod instructions. |
| 296 EmitOI(Reg(0), Reg(p_0, 1), UniqueReg(p_1)); |
| 297 EmitI(Reg(values[0], 0)); |
| 298 EndBlock(Last()); |
| 299 |
| 300 Allocate(); |
| 301 } |
| 302 |
| 303 |
| 304 TEST_F(RegisterAllocatorTest, NestedDiamondPhiMerge) { |
| 305 // Outer diamond. |
| 306 StartBlock(); |
| 307 EndBlock(Branch(Imm(), 1, 5)); |
| 308 |
| 309 // Diamond 1 |
| 310 StartBlock(); |
| 311 EndBlock(Branch(Imm(), 1, 2)); |
| 312 |
| 313 StartBlock(); |
| 314 auto ll = Define(Reg()); |
| 315 EndBlock(Jump(2)); |
| 316 |
| 317 StartBlock(); |
| 318 auto lr = Define(Reg()); |
| 319 EndBlock(); |
| 320 |
| 321 StartBlock(); |
| 322 auto l_phi = Phi(ll, lr); |
| 323 EndBlock(Jump(5)); |
| 324 |
| 325 // Diamond 2 |
| 326 StartBlock(); |
| 327 EndBlock(Branch(Imm(), 1, 2)); |
| 328 |
| 329 StartBlock(); |
| 330 auto rl = Define(Reg()); |
| 331 EndBlock(Jump(2)); |
| 332 |
| 333 StartBlock(); |
| 334 auto rr = Define(Reg()); |
| 335 EndBlock(); |
| 336 |
| 337 StartBlock(); |
| 338 auto r_phi = Phi(rl, rr); |
| 339 EndBlock(); |
| 340 |
| 341 // Outer diamond merge. |
| 342 StartBlock(); |
| 343 auto phi = Phi(l_phi, r_phi); |
| 344 Return(Reg(phi)); |
| 345 EndBlock(); |
| 346 |
| 347 Allocate(); |
| 348 } |
| 349 |
| 350 |
| 351 TEST_F(RegisterAllocatorTest, NestedDiamondPhiMergeDifferent) { |
| 352 // Outer diamond. |
| 353 StartBlock(); |
| 354 EndBlock(Branch(Imm(), 1, 5)); |
| 355 |
| 356 // Diamond 1 |
| 357 StartBlock(); |
| 358 EndBlock(Branch(Imm(), 1, 2)); |
| 359 |
| 360 StartBlock(); |
| 361 auto ll = Define(Reg(0)); |
| 362 EndBlock(Jump(2)); |
| 363 |
| 364 StartBlock(); |
| 365 auto lr = Define(Reg(1)); |
| 366 EndBlock(); |
| 367 |
| 368 StartBlock(); |
| 369 auto l_phi = Phi(ll, lr); |
| 370 EndBlock(Jump(5)); |
| 371 |
| 372 // Diamond 2 |
| 373 StartBlock(); |
| 374 EndBlock(Branch(Imm(), 1, 2)); |
| 375 |
| 376 StartBlock(); |
| 377 auto rl = Define(Reg(2)); |
| 378 EndBlock(Jump(2)); |
| 379 |
| 380 StartBlock(); |
| 381 auto rr = Define(Reg(3)); |
| 382 EndBlock(); |
| 383 |
| 384 StartBlock(); |
| 385 auto r_phi = Phi(rl, rr); |
| 386 EndBlock(); |
| 387 |
| 388 // Outer diamond merge. |
| 389 StartBlock(); |
| 390 auto phi = Phi(l_phi, r_phi); |
| 391 Return(Reg(phi)); |
| 392 EndBlock(); |
| 393 |
| 394 Allocate(); |
| 395 } |
| 396 |
277 } // namespace compiler | 397 } // namespace compiler |
278 } // namespace internal | 398 } // namespace internal |
279 } // namespace v8 | 399 } // namespace v8 |
OLD | NEW |