| 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 |