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/base/utils/random-number-generator.h" | 5 #include "src/base/utils/random-number-generator.h" |
6 #include "src/codegen.h" | 6 #include "src/codegen.h" |
7 #include "src/compiler/js-graph.h" | 7 #include "src/compiler/js-graph.h" |
8 #include "src/compiler/machine-operator-reducer.h" | 8 #include "src/compiler/machine-operator-reducer.h" |
9 #include "src/compiler/operator-properties.h" | 9 #include "src/compiler/operator-properties.h" |
10 #include "src/compiler/typer.h" | 10 #include "src/compiler/typer.h" |
11 #include "test/cctest/cctest.h" | 11 #include "test/cctest/cctest.h" |
12 #include "test/cctest/compiler/value-helper.h" | 12 #include "test/cctest/compiler/value-helper.h" |
13 | 13 |
14 namespace v8 { | 14 namespace v8 { |
15 namespace internal { | 15 namespace internal { |
16 namespace compiler { | 16 namespace compiler { |
17 | 17 |
18 template <typename T> | 18 template <typename T> |
19 const Operator* NewConstantOperator(CommonOperatorBuilder* common, | 19 const Operator* NewConstantOperator(CommonOperatorBuilder* common, |
20 volatile T value); | 20 volatile T value); |
21 | 21 |
22 template <> | 22 template <> |
23 const Operator* NewConstantOperator<int32_t>(CommonOperatorBuilder* common, | 23 const Operator* NewConstantOperator<int32_t>(CommonOperatorBuilder* common, |
24 volatile int32_t value) { | 24 volatile int32_t value) { |
25 return common->Int32Constant(value); | 25 return common->Int32Constant(value); |
26 } | 26 } |
27 | 27 |
28 template <> | 28 template <> |
| 29 const Operator* NewConstantOperator<int64_t>(CommonOperatorBuilder* common, |
| 30 volatile int64_t value) { |
| 31 return common->Int64Constant(value); |
| 32 } |
| 33 |
| 34 template <> |
29 const Operator* NewConstantOperator<double>(CommonOperatorBuilder* common, | 35 const Operator* NewConstantOperator<double>(CommonOperatorBuilder* common, |
30 volatile double value) { | 36 volatile double value) { |
31 return common->Float64Constant(value); | 37 return common->Float64Constant(value); |
32 } | 38 } |
33 | 39 |
34 | 40 |
35 template <typename T> | 41 template <typename T> |
36 T ValueOfOperator(const Operator* op); | 42 T ValueOfOperator(const Operator* op); |
37 | 43 |
38 template <> | 44 template <> |
39 int32_t ValueOfOperator<int32_t>(const Operator* op) { | 45 int32_t ValueOfOperator<int32_t>(const Operator* op) { |
40 CHECK_EQ(IrOpcode::kInt32Constant, op->opcode()); | 46 CHECK_EQ(IrOpcode::kInt32Constant, op->opcode()); |
41 return OpParameter<int32_t>(op); | 47 return OpParameter<int32_t>(op); |
42 } | 48 } |
43 | 49 |
44 template <> | 50 template <> |
| 51 int64_t ValueOfOperator<int64_t>(const Operator* op) { |
| 52 CHECK_EQ(IrOpcode::kInt64Constant, op->opcode()); |
| 53 return OpParameter<int64_t>(op); |
| 54 } |
| 55 |
| 56 template <> |
45 double ValueOfOperator<double>(const Operator* op) { | 57 double ValueOfOperator<double>(const Operator* op) { |
46 CHECK_EQ(IrOpcode::kFloat64Constant, op->opcode()); | 58 CHECK_EQ(IrOpcode::kFloat64Constant, op->opcode()); |
47 return OpParameter<double>(op); | 59 return OpParameter<double>(op); |
48 } | 60 } |
49 | 61 |
50 | 62 |
51 class ReducerTester : public HandleAndZoneScope { | 63 class ReducerTester : public HandleAndZoneScope { |
52 public: | 64 public: |
53 explicit ReducerTester( | 65 explicit ReducerTester( |
54 int num_parameters = 0, | 66 int num_parameters = 0, |
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
308 } | 320 } |
309 | 321 |
310 R.CheckDontPutConstantOnRight(44); | 322 R.CheckDontPutConstantOnRight(44); |
311 | 323 |
312 Node* x = R.Parameter(); | 324 Node* x = R.Parameter(); |
313 Node* zero = R.Constant<int32_t>(0); | 325 Node* zero = R.Constant<int32_t>(0); |
314 | 326 |
315 R.CheckBinop(x, x, zero); // x << 0 => x | 327 R.CheckBinop(x, x, zero); // x << 0 => x |
316 } | 328 } |
317 | 329 |
| 330 TEST(ReduceWord64Shl) { |
| 331 ReducerTester R; |
| 332 R.binop = R.machine.Word64Shl(); |
| 333 |
| 334 FOR_INT64_INPUTS(i) { |
| 335 for (int64_t y = 0; y < 64; y++) { |
| 336 int64_t x = *i; |
| 337 R.CheckFoldBinop<int64_t>(x << y, x, y); |
| 338 } |
| 339 } |
| 340 |
| 341 R.CheckDontPutConstantOnRight(44); |
| 342 |
| 343 Node* x = R.Parameter(); |
| 344 Node* zero = R.Constant<int64_t>(0); |
| 345 |
| 346 R.CheckBinop(x, x, zero); // x << 0 => x |
| 347 } |
318 | 348 |
319 TEST(ReduceWord32Shr) { | 349 TEST(ReduceWord32Shr) { |
320 ReducerTester R; | 350 ReducerTester R; |
321 R.binop = R.machine.Word32Shr(); | 351 R.binop = R.machine.Word32Shr(); |
322 | 352 |
323 // TODO(titzer): test out of range shifts | 353 // TODO(titzer): test out of range shifts |
324 FOR_UINT32_INPUTS(i) { | 354 FOR_UINT32_INPUTS(i) { |
325 for (uint32_t y = 0; y < 32; y++) { | 355 for (uint32_t y = 0; y < 32; y++) { |
326 uint32_t x = *i; | 356 uint32_t x = *i; |
327 R.CheckFoldBinop<int32_t>(x >> y, x, y); | 357 R.CheckFoldBinop<int32_t>(x >> y, x, y); |
328 } | 358 } |
329 } | 359 } |
330 | 360 |
331 R.CheckDontPutConstantOnRight(44); | 361 R.CheckDontPutConstantOnRight(44); |
332 | 362 |
333 Node* x = R.Parameter(); | 363 Node* x = R.Parameter(); |
334 Node* zero = R.Constant<int32_t>(0); | 364 Node* zero = R.Constant<int32_t>(0); |
335 | 365 |
336 R.CheckBinop(x, x, zero); // x >>> 0 => x | 366 R.CheckBinop(x, x, zero); // x >>> 0 => x |
337 } | 367 } |
338 | 368 |
| 369 TEST(ReduceWord64Shr) { |
| 370 ReducerTester R; |
| 371 R.binop = R.machine.Word64Shr(); |
| 372 |
| 373 FOR_UINT64_INPUTS(i) { |
| 374 for (uint64_t y = 0; y < 64; y++) { |
| 375 uint64_t x = *i; |
| 376 R.CheckFoldBinop<int64_t>(x >> y, x, y); |
| 377 } |
| 378 } |
| 379 |
| 380 R.CheckDontPutConstantOnRight(44); |
| 381 |
| 382 Node* x = R.Parameter(); |
| 383 Node* zero = R.Constant<int64_t>(0); |
| 384 |
| 385 R.CheckBinop(x, x, zero); // x >>> 0 => x |
| 386 } |
339 | 387 |
340 TEST(ReduceWord32Sar) { | 388 TEST(ReduceWord32Sar) { |
341 ReducerTester R; | 389 ReducerTester R; |
342 R.binop = R.machine.Word32Sar(); | 390 R.binop = R.machine.Word32Sar(); |
343 | 391 |
344 // TODO(titzer): test out of range shifts | 392 // TODO(titzer): test out of range shifts |
345 FOR_INT32_INPUTS(i) { | 393 FOR_INT32_INPUTS(i) { |
346 for (int32_t y = 0; y < 32; y++) { | 394 for (int32_t y = 0; y < 32; y++) { |
347 int32_t x = *i; | 395 int32_t x = *i; |
348 R.CheckFoldBinop<int32_t>(x >> y, x, y); | 396 R.CheckFoldBinop<int32_t>(x >> y, x, y); |
349 } | 397 } |
350 } | 398 } |
351 | 399 |
352 R.CheckDontPutConstantOnRight(44); | 400 R.CheckDontPutConstantOnRight(44); |
353 | 401 |
354 Node* x = R.Parameter(); | 402 Node* x = R.Parameter(); |
355 Node* zero = R.Constant<int32_t>(0); | 403 Node* zero = R.Constant<int32_t>(0); |
356 | 404 |
357 R.CheckBinop(x, x, zero); // x >> 0 => x | 405 R.CheckBinop(x, x, zero); // x >> 0 => x |
358 } | 406 } |
359 | 407 |
| 408 TEST(ReduceWord64Sar) { |
| 409 ReducerTester R; |
| 410 R.binop = R.machine.Word64Sar(); |
| 411 |
| 412 FOR_INT64_INPUTS(i) { |
| 413 for (int64_t y = 0; y < 64; y++) { |
| 414 int64_t x = *i; |
| 415 R.CheckFoldBinop<int64_t>(x >> y, x, y); |
| 416 } |
| 417 } |
| 418 |
| 419 R.CheckDontPutConstantOnRight(44); |
| 420 |
| 421 Node* x = R.Parameter(); |
| 422 Node* zero = R.Constant<int64_t>(0); |
| 423 |
| 424 R.CheckBinop(x, x, zero); // x >> 0 => x |
| 425 } |
360 | 426 |
361 static void CheckJsShift(ReducerTester* R) { | 427 static void CheckJsShift(ReducerTester* R) { |
362 CHECK(R->machine.Word32ShiftIsSafe()); | 428 CHECK(R->machine.Word32ShiftIsSafe()); |
363 | 429 |
364 Node* x = R->Parameter(0); | 430 Node* x = R->Parameter(0); |
365 Node* y = R->Parameter(1); | 431 Node* y = R->Parameter(1); |
366 Node* thirty_one = R->Constant<int32_t>(0x1f); | 432 Node* thirty_one = R->Constant<int32_t>(0x1f); |
367 Node* y_and_thirty_one = | 433 Node* y_and_thirty_one = |
368 R->graph.NewNode(R->machine.Word32And(), y, thirty_one); | 434 R->graph.NewNode(R->machine.Word32And(), y, thirty_one); |
369 | 435 |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
426 R.CheckPutConstantOnRight(41); | 492 R.CheckPutConstantOnRight(41); |
427 R.CheckPutConstantOnRight(4407); | 493 R.CheckPutConstantOnRight(4407); |
428 | 494 |
429 Node* x = R.Parameter(); | 495 Node* x = R.Parameter(); |
430 Node* zero = R.Constant<int32_t>(0); | 496 Node* zero = R.Constant<int32_t>(0); |
431 | 497 |
432 R.CheckBinop(x, x, zero); // x + 0 => x | 498 R.CheckBinop(x, x, zero); // x + 0 => x |
433 R.CheckBinop(x, zero, x); // 0 + x => x | 499 R.CheckBinop(x, zero, x); // 0 + x => x |
434 } | 500 } |
435 | 501 |
| 502 TEST(ReduceInt64Add) { |
| 503 ReducerTester R; |
| 504 R.binop = R.machine.Int64Add(); |
| 505 |
| 506 FOR_INT64_INPUTS(pl) { |
| 507 FOR_INT64_INPUTS(pr) { |
| 508 int64_t x = *pl, y = *pr; |
| 509 R.CheckFoldBinop<int64_t>(x + y, x, y); |
| 510 } |
| 511 } |
| 512 |
| 513 R.CheckPutConstantOnRight(41); |
| 514 |
| 515 Node* x = R.Parameter(); |
| 516 Node* zero = R.Constant<int64_t>(0); |
| 517 R.CheckBinop(x, x, zero); // x + 0 => x |
| 518 R.CheckBinop(x, zero, x); // 0 + x => x |
| 519 } |
436 | 520 |
437 TEST(ReduceInt32Sub) { | 521 TEST(ReduceInt32Sub) { |
438 ReducerTester R; | 522 ReducerTester R; |
439 R.binop = R.machine.Int32Sub(); | 523 R.binop = R.machine.Int32Sub(); |
440 | 524 |
441 FOR_INT32_INPUTS(pl) { | 525 FOR_INT32_INPUTS(pl) { |
442 FOR_INT32_INPUTS(pr) { | 526 FOR_INT32_INPUTS(pr) { |
443 int32_t x = *pl, y = *pr; | 527 int32_t x = *pl, y = *pr; |
444 R.CheckFoldBinop<int32_t>(x - y, x, y); | 528 R.CheckFoldBinop<int32_t>(x - y, x, y); |
445 } | 529 } |
446 } | 530 } |
447 | 531 |
448 R.CheckDontPutConstantOnRight(412); | 532 R.CheckDontPutConstantOnRight(412); |
449 | 533 |
450 Node* x = R.Parameter(); | 534 Node* x = R.Parameter(); |
451 Node* zero = R.Constant<int32_t>(0); | 535 Node* zero = R.Constant<int32_t>(0); |
452 | 536 |
453 R.CheckBinop(x, x, zero); // x - 0 => x | 537 R.CheckBinop(x, x, zero); // x - 0 => x |
454 } | 538 } |
455 | 539 |
| 540 TEST(ReduceInt64Sub) { |
| 541 ReducerTester R; |
| 542 R.binop = R.machine.Int64Sub(); |
| 543 |
| 544 FOR_INT64_INPUTS(pl) { |
| 545 FOR_INT64_INPUTS(pr) { |
| 546 int64_t x = *pl, y = *pr; |
| 547 R.CheckFoldBinop<int64_t>(x - y, x, y); |
| 548 } |
| 549 } |
| 550 |
| 551 R.CheckDontPutConstantOnRight(42); |
| 552 |
| 553 Node* x = R.Parameter(); |
| 554 Node* zero = R.Constant<int64_t>(0); |
| 555 |
| 556 R.CheckBinop(x, x, zero); // x - 0 => x |
| 557 R.CheckFoldBinop<int64_t>(0, x, x); // x - x => 0 |
| 558 |
| 559 Node* k = R.Constant<int64_t>(6); |
| 560 |
| 561 R.CheckFoldBinop<int64_t>(x, R.machine.Int64Add(), -6, x, |
| 562 k); // x - K => x + -K |
| 563 } |
456 | 564 |
457 TEST(ReduceInt32Mul) { | 565 TEST(ReduceInt32Mul) { |
458 ReducerTester R; | 566 ReducerTester R; |
459 R.binop = R.machine.Int32Mul(); | 567 R.binop = R.machine.Int32Mul(); |
460 | 568 |
461 FOR_INT32_INPUTS(pl) { | 569 FOR_INT32_INPUTS(pl) { |
462 FOR_INT32_INPUTS(pr) { | 570 FOR_INT32_INPUTS(pr) { |
463 int32_t x = *pl, y = *pr; | 571 int32_t x = *pl, y = *pr; |
464 R.CheckFoldBinop<int32_t>(x * y, x, y); // TODO(titzer): signed overflow | 572 R.CheckFoldBinop<int32_t>(x * y, x, y); // TODO(titzer): signed overflow |
465 } | 573 } |
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
710 MachineOperatorReducer reducer(&R.jsgraph); | 818 MachineOperatorReducer reducer(&R.jsgraph); |
711 Reduction reduction = reducer.Reduce(store); | 819 Reduction reduction = reducer.Reduce(store); |
712 CHECK(!reduction.Changed()); // stores should not be reduced. | 820 CHECK(!reduction.Changed()); // stores should not be reduced. |
713 } | 821 } |
714 } | 822 } |
715 | 823 |
716 | 824 |
717 // TODO(titzer): test MachineOperatorReducer for Word64And | 825 // TODO(titzer): test MachineOperatorReducer for Word64And |
718 // TODO(titzer): test MachineOperatorReducer for Word64Or | 826 // TODO(titzer): test MachineOperatorReducer for Word64Or |
719 // TODO(titzer): test MachineOperatorReducer for Word64Xor | 827 // TODO(titzer): test MachineOperatorReducer for Word64Xor |
720 // TODO(titzer): test MachineOperatorReducer for Word64Shl | |
721 // TODO(titzer): test MachineOperatorReducer for Word64Shr | |
722 // TODO(titzer): test MachineOperatorReducer for Word64Sar | |
723 // TODO(titzer): test MachineOperatorReducer for Word64Equal | 828 // TODO(titzer): test MachineOperatorReducer for Word64Equal |
724 // TODO(titzer): test MachineOperatorReducer for Word64Not | 829 // TODO(titzer): test MachineOperatorReducer for Word64Not |
725 // TODO(titzer): test MachineOperatorReducer for Int64Add | |
726 // TODO(titzer): test MachineOperatorReducer for Int64Sub | |
727 // TODO(titzer): test MachineOperatorReducer for Int64Mul | 830 // TODO(titzer): test MachineOperatorReducer for Int64Mul |
728 // TODO(titzer): test MachineOperatorReducer for Int64UMul | 831 // TODO(titzer): test MachineOperatorReducer for Int64UMul |
729 // TODO(titzer): test MachineOperatorReducer for Int64Div | 832 // TODO(titzer): test MachineOperatorReducer for Int64Div |
730 // TODO(titzer): test MachineOperatorReducer for Uint64Div | 833 // TODO(titzer): test MachineOperatorReducer for Uint64Div |
731 // TODO(titzer): test MachineOperatorReducer for Int64Mod | 834 // TODO(titzer): test MachineOperatorReducer for Int64Mod |
732 // TODO(titzer): test MachineOperatorReducer for Uint64Mod | 835 // TODO(titzer): test MachineOperatorReducer for Uint64Mod |
733 // TODO(titzer): test MachineOperatorReducer for Int64Neg | 836 // TODO(titzer): test MachineOperatorReducer for Int64Neg |
734 // TODO(titzer): test MachineOperatorReducer for ChangeInt32ToFloat64 | 837 // TODO(titzer): test MachineOperatorReducer for ChangeInt32ToFloat64 |
735 // TODO(titzer): test MachineOperatorReducer for ChangeFloat64ToInt32 | 838 // TODO(titzer): test MachineOperatorReducer for ChangeFloat64ToInt32 |
736 // TODO(titzer): test MachineOperatorReducer for Float64Compare | 839 // TODO(titzer): test MachineOperatorReducer for Float64Compare |
737 // TODO(titzer): test MachineOperatorReducer for Float64Add | 840 // TODO(titzer): test MachineOperatorReducer for Float64Add |
738 // TODO(titzer): test MachineOperatorReducer for Float64Sub | 841 // TODO(titzer): test MachineOperatorReducer for Float64Sub |
739 // TODO(titzer): test MachineOperatorReducer for Float64Mul | 842 // TODO(titzer): test MachineOperatorReducer for Float64Mul |
740 // TODO(titzer): test MachineOperatorReducer for Float64Div | 843 // TODO(titzer): test MachineOperatorReducer for Float64Div |
741 // TODO(titzer): test MachineOperatorReducer for Float64Mod | 844 // TODO(titzer): test MachineOperatorReducer for Float64Mod |
742 | 845 |
743 } // namespace compiler | 846 } // namespace compiler |
744 } // namespace internal | 847 } // namespace internal |
745 } // namespace v8 | 848 } // namespace v8 |
OLD | NEW |