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/simplified-lowering.h" | 5 #include "src/compiler/simplified-lowering.h" |
6 | 6 |
7 #include <limits> | 7 #include <limits> |
8 | 8 |
9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
10 #include "src/code-factory.h" | 10 #include "src/code-factory.h" |
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
361 Type* upper = NodeProperties::GetType(node); | 361 Type* upper = NodeProperties::GetType(node); |
362 MachineType output_type = | 362 MachineType output_type = |
363 static_cast<MachineType>(changer_->TypeFromUpperBound(upper) | output); | 363 static_cast<MachineType>(changer_->TypeFromUpperBound(upper) | output); |
364 SetOutput(node, output_type); | 364 SetOutput(node, output_type); |
365 | 365 |
366 if (lower()) { | 366 if (lower()) { |
367 // Update the select operator. | 367 // Update the select operator. |
368 SelectParameters p = SelectParametersOf(node->op()); | 368 SelectParameters p = SelectParametersOf(node->op()); |
369 MachineType type = static_cast<MachineType>(output_type); | 369 MachineType type = static_cast<MachineType>(output_type); |
370 if (type != p.type()) { | 370 if (type != p.type()) { |
371 node->set_op(lowering->common()->Select(type, p.hint())); | 371 NodeProperties::ChangeOp(node, |
| 372 lowering->common()->Select(type, p.hint())); |
372 } | 373 } |
373 | 374 |
374 // Convert inputs to the output representation of this select. | 375 // Convert inputs to the output representation of this select. |
375 ProcessInput(node, 1, output_type); | 376 ProcessInput(node, 1, output_type); |
376 ProcessInput(node, 2, output_type); | 377 ProcessInput(node, 2, output_type); |
377 } else { | 378 } else { |
378 // Propagate {use} of the select to value inputs. | 379 // Propagate {use} of the select to value inputs. |
379 MachineType use_type = | 380 MachineType use_type = |
380 static_cast<MachineType>((use & kTypeMask) | output); | 381 static_cast<MachineType>((use & kTypeMask) | output); |
381 ProcessInput(node, 1, use_type); | 382 ProcessInput(node, 1, use_type); |
(...skipping 10 matching lines...) Expand all Loading... |
392 MachineType output_type = | 393 MachineType output_type = |
393 static_cast<MachineType>(changer_->TypeFromUpperBound(upper) | output); | 394 static_cast<MachineType>(changer_->TypeFromUpperBound(upper) | output); |
394 SetOutput(node, output_type); | 395 SetOutput(node, output_type); |
395 | 396 |
396 int values = node->op()->ValueInputCount(); | 397 int values = node->op()->ValueInputCount(); |
397 | 398 |
398 if (lower()) { | 399 if (lower()) { |
399 // Update the phi operator. | 400 // Update the phi operator. |
400 MachineType type = static_cast<MachineType>(output_type); | 401 MachineType type = static_cast<MachineType>(output_type); |
401 if (type != OpParameter<MachineType>(node)) { | 402 if (type != OpParameter<MachineType>(node)) { |
402 node->set_op(lowering->common()->Phi(type, values)); | 403 NodeProperties::ChangeOp(node, lowering->common()->Phi(type, values)); |
403 } | 404 } |
404 | 405 |
405 // Convert inputs to the output representation of this phi. | 406 // Convert inputs to the output representation of this phi. |
406 for (int i = 0; i < node->InputCount(); i++) { | 407 for (int i = 0; i < node->InputCount(); i++) { |
407 ProcessInput(node, i, i < values ? output_type : 0); | 408 ProcessInput(node, i, i < values ? output_type : 0); |
408 } | 409 } |
409 } else { | 410 } else { |
410 // Propagate {use} of the phi to value inputs, and 0 to control. | 411 // Propagate {use} of the phi to value inputs, and 0 to control. |
411 MachineType use_type = | 412 MachineType use_type = |
412 static_cast<MachineType>((use & kTypeMask) | output); | 413 static_cast<MachineType>((use & kTypeMask) | output); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
446 } | 447 } |
447 } else { | 448 } else { |
448 Zone* zone = jsgraph_->zone(); | 449 Zone* zone = jsgraph_->zone(); |
449 ZoneVector<MachineType>* types = | 450 ZoneVector<MachineType>* types = |
450 new (zone->New(sizeof(ZoneVector<MachineType>))) | 451 new (zone->New(sizeof(ZoneVector<MachineType>))) |
451 ZoneVector<MachineType>(node->InputCount(), zone); | 452 ZoneVector<MachineType>(node->InputCount(), zone); |
452 for (int i = 0; i < node->InputCount(); i++) { | 453 for (int i = 0; i < node->InputCount(); i++) { |
453 MachineTypeUnion input_type = GetInfo(node->InputAt(i))->output; | 454 MachineTypeUnion input_type = GetInfo(node->InputAt(i))->output; |
454 (*types)[i] = static_cast<MachineType>(input_type); | 455 (*types)[i] = static_cast<MachineType>(input_type); |
455 } | 456 } |
456 node->set_op(jsgraph_->common()->TypedStateValues(types)); | 457 NodeProperties::ChangeOp(node, |
| 458 jsgraph_->common()->TypedStateValues(types)); |
457 } | 459 } |
458 SetOutput(node, kMachAnyTagged); | 460 SetOutput(node, kMachAnyTagged); |
459 } | 461 } |
460 | 462 |
461 const Operator* Int32Op(Node* node) { | 463 const Operator* Int32Op(Node* node) { |
462 return changer_->Int32OperatorFor(node->opcode()); | 464 return changer_->Int32OperatorFor(node->opcode()); |
463 } | 465 } |
464 | 466 |
465 const Operator* Uint32Op(Node* node) { | 467 const Operator* Uint32Op(Node* node) { |
466 return changer_->Uint32OperatorFor(node->opcode()); | 468 return changer_->Uint32OperatorFor(node->opcode()); |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
576 return SetOutput(node, kRepTagged); | 578 return SetOutput(node, kRepTagged); |
577 | 579 |
578 //------------------------------------------------------------------ | 580 //------------------------------------------------------------------ |
579 // Simplified operators. | 581 // Simplified operators. |
580 //------------------------------------------------------------------ | 582 //------------------------------------------------------------------ |
581 case IrOpcode::kBooleanNot: { | 583 case IrOpcode::kBooleanNot: { |
582 if (lower()) { | 584 if (lower()) { |
583 MachineTypeUnion input = GetInfo(node->InputAt(0))->output; | 585 MachineTypeUnion input = GetInfo(node->InputAt(0))->output; |
584 if (input & kRepBit) { | 586 if (input & kRepBit) { |
585 // BooleanNot(x: kRepBit) => Word32Equal(x, #0) | 587 // BooleanNot(x: kRepBit) => Word32Equal(x, #0) |
586 node->set_op(lowering->machine()->Word32Equal()); | |
587 node->AppendInput(jsgraph_->zone(), jsgraph_->Int32Constant(0)); | 588 node->AppendInput(jsgraph_->zone(), jsgraph_->Int32Constant(0)); |
| 589 NodeProperties::ChangeOp(node, lowering->machine()->Word32Equal()); |
588 } else { | 590 } else { |
589 // BooleanNot(x: kRepTagged) => WordEqual(x, #false) | 591 // BooleanNot(x: kRepTagged) => WordEqual(x, #false) |
590 node->set_op(lowering->machine()->WordEqual()); | |
591 node->AppendInput(jsgraph_->zone(), jsgraph_->FalseConstant()); | 592 node->AppendInput(jsgraph_->zone(), jsgraph_->FalseConstant()); |
| 593 NodeProperties::ChangeOp(node, lowering->machine()->WordEqual()); |
592 } | 594 } |
593 } else { | 595 } else { |
594 // No input representation requirement; adapt during lowering. | 596 // No input representation requirement; adapt during lowering. |
595 ProcessInput(node, 0, kTypeBool); | 597 ProcessInput(node, 0, kTypeBool); |
596 SetOutput(node, kRepBit); | 598 SetOutput(node, kRepBit); |
597 } | 599 } |
598 break; | 600 break; |
599 } | 601 } |
600 case IrOpcode::kBooleanToNumber: { | 602 case IrOpcode::kBooleanToNumber: { |
601 if (lower()) { | 603 if (lower()) { |
602 MachineTypeUnion input = GetInfo(node->InputAt(0))->output; | 604 MachineTypeUnion input = GetInfo(node->InputAt(0))->output; |
603 if (input & kRepBit) { | 605 if (input & kRepBit) { |
604 // BooleanToNumber(x: kRepBit) => x | 606 // BooleanToNumber(x: kRepBit) => x |
605 DeferReplacement(node, node->InputAt(0)); | 607 DeferReplacement(node, node->InputAt(0)); |
606 } else { | 608 } else { |
607 // BooleanToNumber(x: kRepTagged) => WordEqual(x, #true) | 609 // BooleanToNumber(x: kRepTagged) => WordEqual(x, #true) |
608 node->set_op(lowering->machine()->WordEqual()); | |
609 node->AppendInput(jsgraph_->zone(), jsgraph_->TrueConstant()); | 610 node->AppendInput(jsgraph_->zone(), jsgraph_->TrueConstant()); |
| 611 NodeProperties::ChangeOp(node, lowering->machine()->WordEqual()); |
610 } | 612 } |
611 } else { | 613 } else { |
612 // No input representation requirement; adapt during lowering. | 614 // No input representation requirement; adapt during lowering. |
613 ProcessInput(node, 0, kTypeBool); | 615 ProcessInput(node, 0, kTypeBool); |
614 SetOutput(node, kMachInt32); | 616 SetOutput(node, kMachInt32); |
615 } | 617 } |
616 break; | 618 break; |
617 } | 619 } |
618 case IrOpcode::kNumberEqual: | 620 case IrOpcode::kNumberEqual: |
619 case IrOpcode::kNumberLessThan: | 621 case IrOpcode::kNumberLessThan: |
620 case IrOpcode::kNumberLessThanOrEqual: { | 622 case IrOpcode::kNumberLessThanOrEqual: { |
621 // Number comparisons reduce to integer comparisons for integer inputs. | 623 // Number comparisons reduce to integer comparisons for integer inputs. |
622 if (BothInputsAre(node, Type::Signed32())) { | 624 if (BothInputsAre(node, Type::Signed32())) { |
623 // => signed Int32Cmp | 625 // => signed Int32Cmp |
624 VisitInt32Cmp(node); | 626 VisitInt32Cmp(node); |
625 if (lower()) node->set_op(Int32Op(node)); | 627 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node)); |
626 } else if (BothInputsAre(node, Type::Unsigned32())) { | 628 } else if (BothInputsAre(node, Type::Unsigned32())) { |
627 // => unsigned Int32Cmp | 629 // => unsigned Int32Cmp |
628 VisitUint32Cmp(node); | 630 VisitUint32Cmp(node); |
629 if (lower()) node->set_op(Uint32Op(node)); | 631 if (lower()) NodeProperties::ChangeOp(node, Uint32Op(node)); |
630 } else { | 632 } else { |
631 // => Float64Cmp | 633 // => Float64Cmp |
632 VisitFloat64Cmp(node); | 634 VisitFloat64Cmp(node); |
633 if (lower()) node->set_op(Float64Op(node)); | 635 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node)); |
634 } | 636 } |
635 break; | 637 break; |
636 } | 638 } |
637 case IrOpcode::kNumberAdd: | 639 case IrOpcode::kNumberAdd: |
638 case IrOpcode::kNumberSubtract: { | 640 case IrOpcode::kNumberSubtract: { |
639 // Add and subtract reduce to Int32Add/Sub if the inputs | 641 // Add and subtract reduce to Int32Add/Sub if the inputs |
640 // are already integers and all uses are truncating. | 642 // are already integers and all uses are truncating. |
641 if (CanLowerToInt32Binop(node, use)) { | 643 if (CanLowerToInt32Binop(node, use)) { |
642 // => signed Int32Add/Sub | 644 // => signed Int32Add/Sub |
643 VisitInt32Binop(node); | 645 VisitInt32Binop(node); |
644 if (lower()) node->set_op(Int32Op(node)); | 646 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node)); |
645 } else if (CanLowerToInt32AdditiveBinop(node, use)) { | 647 } else if (CanLowerToInt32AdditiveBinop(node, use)) { |
646 // => signed Int32Add/Sub, truncating inputs | 648 // => signed Int32Add/Sub, truncating inputs |
647 ProcessTruncateWord32Input(node, 0, kTypeInt32); | 649 ProcessTruncateWord32Input(node, 0, kTypeInt32); |
648 ProcessTruncateWord32Input(node, 1, kTypeInt32); | 650 ProcessTruncateWord32Input(node, 1, kTypeInt32); |
649 SetOutput(node, kMachInt32); | 651 SetOutput(node, kMachInt32); |
650 if (lower()) node->set_op(Int32Op(node)); | 652 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node)); |
651 } else if (CanLowerToUint32Binop(node, use)) { | 653 } else if (CanLowerToUint32Binop(node, use)) { |
652 // => unsigned Int32Add/Sub | 654 // => unsigned Int32Add/Sub |
653 VisitUint32Binop(node); | 655 VisitUint32Binop(node); |
654 if (lower()) node->set_op(Uint32Op(node)); | 656 if (lower()) NodeProperties::ChangeOp(node, Uint32Op(node)); |
655 } else if (CanLowerToUint32AdditiveBinop(node, use)) { | 657 } else if (CanLowerToUint32AdditiveBinop(node, use)) { |
656 // => signed Int32Add/Sub, truncating inputs | 658 // => signed Int32Add/Sub, truncating inputs |
657 ProcessTruncateWord32Input(node, 0, kTypeUint32); | 659 ProcessTruncateWord32Input(node, 0, kTypeUint32); |
658 ProcessTruncateWord32Input(node, 1, kTypeUint32); | 660 ProcessTruncateWord32Input(node, 1, kTypeUint32); |
659 SetOutput(node, kMachUint32); | 661 SetOutput(node, kMachUint32); |
660 if (lower()) node->set_op(Uint32Op(node)); | 662 if (lower()) NodeProperties::ChangeOp(node, Uint32Op(node)); |
661 } else { | 663 } else { |
662 // => Float64Add/Sub | 664 // => Float64Add/Sub |
663 VisitFloat64Binop(node); | 665 VisitFloat64Binop(node); |
664 if (lower()) node->set_op(Float64Op(node)); | 666 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node)); |
665 } | 667 } |
666 break; | 668 break; |
667 } | 669 } |
668 case IrOpcode::kNumberMultiply: { | 670 case IrOpcode::kNumberMultiply: { |
669 NumberMatcher right(node->InputAt(1)); | 671 NumberMatcher right(node->InputAt(1)); |
670 if (right.IsInRange(-1048576, 1048576)) { // must fit double mantissa. | 672 if (right.IsInRange(-1048576, 1048576)) { // must fit double mantissa. |
671 if (CanLowerToInt32Binop(node, use)) { | 673 if (CanLowerToInt32Binop(node, use)) { |
672 // => signed Int32Mul | 674 // => signed Int32Mul |
673 VisitInt32Binop(node); | 675 VisitInt32Binop(node); |
674 if (lower()) node->set_op(Int32Op(node)); | 676 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node)); |
675 break; | 677 break; |
676 } | 678 } |
677 } | 679 } |
678 // => Float64Mul | 680 // => Float64Mul |
679 VisitFloat64Binop(node); | 681 VisitFloat64Binop(node); |
680 if (lower()) node->set_op(Float64Op(node)); | 682 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node)); |
681 break; | 683 break; |
682 } | 684 } |
683 case IrOpcode::kNumberDivide: { | 685 case IrOpcode::kNumberDivide: { |
684 if (CanLowerToInt32Binop(node, use)) { | 686 if (CanLowerToInt32Binop(node, use)) { |
685 // => signed Int32Div | 687 // => signed Int32Div |
686 VisitInt32Binop(node); | 688 VisitInt32Binop(node); |
687 if (lower()) DeferReplacement(node, lowering->Int32Div(node)); | 689 if (lower()) DeferReplacement(node, lowering->Int32Div(node)); |
688 break; | 690 break; |
689 } | 691 } |
690 if (BothInputsAre(node, Type::Unsigned32()) && !CanObserveNaN(use)) { | 692 if (BothInputsAre(node, Type::Unsigned32()) && !CanObserveNaN(use)) { |
691 // => unsigned Uint32Div | 693 // => unsigned Uint32Div |
692 VisitUint32Binop(node); | 694 VisitUint32Binop(node); |
693 if (lower()) DeferReplacement(node, lowering->Uint32Div(node)); | 695 if (lower()) DeferReplacement(node, lowering->Uint32Div(node)); |
694 break; | 696 break; |
695 } | 697 } |
696 // => Float64Div | 698 // => Float64Div |
697 VisitFloat64Binop(node); | 699 VisitFloat64Binop(node); |
698 if (lower()) node->set_op(Float64Op(node)); | 700 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node)); |
699 break; | 701 break; |
700 } | 702 } |
701 case IrOpcode::kNumberModulus: { | 703 case IrOpcode::kNumberModulus: { |
702 if (CanLowerToInt32Binop(node, use)) { | 704 if (CanLowerToInt32Binop(node, use)) { |
703 // => signed Int32Mod | 705 // => signed Int32Mod |
704 VisitInt32Binop(node); | 706 VisitInt32Binop(node); |
705 if (lower()) DeferReplacement(node, lowering->Int32Mod(node)); | 707 if (lower()) DeferReplacement(node, lowering->Int32Mod(node)); |
706 break; | 708 break; |
707 } | 709 } |
708 if (BothInputsAre(node, Type::Unsigned32()) && !CanObserveNaN(use)) { | 710 if (BothInputsAre(node, Type::Unsigned32()) && !CanObserveNaN(use)) { |
709 // => unsigned Uint32Mod | 711 // => unsigned Uint32Mod |
710 VisitUint32Binop(node); | 712 VisitUint32Binop(node); |
711 if (lower()) DeferReplacement(node, lowering->Uint32Mod(node)); | 713 if (lower()) DeferReplacement(node, lowering->Uint32Mod(node)); |
712 break; | 714 break; |
713 } | 715 } |
714 // => Float64Mod | 716 // => Float64Mod |
715 VisitFloat64Binop(node); | 717 VisitFloat64Binop(node); |
716 if (lower()) node->set_op(Float64Op(node)); | 718 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node)); |
717 break; | 719 break; |
718 } | 720 } |
719 case IrOpcode::kNumberShiftLeft: { | 721 case IrOpcode::kNumberShiftLeft: { |
720 VisitBinop(node, kMachInt32, kMachUint32, kMachInt32); | 722 VisitBinop(node, kMachInt32, kMachUint32, kMachInt32); |
721 if (lower()) lowering->DoShift(node, lowering->machine()->Word32Shl()); | 723 if (lower()) lowering->DoShift(node, lowering->machine()->Word32Shl()); |
722 break; | 724 break; |
723 } | 725 } |
724 case IrOpcode::kNumberShiftRight: { | 726 case IrOpcode::kNumberShiftRight: { |
725 VisitBinop(node, kMachInt32, kMachUint32, kMachInt32); | 727 VisitBinop(node, kMachInt32, kMachUint32, kMachInt32); |
726 if (lower()) lowering->DoShift(node, lowering->machine()->Word32Sar()); | 728 if (lower()) lowering->DoShift(node, lowering->machine()->Word32Sar()); |
(...skipping 21 matching lines...) Expand all Loading... |
748 } else if ((in & kTypeMask) == kTypeInt32 || | 750 } else if ((in & kTypeMask) == kTypeInt32 || |
749 (in & kRepMask) == kRepWord32) { | 751 (in & kRepMask) == kRepWord32) { |
750 // Just change representation if necessary. | 752 // Just change representation if necessary. |
751 VisitUnop(node, kTypeInt32 | kRepWord32, kTypeInt32 | kRepWord32); | 753 VisitUnop(node, kTypeInt32 | kRepWord32, kTypeInt32 | kRepWord32); |
752 if (lower()) DeferReplacement(node, node->InputAt(0)); | 754 if (lower()) DeferReplacement(node, node->InputAt(0)); |
753 } else { | 755 } else { |
754 // Require the input in float64 format and perform truncation. | 756 // Require the input in float64 format and perform truncation. |
755 // TODO(turbofan): avoid a truncation with a smi check. | 757 // TODO(turbofan): avoid a truncation with a smi check. |
756 VisitUnop(node, kTypeInt32 | kRepFloat64, kTypeInt32 | kRepWord32); | 758 VisitUnop(node, kTypeInt32 | kRepFloat64, kTypeInt32 | kRepWord32); |
757 if (lower()) { | 759 if (lower()) { |
758 node->set_op(lowering->machine()->TruncateFloat64ToInt32( | 760 NodeProperties::ChangeOp( |
759 TruncationMode::kJavaScript)); | 761 node, lowering->machine()->TruncateFloat64ToInt32( |
| 762 TruncationMode::kJavaScript)); |
760 } | 763 } |
761 } | 764 } |
762 break; | 765 break; |
763 } | 766 } |
764 case IrOpcode::kNumberToUint32: { | 767 case IrOpcode::kNumberToUint32: { |
765 MachineTypeUnion use_rep = use & kRepMask; | 768 MachineTypeUnion use_rep = use & kRepMask; |
766 Node* input = node->InputAt(0); | 769 Node* input = node->InputAt(0); |
767 Type* in_upper = NodeProperties::GetType(input); | 770 Type* in_upper = NodeProperties::GetType(input); |
768 MachineTypeUnion in = GetInfo(input)->output; | 771 MachineTypeUnion in = GetInfo(input)->output; |
769 if (in_upper->Is(Type::Unsigned32())) { | 772 if (in_upper->Is(Type::Unsigned32())) { |
770 // If the input has type uint32, pass through representation. | 773 // If the input has type uint32, pass through representation. |
771 VisitUnop(node, kTypeUint32 | use_rep, kTypeUint32 | use_rep); | 774 VisitUnop(node, kTypeUint32 | use_rep, kTypeUint32 | use_rep); |
772 if (lower()) DeferReplacement(node, node->InputAt(0)); | 775 if (lower()) DeferReplacement(node, node->InputAt(0)); |
773 } else if ((in & kTypeMask) == kTypeInt32 || | 776 } else if ((in & kTypeMask) == kTypeInt32 || |
774 in_upper->Is(Type::Signed32())) { | 777 in_upper->Is(Type::Signed32())) { |
775 // Just change representation if necessary. | 778 // Just change representation if necessary. |
776 VisitUnop(node, kTypeInt32 | kRepWord32, kTypeUint32 | kRepWord32); | 779 VisitUnop(node, kTypeInt32 | kRepWord32, kTypeUint32 | kRepWord32); |
777 if (lower()) DeferReplacement(node, node->InputAt(0)); | 780 if (lower()) DeferReplacement(node, node->InputAt(0)); |
778 } else if ((in & kTypeMask) == kTypeUint32 || | 781 } else if ((in & kTypeMask) == kTypeUint32 || |
779 (in & kRepMask) == kRepWord32) { | 782 (in & kRepMask) == kRepWord32) { |
780 // Just change representation if necessary. | 783 // Just change representation if necessary. |
781 VisitUnop(node, kTypeUint32 | kRepWord32, kTypeUint32 | kRepWord32); | 784 VisitUnop(node, kTypeUint32 | kRepWord32, kTypeUint32 | kRepWord32); |
782 if (lower()) DeferReplacement(node, node->InputAt(0)); | 785 if (lower()) DeferReplacement(node, node->InputAt(0)); |
783 } else { | 786 } else { |
784 // Require the input in float64 format and perform truncation. | 787 // Require the input in float64 format and perform truncation. |
785 // TODO(turbofan): avoid a truncation with a smi check. | 788 // TODO(turbofan): avoid a truncation with a smi check. |
786 VisitUnop(node, kTypeUint32 | kRepFloat64, kTypeUint32 | kRepWord32); | 789 VisitUnop(node, kTypeUint32 | kRepFloat64, kTypeUint32 | kRepWord32); |
787 if (lower()) { | 790 if (lower()) { |
788 node->set_op(lowering->machine()->TruncateFloat64ToInt32( | 791 NodeProperties::ChangeOp( |
789 TruncationMode::kJavaScript)); | 792 node, lowering->machine()->TruncateFloat64ToInt32( |
| 793 TruncationMode::kJavaScript)); |
790 } | 794 } |
791 } | 795 } |
792 break; | 796 break; |
793 } | 797 } |
794 case IrOpcode::kPlainPrimitiveToNumber: { | 798 case IrOpcode::kPlainPrimitiveToNumber: { |
795 VisitUnop(node, kMachAnyTagged, kTypeNumber | kRepTagged); | 799 VisitUnop(node, kMachAnyTagged, kTypeNumber | kRepTagged); |
796 if (lower()) { | 800 if (lower()) { |
797 // PlainPrimitiveToNumber(x) => Call(ToNumberStub, x, no-context) | 801 // PlainPrimitiveToNumber(x) => Call(ToNumberStub, x, no-context) |
798 Operator::Properties properties = node->op()->properties(); | 802 Operator::Properties properties = node->op()->properties(); |
799 Callable callable = CodeFactory::ToNumber(jsgraph_->isolate()); | 803 Callable callable = CodeFactory::ToNumber(jsgraph_->isolate()); |
800 CallDescriptor::Flags flags = CallDescriptor::kNoFlags; | 804 CallDescriptor::Flags flags = CallDescriptor::kNoFlags; |
801 CallDescriptor* desc = Linkage::GetStubCallDescriptor( | 805 CallDescriptor* desc = Linkage::GetStubCallDescriptor( |
802 jsgraph_->isolate(), jsgraph_->zone(), callable.descriptor(), 0, | 806 jsgraph_->isolate(), jsgraph_->zone(), callable.descriptor(), 0, |
803 flags, properties); | 807 flags, properties); |
804 node->set_op(jsgraph_->common()->Call(desc)); | |
805 node->InsertInput(jsgraph_->zone(), 0, | 808 node->InsertInput(jsgraph_->zone(), 0, |
806 jsgraph_->HeapConstant(callable.code())); | 809 jsgraph_->HeapConstant(callable.code())); |
807 node->AppendInput(jsgraph_->zone(), jsgraph_->NoContextConstant()); | 810 node->AppendInput(jsgraph_->zone(), jsgraph_->NoContextConstant()); |
| 811 NodeProperties::ChangeOp(node, jsgraph_->common()->Call(desc)); |
808 } | 812 } |
809 break; | 813 break; |
810 } | 814 } |
811 case IrOpcode::kReferenceEqual: { | 815 case IrOpcode::kReferenceEqual: { |
812 VisitBinop(node, kMachAnyTagged, kRepBit); | 816 VisitBinop(node, kMachAnyTagged, kRepBit); |
813 if (lower()) node->set_op(lowering->machine()->WordEqual()); | 817 if (lower()) { |
| 818 NodeProperties::ChangeOp(node, lowering->machine()->WordEqual()); |
| 819 } |
814 break; | 820 break; |
815 } | 821 } |
816 case IrOpcode::kStringEqual: { | 822 case IrOpcode::kStringEqual: { |
817 VisitBinop(node, kMachAnyTagged, kRepBit); | 823 VisitBinop(node, kMachAnyTagged, kRepBit); |
818 if (lower()) lowering->DoStringEqual(node); | 824 if (lower()) lowering->DoStringEqual(node); |
819 break; | 825 break; |
820 } | 826 } |
821 case IrOpcode::kStringLessThan: { | 827 case IrOpcode::kStringLessThan: { |
822 VisitBinop(node, kMachAnyTagged, kRepBit); | 828 VisitBinop(node, kMachAnyTagged, kRepBit); |
823 if (lower()) lowering->DoStringLessThan(node); | 829 if (lower()) lowering->DoStringLessThan(node); |
(...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1203 | 1209 |
1204 } // namespace | 1210 } // namespace |
1205 | 1211 |
1206 | 1212 |
1207 void SimplifiedLowering::DoAllocate(Node* node) { | 1213 void SimplifiedLowering::DoAllocate(Node* node) { |
1208 PretenureFlag pretenure = OpParameter<PretenureFlag>(node->op()); | 1214 PretenureFlag pretenure = OpParameter<PretenureFlag>(node->op()); |
1209 AllocationSpace space = pretenure == TENURED ? OLD_SPACE : NEW_SPACE; | 1215 AllocationSpace space = pretenure == TENURED ? OLD_SPACE : NEW_SPACE; |
1210 Runtime::FunctionId f = Runtime::kAllocateInTargetSpace; | 1216 Runtime::FunctionId f = Runtime::kAllocateInTargetSpace; |
1211 Operator::Properties props = node->op()->properties(); | 1217 Operator::Properties props = node->op()->properties(); |
1212 CallDescriptor* desc = Linkage::GetRuntimeCallDescriptor(zone(), f, 2, props); | 1218 CallDescriptor* desc = Linkage::GetRuntimeCallDescriptor(zone(), f, 2, props); |
1213 node->set_op(common()->Call(desc)); | |
1214 ExternalReference ref(f, jsgraph()->isolate()); | 1219 ExternalReference ref(f, jsgraph()->isolate()); |
1215 int32_t flags = AllocateTargetSpace::encode(space); | 1220 int32_t flags = AllocateTargetSpace::encode(space); |
1216 node->InsertInput(graph()->zone(), 0, jsgraph()->CEntryStubConstant(1)); | 1221 node->InsertInput(graph()->zone(), 0, jsgraph()->CEntryStubConstant(1)); |
1217 node->InsertInput(graph()->zone(), 2, jsgraph()->SmiConstant(flags)); | 1222 node->InsertInput(graph()->zone(), 2, jsgraph()->SmiConstant(flags)); |
1218 node->InsertInput(graph()->zone(), 3, jsgraph()->ExternalConstant(ref)); | 1223 node->InsertInput(graph()->zone(), 3, jsgraph()->ExternalConstant(ref)); |
1219 node->InsertInput(graph()->zone(), 4, jsgraph()->Int32Constant(2)); | 1224 node->InsertInput(graph()->zone(), 4, jsgraph()->Int32Constant(2)); |
1220 node->InsertInput(graph()->zone(), 5, jsgraph()->NoContextConstant()); | 1225 node->InsertInput(graph()->zone(), 5, jsgraph()->NoContextConstant()); |
| 1226 NodeProperties::ChangeOp(node, common()->Call(desc)); |
1221 } | 1227 } |
1222 | 1228 |
1223 | 1229 |
1224 void SimplifiedLowering::DoLoadField(Node* node) { | 1230 void SimplifiedLowering::DoLoadField(Node* node) { |
1225 const FieldAccess& access = FieldAccessOf(node->op()); | 1231 const FieldAccess& access = FieldAccessOf(node->op()); |
1226 node->set_op(machine()->Load(access.machine_type)); | |
1227 Node* offset = jsgraph()->IntPtrConstant(access.offset - access.tag()); | 1232 Node* offset = jsgraph()->IntPtrConstant(access.offset - access.tag()); |
1228 node->InsertInput(graph()->zone(), 1, offset); | 1233 node->InsertInput(graph()->zone(), 1, offset); |
| 1234 NodeProperties::ChangeOp(node, machine()->Load(access.machine_type)); |
1229 } | 1235 } |
1230 | 1236 |
1231 | 1237 |
1232 void SimplifiedLowering::DoStoreField(Node* node) { | 1238 void SimplifiedLowering::DoStoreField(Node* node) { |
1233 const FieldAccess& access = FieldAccessOf(node->op()); | 1239 const FieldAccess& access = FieldAccessOf(node->op()); |
1234 Type* type = NodeProperties::GetType(node->InputAt(1)); | 1240 Type* type = NodeProperties::GetType(node->InputAt(1)); |
1235 WriteBarrierKind kind = | 1241 WriteBarrierKind kind = |
1236 ComputeWriteBarrierKind(access.base_is_tagged, access.machine_type, type); | 1242 ComputeWriteBarrierKind(access.base_is_tagged, access.machine_type, type); |
1237 node->set_op( | |
1238 machine()->Store(StoreRepresentation(access.machine_type, kind))); | |
1239 Node* offset = jsgraph()->IntPtrConstant(access.offset - access.tag()); | 1243 Node* offset = jsgraph()->IntPtrConstant(access.offset - access.tag()); |
1240 node->InsertInput(graph()->zone(), 1, offset); | 1244 node->InsertInput(graph()->zone(), 1, offset); |
| 1245 NodeProperties::ChangeOp( |
| 1246 node, machine()->Store(StoreRepresentation(access.machine_type, kind))); |
1241 } | 1247 } |
1242 | 1248 |
1243 | 1249 |
1244 Node* SimplifiedLowering::ComputeIndex(const ElementAccess& access, | 1250 Node* SimplifiedLowering::ComputeIndex(const ElementAccess& access, |
1245 Node* const key) { | 1251 Node* const key) { |
1246 Node* index = key; | 1252 Node* index = key; |
1247 const int element_size_shift = ElementSizeLog2Of(access.machine_type); | 1253 const int element_size_shift = ElementSizeLog2Of(access.machine_type); |
1248 if (element_size_shift) { | 1254 if (element_size_shift) { |
1249 index = graph()->NewNode(machine()->Word32Shl(), index, | 1255 index = graph()->NewNode(machine()->Word32Shl(), index, |
1250 jsgraph()->Int32Constant(element_size_shift)); | 1256 jsgraph()->Int32Constant(element_size_shift)); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1304 vfalse = jsgraph()->Int32Constant(0); | 1310 vfalse = jsgraph()->Int32Constant(0); |
1305 } | 1311 } |
1306 | 1312 |
1307 Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false); | 1313 Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false); |
1308 Node* ephi = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, merge); | 1314 Node* ephi = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, merge); |
1309 | 1315 |
1310 // Replace effect uses of {node} with the {ephi}. | 1316 // Replace effect uses of {node} with the {ephi}. |
1311 NodeProperties::ReplaceUses(node, node, ephi); | 1317 NodeProperties::ReplaceUses(node, node, ephi); |
1312 | 1318 |
1313 // Turn the {node} into a Phi. | 1319 // Turn the {node} into a Phi. |
1314 node->set_op(common()->Phi(output_type, 2)); | |
1315 node->ReplaceInput(0, vtrue); | 1320 node->ReplaceInput(0, vtrue); |
1316 node->ReplaceInput(1, vfalse); | 1321 node->ReplaceInput(1, vfalse); |
1317 node->ReplaceInput(2, merge); | 1322 node->ReplaceInput(2, merge); |
1318 node->TrimInputCount(3); | 1323 node->TrimInputCount(3); |
| 1324 NodeProperties::ChangeOp(node, common()->Phi(output_type, 2)); |
1319 } else { | 1325 } else { |
1320 node->set_op(machine()->CheckedLoad(type)); | 1326 NodeProperties::ChangeOp(node, machine()->CheckedLoad(type)); |
1321 } | 1327 } |
1322 } | 1328 } |
1323 | 1329 |
1324 | 1330 |
1325 void SimplifiedLowering::DoStoreBuffer(Node* node) { | 1331 void SimplifiedLowering::DoStoreBuffer(Node* node) { |
1326 DCHECK_EQ(IrOpcode::kStoreBuffer, node->opcode()); | 1332 DCHECK_EQ(IrOpcode::kStoreBuffer, node->opcode()); |
1327 MachineType const type = BufferAccessOf(node->op()).machine_type(); | 1333 MachineType const type = BufferAccessOf(node->op()).machine_type(); |
1328 node->set_op(machine()->CheckedStore(type)); | 1334 NodeProperties::ChangeOp(node, machine()->CheckedStore(type)); |
1329 } | 1335 } |
1330 | 1336 |
1331 | 1337 |
1332 void SimplifiedLowering::DoLoadElement(Node* node) { | 1338 void SimplifiedLowering::DoLoadElement(Node* node) { |
1333 const ElementAccess& access = ElementAccessOf(node->op()); | 1339 const ElementAccess& access = ElementAccessOf(node->op()); |
1334 node->set_op(machine()->Load(access.machine_type)); | |
1335 node->ReplaceInput(1, ComputeIndex(access, node->InputAt(1))); | 1340 node->ReplaceInput(1, ComputeIndex(access, node->InputAt(1))); |
| 1341 NodeProperties::ChangeOp(node, machine()->Load(access.machine_type)); |
1336 } | 1342 } |
1337 | 1343 |
1338 | 1344 |
1339 void SimplifiedLowering::DoStoreElement(Node* node) { | 1345 void SimplifiedLowering::DoStoreElement(Node* node) { |
1340 const ElementAccess& access = ElementAccessOf(node->op()); | 1346 const ElementAccess& access = ElementAccessOf(node->op()); |
1341 Type* type = NodeProperties::GetType(node->InputAt(2)); | 1347 Type* type = NodeProperties::GetType(node->InputAt(2)); |
1342 node->set_op(machine()->Store( | |
1343 StoreRepresentation(access.machine_type, | |
1344 ComputeWriteBarrierKind(access.base_is_tagged, | |
1345 access.machine_type, type)))); | |
1346 node->ReplaceInput(1, ComputeIndex(access, node->InputAt(1))); | 1348 node->ReplaceInput(1, ComputeIndex(access, node->InputAt(1))); |
| 1349 NodeProperties::ChangeOp( |
| 1350 node, machine()->Store(StoreRepresentation( |
| 1351 access.machine_type, |
| 1352 ComputeWriteBarrierKind(access.base_is_tagged, |
| 1353 access.machine_type, type)))); |
1347 } | 1354 } |
1348 | 1355 |
1349 | 1356 |
1350 Node* SimplifiedLowering::StringComparison(Node* node) { | 1357 Node* SimplifiedLowering::StringComparison(Node* node) { |
1351 Operator::Properties properties = node->op()->properties(); | 1358 Operator::Properties properties = node->op()->properties(); |
1352 Callable callable = CodeFactory::StringCompare(isolate()); | 1359 Callable callable = CodeFactory::StringCompare(isolate()); |
1353 CallDescriptor::Flags flags = CallDescriptor::kNoFlags; | 1360 CallDescriptor::Flags flags = CallDescriptor::kNoFlags; |
1354 CallDescriptor* desc = Linkage::GetStubCallDescriptor( | 1361 CallDescriptor* desc = Linkage::GetStubCallDescriptor( |
1355 isolate(), zone(), callable.descriptor(), 0, flags, properties); | 1362 isolate(), zone(), callable.descriptor(), 0, flags, properties); |
1356 return graph()->NewNode( | 1363 return graph()->NewNode( |
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1603 | 1610 |
1604 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0); | 1611 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0); |
1605 Node* false0 = zero; | 1612 Node* false0 = zero; |
1606 | 1613 |
1607 Node* merge0 = graph()->NewNode(merge_op, if_true0, if_false0); | 1614 Node* merge0 = graph()->NewNode(merge_op, if_true0, if_false0); |
1608 return graph()->NewNode(phi_op, true0, false0, merge0); | 1615 return graph()->NewNode(phi_op, true0, false0, merge0); |
1609 } | 1616 } |
1610 | 1617 |
1611 | 1618 |
1612 void SimplifiedLowering::DoShift(Node* node, Operator const* op) { | 1619 void SimplifiedLowering::DoShift(Node* node, Operator const* op) { |
1613 node->set_op(op); | |
1614 Node* const rhs = NodeProperties::GetValueInput(node, 1); | 1620 Node* const rhs = NodeProperties::GetValueInput(node, 1); |
1615 Type* const rhs_type = NodeProperties::GetType(rhs); | 1621 Type* const rhs_type = NodeProperties::GetType(rhs); |
1616 if (!rhs_type->Is(zero_thirtyone_range_)) { | 1622 if (!rhs_type->Is(zero_thirtyone_range_)) { |
1617 node->ReplaceInput(1, graph()->NewNode(machine()->Word32And(), rhs, | 1623 node->ReplaceInput(1, graph()->NewNode(machine()->Word32And(), rhs, |
1618 jsgraph()->Int32Constant(0x1f))); | 1624 jsgraph()->Int32Constant(0x1f))); |
1619 } | 1625 } |
| 1626 NodeProperties::ChangeOp(node, op); |
1620 } | 1627 } |
1621 | 1628 |
1622 | 1629 |
1623 void SimplifiedLowering::DoStringEqual(Node* node) { | 1630 void SimplifiedLowering::DoStringEqual(Node* node) { |
1624 node->set_op(machine()->WordEqual()); | |
1625 node->ReplaceInput(0, StringComparison(node)); | 1631 node->ReplaceInput(0, StringComparison(node)); |
1626 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); | 1632 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); |
| 1633 NodeProperties::ChangeOp(node, machine()->WordEqual()); |
1627 } | 1634 } |
1628 | 1635 |
1629 | 1636 |
1630 void SimplifiedLowering::DoStringLessThan(Node* node) { | 1637 void SimplifiedLowering::DoStringLessThan(Node* node) { |
1631 node->set_op(machine()->IntLessThan()); | |
1632 node->ReplaceInput(0, StringComparison(node)); | 1638 node->ReplaceInput(0, StringComparison(node)); |
1633 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); | 1639 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); |
| 1640 NodeProperties::ChangeOp(node, machine()->IntLessThan()); |
1634 } | 1641 } |
1635 | 1642 |
1636 | 1643 |
1637 void SimplifiedLowering::DoStringLessThanOrEqual(Node* node) { | 1644 void SimplifiedLowering::DoStringLessThanOrEqual(Node* node) { |
1638 node->set_op(machine()->IntLessThanOrEqual()); | |
1639 node->ReplaceInput(0, StringComparison(node)); | 1645 node->ReplaceInput(0, StringComparison(node)); |
1640 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); | 1646 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); |
| 1647 NodeProperties::ChangeOp(node, machine()->IntLessThanOrEqual()); |
1641 } | 1648 } |
1642 | 1649 |
1643 } // namespace compiler | 1650 } // namespace compiler |
1644 } // namespace internal | 1651 } // namespace internal |
1645 } // namespace v8 | 1652 } // namespace v8 |
OLD | NEW |