Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/compiler/effect-control-linearizer.cc

Issue 2571903004: [turbofan] Introduce graph assembler to build effect-control-linearizer sub-graphs. (Closed)
Patch Set: Fixes Created 3 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 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/effect-control-linearizer.h" 5 #include "src/compiler/effect-control-linearizer.h"
6 6
7 #include "src/code-factory.h" 7 #include "src/code-factory.h"
8 #include "src/compiler/access-builder.h" 8 #include "src/compiler/access-builder.h"
9 #include "src/compiler/compiler-source-position-table.h" 9 #include "src/compiler/compiler-source-position-table.h"
10 #include "src/compiler/graph-assembler.h"
10 #include "src/compiler/js-graph.h" 11 #include "src/compiler/js-graph.h"
11 #include "src/compiler/linkage.h" 12 #include "src/compiler/linkage.h"
12 #include "src/compiler/node-matchers.h" 13 #include "src/compiler/node-matchers.h"
13 #include "src/compiler/node-properties.h" 14 #include "src/compiler/node-properties.h"
14 #include "src/compiler/node.h" 15 #include "src/compiler/node.h"
15 #include "src/compiler/schedule.h" 16 #include "src/compiler/schedule.h"
16 17
17 namespace v8 { 18 namespace v8 {
18 namespace internal { 19 namespace internal {
19 namespace compiler { 20 namespace compiler {
20 21
21 EffectControlLinearizer::EffectControlLinearizer( 22 EffectControlLinearizer::EffectControlLinearizer(
22 JSGraph* js_graph, Schedule* schedule, Zone* temp_zone, 23 JSGraph* js_graph, Schedule* schedule, Zone* temp_zone,
23 SourcePositionTable* source_positions) 24 SourcePositionTable* source_positions)
24 : js_graph_(js_graph), 25 : js_graph_(js_graph),
25 schedule_(schedule), 26 schedule_(schedule),
26 temp_zone_(temp_zone), 27 temp_zone_(temp_zone),
27 source_positions_(source_positions) {} 28 source_positions_(source_positions),
29 graph_assembler_(js_graph, nullptr, nullptr, temp_zone) {}
28 30
29 Graph* EffectControlLinearizer::graph() const { return js_graph_->graph(); } 31 Graph* EffectControlLinearizer::graph() const { return js_graph_->graph(); }
30 CommonOperatorBuilder* EffectControlLinearizer::common() const { 32 CommonOperatorBuilder* EffectControlLinearizer::common() const {
31 return js_graph_->common(); 33 return js_graph_->common();
32 } 34 }
33 SimplifiedOperatorBuilder* EffectControlLinearizer::simplified() const { 35 SimplifiedOperatorBuilder* EffectControlLinearizer::simplified() const {
34 return js_graph_->simplified(); 36 return js_graph_->simplified();
35 } 37 }
36 MachineOperatorBuilder* EffectControlLinearizer::machine() const { 38 MachineOperatorBuilder* EffectControlLinearizer::machine() const {
37 return js_graph_->machine(); 39 return js_graph_->machine();
(...skipping 551 matching lines...) Expand 10 before | Expand all | Expand 10 after
589 // Schedule the call's IfSuccess node (if there is no exception use). 591 // Schedule the call's IfSuccess node (if there is no exception use).
590 TryScheduleCallIfSuccess(node, control); 592 TryScheduleCallIfSuccess(node, control);
591 } 593 }
592 } 594 }
593 } 595 }
594 596
595 bool EffectControlLinearizer::TryWireInStateEffect(Node* node, 597 bool EffectControlLinearizer::TryWireInStateEffect(Node* node,
596 Node* frame_state, 598 Node* frame_state,
597 Node** effect, 599 Node** effect,
598 Node** control) { 600 Node** control) {
599 ValueEffectControl state(nullptr, nullptr, nullptr); 601 gasm()->Reset(*effect, *control);
602 Node* result = nullptr;
600 switch (node->opcode()) { 603 switch (node->opcode()) {
601 case IrOpcode::kChangeBitToTagged: 604 case IrOpcode::kChangeBitToTagged:
602 state = LowerChangeBitToTagged(node, *effect, *control); 605 result = LowerChangeBitToTagged(node);
603 break; 606 break;
604 case IrOpcode::kChangeInt31ToTaggedSigned: 607 case IrOpcode::kChangeInt31ToTaggedSigned:
605 state = LowerChangeInt31ToTaggedSigned(node, *effect, *control); 608 result = LowerChangeInt31ToTaggedSigned(node);
606 break; 609 break;
607 case IrOpcode::kChangeInt32ToTagged: 610 case IrOpcode::kChangeInt32ToTagged:
608 state = LowerChangeInt32ToTagged(node, *effect, *control); 611 result = LowerChangeInt32ToTagged(node);
609 break; 612 break;
610 case IrOpcode::kChangeUint32ToTagged: 613 case IrOpcode::kChangeUint32ToTagged:
611 state = LowerChangeUint32ToTagged(node, *effect, *control); 614 result = LowerChangeUint32ToTagged(node);
612 break; 615 break;
613 case IrOpcode::kChangeFloat64ToTagged: 616 case IrOpcode::kChangeFloat64ToTagged:
614 state = LowerChangeFloat64ToTagged(node, *effect, *control); 617 result = LowerChangeFloat64ToTagged(node);
615 break; 618 break;
616 case IrOpcode::kChangeFloat64ToTaggedPointer: 619 case IrOpcode::kChangeFloat64ToTaggedPointer:
617 state = LowerChangeFloat64ToTaggedPointer(node, *effect, *control); 620 result = LowerChangeFloat64ToTaggedPointer(node);
618 break; 621 break;
619 case IrOpcode::kChangeTaggedSignedToInt32: 622 case IrOpcode::kChangeTaggedSignedToInt32:
620 state = LowerChangeTaggedSignedToInt32(node, *effect, *control); 623 result = LowerChangeTaggedSignedToInt32(node);
621 break; 624 break;
622 case IrOpcode::kChangeTaggedToBit: 625 case IrOpcode::kChangeTaggedToBit:
623 state = LowerChangeTaggedToBit(node, *effect, *control); 626 result = LowerChangeTaggedToBit(node);
624 break; 627 break;
625 case IrOpcode::kChangeTaggedToInt32: 628 case IrOpcode::kChangeTaggedToInt32:
626 state = LowerChangeTaggedToInt32(node, *effect, *control); 629 result = LowerChangeTaggedToInt32(node);
627 break; 630 break;
628 case IrOpcode::kChangeTaggedToUint32: 631 case IrOpcode::kChangeTaggedToUint32:
629 state = LowerChangeTaggedToUint32(node, *effect, *control); 632 result = LowerChangeTaggedToUint32(node);
630 break; 633 break;
631 case IrOpcode::kChangeTaggedToFloat64: 634 case IrOpcode::kChangeTaggedToFloat64:
632 state = LowerChangeTaggedToFloat64(node, *effect, *control); 635 result = LowerChangeTaggedToFloat64(node);
633 break; 636 break;
634 case IrOpcode::kTruncateTaggedToBit: 637 case IrOpcode::kTruncateTaggedToBit:
635 state = LowerTruncateTaggedToBit(node, *effect, *control); 638 result = LowerTruncateTaggedToBit(node);
636 break; 639 break;
637 case IrOpcode::kTruncateTaggedToFloat64: 640 case IrOpcode::kTruncateTaggedToFloat64:
638 state = LowerTruncateTaggedToFloat64(node, *effect, *control); 641 result = LowerTruncateTaggedToFloat64(node);
639 break; 642 break;
640 case IrOpcode::kCheckBounds: 643 case IrOpcode::kCheckBounds:
641 state = LowerCheckBounds(node, frame_state, *effect, *control); 644 result = LowerCheckBounds(node, frame_state);
642 break; 645 break;
643 case IrOpcode::kCheckMaps: 646 case IrOpcode::kCheckMaps:
644 state = LowerCheckMaps(node, frame_state, *effect, *control); 647 result = LowerCheckMaps(node, frame_state);
645 break; 648 break;
646 case IrOpcode::kCheckNumber: 649 case IrOpcode::kCheckNumber:
647 state = LowerCheckNumber(node, frame_state, *effect, *control); 650 result = LowerCheckNumber(node, frame_state);
648 break; 651 break;
649 case IrOpcode::kCheckString: 652 case IrOpcode::kCheckString:
650 state = LowerCheckString(node, frame_state, *effect, *control); 653 result = LowerCheckString(node, frame_state);
651 break; 654 break;
652 case IrOpcode::kCheckIf: 655 case IrOpcode::kCheckIf:
653 state = LowerCheckIf(node, frame_state, *effect, *control); 656 result = LowerCheckIf(node, frame_state);
654 break; 657 break;
655 case IrOpcode::kCheckedInt32Add: 658 case IrOpcode::kCheckedInt32Add:
656 state = LowerCheckedInt32Add(node, frame_state, *effect, *control); 659 result = LowerCheckedInt32Add(node, frame_state);
657 break; 660 break;
658 case IrOpcode::kCheckedInt32Sub: 661 case IrOpcode::kCheckedInt32Sub:
659 state = LowerCheckedInt32Sub(node, frame_state, *effect, *control); 662 result = LowerCheckedInt32Sub(node, frame_state);
660 break; 663 break;
661 case IrOpcode::kCheckedInt32Div: 664 case IrOpcode::kCheckedInt32Div:
662 state = LowerCheckedInt32Div(node, frame_state, *effect, *control); 665 result = LowerCheckedInt32Div(node, frame_state);
663 break; 666 break;
664 case IrOpcode::kCheckedInt32Mod: 667 case IrOpcode::kCheckedInt32Mod:
665 state = LowerCheckedInt32Mod(node, frame_state, *effect, *control); 668 result = LowerCheckedInt32Mod(node, frame_state);
666 break; 669 break;
667 case IrOpcode::kCheckedUint32Div: 670 case IrOpcode::kCheckedUint32Div:
668 state = LowerCheckedUint32Div(node, frame_state, *effect, *control); 671 result = LowerCheckedUint32Div(node, frame_state);
669 break; 672 break;
670 case IrOpcode::kCheckedUint32Mod: 673 case IrOpcode::kCheckedUint32Mod:
671 state = LowerCheckedUint32Mod(node, frame_state, *effect, *control); 674 result = LowerCheckedUint32Mod(node, frame_state);
672 break; 675 break;
673 case IrOpcode::kCheckedInt32Mul: 676 case IrOpcode::kCheckedInt32Mul:
674 state = LowerCheckedInt32Mul(node, frame_state, *effect, *control); 677 result = LowerCheckedInt32Mul(node, frame_state);
675 break; 678 break;
676 case IrOpcode::kCheckedInt32ToTaggedSigned: 679 case IrOpcode::kCheckedInt32ToTaggedSigned:
677 state = 680 result = LowerCheckedInt32ToTaggedSigned(node, frame_state);
678 LowerCheckedInt32ToTaggedSigned(node, frame_state, *effect, *control);
679 break; 681 break;
680 case IrOpcode::kCheckedUint32ToInt32: 682 case IrOpcode::kCheckedUint32ToInt32:
681 state = LowerCheckedUint32ToInt32(node, frame_state, *effect, *control); 683 result = LowerCheckedUint32ToInt32(node, frame_state);
682 break; 684 break;
683 case IrOpcode::kCheckedUint32ToTaggedSigned: 685 case IrOpcode::kCheckedUint32ToTaggedSigned:
684 state = LowerCheckedUint32ToTaggedSigned(node, frame_state, *effect, 686 result = LowerCheckedUint32ToTaggedSigned(node, frame_state);
685 *control);
686 break; 687 break;
687 case IrOpcode::kCheckedFloat64ToInt32: 688 case IrOpcode::kCheckedFloat64ToInt32:
688 state = LowerCheckedFloat64ToInt32(node, frame_state, *effect, *control); 689 result = LowerCheckedFloat64ToInt32(node, frame_state);
689 break; 690 break;
690 case IrOpcode::kCheckedTaggedSignedToInt32: 691 case IrOpcode::kCheckedTaggedSignedToInt32:
691 state = 692 result = LowerCheckedTaggedSignedToInt32(node, frame_state);
692 LowerCheckedTaggedSignedToInt32(node, frame_state, *effect, *control);
693 break; 693 break;
694 case IrOpcode::kCheckedTaggedToInt32: 694 case IrOpcode::kCheckedTaggedToInt32:
695 state = LowerCheckedTaggedToInt32(node, frame_state, *effect, *control); 695 result = LowerCheckedTaggedToInt32(node, frame_state);
696 break; 696 break;
697 case IrOpcode::kCheckedTaggedToFloat64: 697 case IrOpcode::kCheckedTaggedToFloat64:
698 state = LowerCheckedTaggedToFloat64(node, frame_state, *effect, *control); 698 result = LowerCheckedTaggedToFloat64(node, frame_state);
699 break; 699 break;
700 case IrOpcode::kCheckedTaggedToTaggedSigned: 700 case IrOpcode::kCheckedTaggedToTaggedSigned:
701 state = LowerCheckedTaggedToTaggedSigned(node, frame_state, *effect, 701 result = LowerCheckedTaggedToTaggedSigned(node, frame_state);
702 *control);
703 break; 702 break;
704 case IrOpcode::kCheckedTaggedToTaggedPointer: 703 case IrOpcode::kCheckedTaggedToTaggedPointer:
705 state = LowerCheckedTaggedToTaggedPointer(node, frame_state, *effect, 704 result = LowerCheckedTaggedToTaggedPointer(node, frame_state);
706 *control);
707 break; 705 break;
708 case IrOpcode::kTruncateTaggedToWord32: 706 case IrOpcode::kTruncateTaggedToWord32:
709 state = LowerTruncateTaggedToWord32(node, *effect, *control); 707 result = LowerTruncateTaggedToWord32(node);
710 break; 708 break;
711 case IrOpcode::kCheckedTruncateTaggedToWord32: 709 case IrOpcode::kCheckedTruncateTaggedToWord32:
712 state = LowerCheckedTruncateTaggedToWord32(node, frame_state, *effect, 710 result = LowerCheckedTruncateTaggedToWord32(node, frame_state);
713 *control);
714 break; 711 break;
715 case IrOpcode::kObjectIsCallable: 712 case IrOpcode::kObjectIsCallable:
716 state = LowerObjectIsCallable(node, *effect, *control); 713 result = LowerObjectIsCallable(node);
717 break; 714 break;
718 case IrOpcode::kObjectIsNumber: 715 case IrOpcode::kObjectIsNumber:
719 state = LowerObjectIsNumber(node, *effect, *control); 716 result = LowerObjectIsNumber(node);
720 break; 717 break;
721 case IrOpcode::kObjectIsReceiver: 718 case IrOpcode::kObjectIsReceiver:
722 state = LowerObjectIsReceiver(node, *effect, *control); 719 result = LowerObjectIsReceiver(node);
723 break; 720 break;
724 case IrOpcode::kObjectIsSmi: 721 case IrOpcode::kObjectIsSmi:
725 state = LowerObjectIsSmi(node, *effect, *control); 722 result = LowerObjectIsSmi(node);
726 break; 723 break;
727 case IrOpcode::kObjectIsString: 724 case IrOpcode::kObjectIsString:
728 state = LowerObjectIsString(node, *effect, *control); 725 result = LowerObjectIsString(node);
729 break; 726 break;
730 case IrOpcode::kObjectIsUndetectable: 727 case IrOpcode::kObjectIsUndetectable:
731 state = LowerObjectIsUndetectable(node, *effect, *control); 728 result = LowerObjectIsUndetectable(node);
732 break; 729 break;
733 case IrOpcode::kNewRestParameterElements: 730 case IrOpcode::kNewRestParameterElements:
734 state = LowerNewRestParameterElements(node, *effect, *control); 731 result = LowerNewRestParameterElements(node);
735 break; 732 break;
736 case IrOpcode::kNewUnmappedArgumentsElements: 733 case IrOpcode::kNewUnmappedArgumentsElements:
737 state = LowerNewUnmappedArgumentsElements(node, *effect, *control); 734 result = LowerNewUnmappedArgumentsElements(node);
738 break; 735 break;
739 case IrOpcode::kArrayBufferWasNeutered: 736 case IrOpcode::kArrayBufferWasNeutered:
740 state = LowerArrayBufferWasNeutered(node, *effect, *control); 737 result = LowerArrayBufferWasNeutered(node);
741 break; 738 break;
742 case IrOpcode::kStringFromCharCode: 739 case IrOpcode::kStringFromCharCode:
743 state = LowerStringFromCharCode(node, *effect, *control); 740 result = LowerStringFromCharCode(node);
744 break; 741 break;
745 case IrOpcode::kStringFromCodePoint: 742 case IrOpcode::kStringFromCodePoint:
746 state = LowerStringFromCodePoint(node, *effect, *control); 743 result = LowerStringFromCodePoint(node);
747 break; 744 break;
748 case IrOpcode::kStringCharAt: 745 case IrOpcode::kStringCharAt:
749 state = LowerStringCharAt(node, *effect, *control); 746 result = LowerStringCharAt(node);
750 break; 747 break;
751 case IrOpcode::kStringCharCodeAt: 748 case IrOpcode::kStringCharCodeAt:
752 state = LowerStringCharCodeAt(node, *effect, *control); 749 result = LowerStringCharCodeAt(node);
753 break; 750 break;
754 case IrOpcode::kStringEqual: 751 case IrOpcode::kStringEqual:
755 state = LowerStringEqual(node, *effect, *control); 752 result = LowerStringEqual(node);
756 break; 753 break;
757 case IrOpcode::kStringLessThan: 754 case IrOpcode::kStringLessThan:
758 state = LowerStringLessThan(node, *effect, *control); 755 result = LowerStringLessThan(node);
759 break; 756 break;
760 case IrOpcode::kStringLessThanOrEqual: 757 case IrOpcode::kStringLessThanOrEqual:
761 state = LowerStringLessThanOrEqual(node, *effect, *control); 758 result = LowerStringLessThanOrEqual(node);
762 break; 759 break;
763 case IrOpcode::kCheckFloat64Hole: 760 case IrOpcode::kCheckFloat64Hole:
764 state = LowerCheckFloat64Hole(node, frame_state, *effect, *control); 761 result = LowerCheckFloat64Hole(node, frame_state);
765 break; 762 break;
766 case IrOpcode::kCheckTaggedHole: 763 case IrOpcode::kCheckTaggedHole:
767 state = LowerCheckTaggedHole(node, frame_state, *effect, *control); 764 result = LowerCheckTaggedHole(node, frame_state);
768 break; 765 break;
769 case IrOpcode::kConvertTaggedHoleToUndefined: 766 case IrOpcode::kConvertTaggedHoleToUndefined:
770 state = LowerConvertTaggedHoleToUndefined(node, *effect, *control); 767 result = LowerConvertTaggedHoleToUndefined(node);
771 break; 768 break;
772 case IrOpcode::kPlainPrimitiveToNumber: 769 case IrOpcode::kPlainPrimitiveToNumber:
773 state = LowerPlainPrimitiveToNumber(node, *effect, *control); 770 result = LowerPlainPrimitiveToNumber(node);
774 break; 771 break;
775 case IrOpcode::kPlainPrimitiveToWord32: 772 case IrOpcode::kPlainPrimitiveToWord32:
776 state = LowerPlainPrimitiveToWord32(node, *effect, *control); 773 result = LowerPlainPrimitiveToWord32(node);
777 break; 774 break;
778 case IrOpcode::kPlainPrimitiveToFloat64: 775 case IrOpcode::kPlainPrimitiveToFloat64:
779 state = LowerPlainPrimitiveToFloat64(node, *effect, *control); 776 result = LowerPlainPrimitiveToFloat64(node);
780 break; 777 break;
781 case IrOpcode::kEnsureWritableFastElements: 778 case IrOpcode::kEnsureWritableFastElements:
782 state = LowerEnsureWritableFastElements(node, *effect, *control); 779 result = LowerEnsureWritableFastElements(node);
783 break; 780 break;
784 case IrOpcode::kMaybeGrowFastElements: 781 case IrOpcode::kMaybeGrowFastElements:
785 state = LowerMaybeGrowFastElements(node, frame_state, *effect, *control); 782 result = LowerMaybeGrowFastElements(node, frame_state);
786 break; 783 break;
787 case IrOpcode::kTransitionElementsKind: 784 case IrOpcode::kTransitionElementsKind:
788 state = LowerTransitionElementsKind(node, *effect, *control); 785 LowerTransitionElementsKind(node);
789 break; 786 break;
790 case IrOpcode::kLoadTypedElement: 787 case IrOpcode::kLoadTypedElement:
791 state = LowerLoadTypedElement(node, *effect, *control); 788 result = LowerLoadTypedElement(node);
792 break; 789 break;
793 case IrOpcode::kStoreTypedElement: 790 case IrOpcode::kStoreTypedElement:
794 state = LowerStoreTypedElement(node, *effect, *control); 791 LowerStoreTypedElement(node);
795 break; 792 break;
796 case IrOpcode::kFloat64RoundUp: 793 case IrOpcode::kFloat64RoundUp:
797 state = LowerFloat64RoundUp(node, *effect, *control); 794 if (!LowerFloat64RoundUp(node).To(&result)) {
795 return false;
796 }
798 break; 797 break;
799 case IrOpcode::kFloat64RoundDown: 798 case IrOpcode::kFloat64RoundDown:
800 state = LowerFloat64RoundDown(node, *effect, *control); 799 if (!LowerFloat64RoundDown(node).To(&result)) {
800 return false;
801 }
801 break; 802 break;
802 case IrOpcode::kFloat64RoundTruncate: 803 case IrOpcode::kFloat64RoundTruncate:
803 state = LowerFloat64RoundTruncate(node, *effect, *control); 804 if (!LowerFloat64RoundTruncate(node).To(&result)) {
805 return false;
806 }
804 break; 807 break;
805 case IrOpcode::kFloat64RoundTiesEven: 808 case IrOpcode::kFloat64RoundTiesEven:
806 state = LowerFloat64RoundTiesEven(node, *effect, *control); 809 if (!LowerFloat64RoundTiesEven(node).To(&result)) {
810 return false;
811 }
807 break; 812 break;
808 default: 813 default:
809 return false; 814 return false;
810 } 815 }
811 NodeProperties::ReplaceUses(node, state.value, state.effect, state.control); 816 *effect = gasm()->ExtractCurrentEffect();
812 *effect = state.effect; 817 *control = gasm()->ExtractCurrentControl();
813 *control = state.control; 818 NodeProperties::ReplaceUses(node, result, *effect, *control);
814 return true; 819 return true;
815 } 820 }
816 821
817 EffectControlLinearizer::ValueEffectControl 822 #define __ gasm()->
818 EffectControlLinearizer::LowerChangeFloat64ToTagged(Node* node, Node* effect, 823
819 Node* control) { 824 Node* EffectControlLinearizer::LowerChangeFloat64ToTagged(Node* node) {
820 Node* value = node->InputAt(0); 825 Node* value = node->InputAt(0);
821 return AllocateHeapNumberWithValue(value, effect, control); 826 return AllocateHeapNumberWithValue(value);
822 } 827 }
823 828
824 EffectControlLinearizer::ValueEffectControl 829 Node* EffectControlLinearizer::LowerChangeFloat64ToTaggedPointer(Node* node) {
825 EffectControlLinearizer::LowerChangeFloat64ToTaggedPointer(Node* node, 830 Node* value = node->InputAt(0);
826 Node* effect, 831 return AllocateHeapNumberWithValue(value);
827 Node* control) { 832 }
828 Node* value = node->InputAt(0); 833
829 return AllocateHeapNumberWithValue(value, effect, control); 834 Node* EffectControlLinearizer::LowerChangeBitToTagged(Node* node) {
830 } 835 Node* value = node->InputAt(0);
831 836
832 EffectControlLinearizer::ValueEffectControl 837 auto if_true = __ MakeLabel<1>();
833 EffectControlLinearizer::LowerChangeBitToTagged(Node* node, Node* effect, 838 auto done = __ MakeLabel<2>(MachineRepresentation::kTagged);
834 Node* control) { 839
835 Node* value = node->InputAt(0); 840 __ GotoIf(value, &if_true);
836 841 __ Goto(&done, __ FalseConstant());
837 Node* branch = graph()->NewNode(common()->Branch(), value, control); 842
838 843 __ Bind(&if_true);
839 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); 844 __ Goto(&done, __ TrueConstant());
840 Node* vtrue = jsgraph()->TrueConstant(); 845
841 846 __ Bind(&done);
842 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); 847 return done.PhiAt(0);
843 Node* vfalse = jsgraph()->FalseConstant(); 848 }
844 849
845 control = graph()->NewNode(common()->Merge(2), if_true, if_false); 850 Node* EffectControlLinearizer::LowerChangeInt31ToTaggedSigned(Node* node) {
846 value = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2), 851 Node* value = node->InputAt(0);
847 vtrue, vfalse, control); 852 return ChangeInt32ToSmi(value);
848 853 }
849 return ValueEffectControl(value, effect, control); 854
850 } 855 Node* EffectControlLinearizer::LowerChangeInt32ToTagged(Node* node) {
851
852 EffectControlLinearizer::ValueEffectControl
853 EffectControlLinearizer::LowerChangeInt31ToTaggedSigned(Node* node,
854 Node* effect,
855 Node* control) {
856 Node* value = node->InputAt(0);
857 value = ChangeInt32ToSmi(value);
858 return ValueEffectControl(value, effect, control);
859 }
860
861 EffectControlLinearizer::ValueEffectControl
862 EffectControlLinearizer::LowerChangeInt32ToTagged(Node* node, Node* effect,
863 Node* control) {
864 Node* value = node->InputAt(0); 856 Node* value = node->InputAt(0);
865 857
866 if (machine()->Is64()) { 858 if (machine()->Is64()) {
867 return ValueEffectControl(ChangeInt32ToSmi(value), effect, control); 859 return ChangeInt32ToSmi(value);
868 } 860 }
869 861
870 Node* add = graph()->NewNode(machine()->Int32AddWithOverflow(), value, value, 862 auto if_overflow = __ MakeDeferredLabel<1>();
871 control); 863 auto done = __ MakeLabel<2>(MachineRepresentation::kTagged);
872 864
873 Node* ovf = graph()->NewNode(common()->Projection(1), add, control); 865 Node* add = __ Int32AddWithOverflow(value, value);
874 Node* branch = 866 Node* ovf = __ Projection(1, add);
875 graph()->NewNode(common()->Branch(BranchHint::kFalse), ovf, control); 867 __ GotoIf(ovf, &if_overflow);
876 868 __ Goto(&done, __ Projection(0, add));
877 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); 869
878 ValueEffectControl alloc = 870 __ Bind(&if_overflow);
879 AllocateHeapNumberWithValue(ChangeInt32ToFloat64(value), effect, if_true); 871 Node* number = AllocateHeapNumberWithValue(__ ChangeInt32ToFloat64(value));
880 872 __ Goto(&done, number);
881 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); 873
882 Node* vfalse = graph()->NewNode(common()->Projection(0), add, if_false); 874 __ Bind(&done);
883 875 return done.PhiAt(0);
884 Node* merge = graph()->NewNode(common()->Merge(2), alloc.control, if_false); 876 }
885 Node* phi = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2), 877
886 alloc.value, vfalse, merge); 878 Node* EffectControlLinearizer::LowerChangeUint32ToTagged(Node* node) {
887 Node* ephi = 879 Node* value = node->InputAt(0);
888 graph()->NewNode(common()->EffectPhi(2), alloc.effect, effect, merge); 880
889 881 auto if_not_in_smi_range = __ MakeDeferredLabel<1>();
890 return ValueEffectControl(phi, ephi, merge); 882 auto done = __ MakeLabel<2>(MachineRepresentation::kTagged);
891 } 883
892 884 Node* check = __ Uint32LessThanOrEqual(value, SmiMaxValueConstant());
893 EffectControlLinearizer::ValueEffectControl 885 __ GotoUnless(check, &if_not_in_smi_range);
894 EffectControlLinearizer::LowerChangeUint32ToTagged(Node* node, Node* effect, 886 __ Goto(&done, ChangeUint32ToSmi(value));
895 Node* control) { 887
896 Node* value = node->InputAt(0); 888 __ Bind(&if_not_in_smi_range);
897 889 Node* number = AllocateHeapNumberWithValue(__ ChangeUint32ToFloat64(value));
898 Node* check = graph()->NewNode(machine()->Uint32LessThanOrEqual(), value, 890
899 SmiMaxValueConstant()); 891 __ Goto(&done, number);
900 Node* branch = 892 __ Bind(&done);
901 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); 893
902 894 return done.PhiAt(0);
903 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); 895 }
904 Node* vtrue = ChangeUint32ToSmi(value); 896
905 897 Node* EffectControlLinearizer::LowerChangeTaggedSignedToInt32(Node* node) {
906 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); 898 Node* value = node->InputAt(0);
907 ValueEffectControl alloc = AllocateHeapNumberWithValue( 899 return ChangeSmiToInt32(value);
908 ChangeUint32ToFloat64(value), effect, if_false); 900 }
909 901
910 Node* merge = graph()->NewNode(common()->Merge(2), if_true, alloc.control); 902 Node* EffectControlLinearizer::LowerChangeTaggedToBit(Node* node) {
911 Node* phi = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2), 903 Node* value = node->InputAt(0);
912 vtrue, alloc.value, merge); 904 return __ WordEqual(value, __ TrueConstant());
913 Node* ephi = 905 }
914 graph()->NewNode(common()->EffectPhi(2), effect, alloc.effect, merge); 906
915 907 Node* EffectControlLinearizer::LowerTruncateTaggedToBit(Node* node) {
916 return ValueEffectControl(phi, ephi, merge); 908 Node* value = node->InputAt(0);
917 } 909
918 910 auto if_smi = __ MakeDeferredLabel<1>();
919 EffectControlLinearizer::ValueEffectControl 911 auto if_not_oddball = __ MakeDeferredLabel<1>();
920 EffectControlLinearizer::LowerChangeTaggedSignedToInt32(Node* node, 912 auto if_not_string = __ MakeDeferredLabel<1>();
921 Node* effect, 913 auto if_not_heapnumber = __ MakeDeferredLabel<1>();
922 Node* control) { 914 auto done = __ MakeLabel<5>(MachineRepresentation::kBit);
923 Node* value = node->InputAt(0); 915
924 value = ChangeSmiToInt32(value); 916 Node* zero = __ Int32Constant(0);
925 return ValueEffectControl(value, effect, control); 917 Node* fzero = __ Float64Constant(0.0);
926 }
927
928 EffectControlLinearizer::ValueEffectControl
929 EffectControlLinearizer::LowerChangeTaggedToBit(Node* node, Node* effect,
930 Node* control) {
931 Node* value = node->InputAt(0);
932 value = graph()->NewNode(machine()->WordEqual(), value,
933 jsgraph()->TrueConstant());
934 return ValueEffectControl(value, effect, control);
935 }
936
937 EffectControlLinearizer::ValueEffectControl
938 EffectControlLinearizer::LowerTruncateTaggedToBit(Node* node, Node* effect,
939 Node* control) {
940 Node* value = node->InputAt(0);
941 Node* zero = jsgraph()->Int32Constant(0);
942 Node* fzero = jsgraph()->Float64Constant(0.0);
943
944 // Collect effect/control/value triples.
945 int count = 0;
946 Node* values[6];
947 Node* effects[6];
948 Node* controls[5];
949 918
950 // Check if {value} is a Smi. 919 // Check if {value} is a Smi.
951 Node* check_smi = ObjectIsSmi(value); 920 Node* check_smi = ObjectIsSmi(value);
952 Node* branch_smi = graph()->NewNode(common()->Branch(BranchHint::kFalse), 921 __ GotoIf(check_smi, &if_smi);
953 check_smi, control);
954
955 // If {value} is a Smi, then we only need to check that it's not zero.
956 Node* if_smi = graph()->NewNode(common()->IfTrue(), branch_smi);
957 Node* esmi = effect;
958 {
959 controls[count] = if_smi;
960 effects[count] = esmi;
961 values[count] =
962 graph()->NewNode(machine()->Word32Equal(),
963 graph()->NewNode(machine()->WordEqual(), value,
964 jsgraph()->IntPtrConstant(0)),
965 zero);
966 count++;
967 }
968 control = graph()->NewNode(common()->IfFalse(), branch_smi);
969 922
970 // Load the map instance type of {value}. 923 // Load the map instance type of {value}.
971 Node* value_map = effect = graph()->NewNode( 924 Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
972 simplified()->LoadField(AccessBuilder::ForMap()), value, effect, control); 925 Node* value_instance_type =
973 Node* value_instance_type = effect = graph()->NewNode( 926 __ LoadField(AccessBuilder::ForMapInstanceType(), value_map);
974 simplified()->LoadField(AccessBuilder::ForMapInstanceType()), value_map,
975 effect, control);
976 927
977 // Check if {value} is an Oddball. 928 // Check if {value} is an Oddball.
978 Node* check_oddball = 929 Node* check_oddball =
979 graph()->NewNode(machine()->Word32Equal(), value_instance_type, 930 __ Word32Equal(value_instance_type, __ Int32Constant(ODDBALL_TYPE));
980 jsgraph()->Int32Constant(ODDBALL_TYPE)); 931
981 Node* branch_oddball = graph()->NewNode(common()->Branch(BranchHint::kTrue), 932 __ GotoUnless(check_oddball, &if_not_oddball);
982 check_oddball, control);
983
984 // The only Oddball {value} that is trueish is true itself. 933 // The only Oddball {value} that is trueish is true itself.
985 Node* if_oddball = graph()->NewNode(common()->IfTrue(), branch_oddball); 934 __ Goto(&done, __ WordEqual(value, __ TrueConstant()));
986 Node* eoddball = effect; 935
987 { 936 __ Bind(&if_not_oddball);
988 controls[count] = if_oddball;
989 effects[count] = eoddball;
990 values[count] = graph()->NewNode(machine()->WordEqual(), value,
991 jsgraph()->TrueConstant());
992 count++;
993 }
994 control = graph()->NewNode(common()->IfFalse(), branch_oddball);
995
996 // Check if {value} is a String. 937 // Check if {value} is a String.
997 Node* check_string = 938 Node* check_string = __ Int32LessThan(value_instance_type,
998 graph()->NewNode(machine()->Int32LessThan(), value_instance_type, 939 __ Int32Constant(FIRST_NONSTRING_TYPE));
999 jsgraph()->Int32Constant(FIRST_NONSTRING_TYPE)); 940 __ GotoUnless(check_string, &if_not_string);
1000 Node* branch_string =
1001 graph()->NewNode(common()->Branch(), check_string, control);
1002
1003 // For String {value}, we need to check that the length is not zero. 941 // For String {value}, we need to check that the length is not zero.
1004 Node* if_string = graph()->NewNode(common()->IfTrue(), branch_string); 942 Node* value_length = __ LoadField(AccessBuilder::ForStringLength(), value);
1005 Node* estring = effect; 943 __ Goto(&done, __ Word32Equal(
1006 { 944 __ WordEqual(value_length, __ IntPtrConstant(0)), zero));
1007 // Load the {value} length. 945
1008 Node* value_length = estring = graph()->NewNode( 946 __ Bind(&if_not_string);
1009 simplified()->LoadField(AccessBuilder::ForStringLength()), value,
1010 estring, if_string);
1011
1012 controls[count] = if_string;
1013 effects[count] = estring;
1014 values[count] =
1015 graph()->NewNode(machine()->Word32Equal(),
1016 graph()->NewNode(machine()->WordEqual(), value_length,
1017 jsgraph()->IntPtrConstant(0)),
1018 zero);
1019 count++;
1020 }
1021 control = graph()->NewNode(common()->IfFalse(), branch_string);
1022
1023 // Check if {value} is a HeapNumber. 947 // Check if {value} is a HeapNumber.
1024 Node* check_heapnumber = 948 Node* check_heapnumber =
1025 graph()->NewNode(machine()->Word32Equal(), value_instance_type, 949 __ Word32Equal(value_instance_type, __ Int32Constant(HEAP_NUMBER_TYPE));
1026 jsgraph()->Int32Constant(HEAP_NUMBER_TYPE)); 950 __ GotoUnless(check_heapnumber, &if_not_heapnumber);
1027 Node* branch_heapnumber = 951
1028 graph()->NewNode(common()->Branch(), check_heapnumber, control); 952 // For HeapNumber {value}, just check that its value is not 0.0, -0.0 or
1029 953 // NaN.
1030 // For HeapNumber {value}, just check that its value is not 0.0, -0.0 or NaN. 954 // Load the raw value of {value}.
1031 Node* if_heapnumber = graph()->NewNode(common()->IfTrue(), branch_heapnumber); 955 Node* value_value = __ LoadField(AccessBuilder::ForHeapNumberValue(), value);
1032 Node* eheapnumber = effect; 956 __ Goto(&done, __ Float64LessThan(fzero, __ Float64Abs(value_value)));
1033 {
1034 // Load the raw value of {value}.
1035 Node* value_value = eheapnumber = graph()->NewNode(
1036 simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), value,
1037 eheapnumber, if_heapnumber);
1038
1039 // Check if {value} is not one of 0, -0, or NaN.
1040 controls[count] = if_heapnumber;
1041 effects[count] = eheapnumber;
1042 values[count] = graph()->NewNode(
1043 machine()->Float64LessThan(), fzero,
1044 graph()->NewNode(machine()->Float64Abs(), value_value));
1045 count++;
1046 }
1047 control = graph()->NewNode(common()->IfFalse(), branch_heapnumber);
1048 957
1049 // The {value} is either a JSReceiver, a Symbol or some Simd128Value. In 958 // The {value} is either a JSReceiver, a Symbol or some Simd128Value. In
1050 // those cases we can just the undetectable bit on the map, which will only 959 // those cases we can just the undetectable bit on the map, which will only
1051 // be set for certain JSReceivers, i.e. document.all. 960 // be set for certain JSReceivers, i.e. document.all.
1052 { 961 __ Bind(&if_not_heapnumber);
1053 // Load the {value} map bit field. 962
1054 Node* value_map_bitfield = effect = graph()->NewNode( 963 // Load the {value} map bit field.
1055 simplified()->LoadField(AccessBuilder::ForMapBitField()), value_map, 964 Node* value_map_bitfield =
1056 effect, control); 965 __ LoadField(AccessBuilder::ForMapBitField(), value_map);
1057 966 __ Goto(&done, __ Word32Equal(
1058 controls[count] = control; 967 __ Word32And(value_map_bitfield,
1059 effects[count] = effect; 968 __ Int32Constant(1 << Map::kIsUndetectable)),
1060 values[count] = graph()->NewNode( 969 zero));
1061 machine()->Word32Equal(), 970
1062 graph()->NewNode(machine()->Word32And(), value_map_bitfield, 971 __ Bind(&if_smi);
1063 jsgraph()->Int32Constant(1 << Map::kIsUndetectable)), 972 // If {value} is a Smi, then we only need to check that it's not zero.
1064 zero); 973 __ Goto(&done,
1065 count++; 974 __ Word32Equal(__ WordEqual(value, __ IntPtrConstant(0)), zero));
1066 } 975
1067 976 __ Bind(&done);
1068 // Merge the different controls. 977 return done.PhiAt(0);
1069 control = graph()->NewNode(common()->Merge(count), count, controls); 978 }
1070 effects[count] = control; 979
1071 effect = graph()->NewNode(common()->EffectPhi(count), count + 1, effects); 980 Node* EffectControlLinearizer::LowerChangeTaggedToInt32(Node* node) {
1072 values[count] = control; 981 Node* value = node->InputAt(0);
1073 value = graph()->NewNode(common()->Phi(MachineRepresentation::kBit, count), 982
1074 count + 1, values); 983 auto if_not_smi = __ MakeDeferredLabel<1>();
1075 984 auto done = __ MakeLabel<2>(MachineRepresentation::kWord32);
1076 return ValueEffectControl(value, effect, control);
1077 }
1078
1079 EffectControlLinearizer::ValueEffectControl
1080 EffectControlLinearizer::LowerChangeTaggedToInt32(Node* node, Node* effect,
1081 Node* control) {
1082 Node* value = node->InputAt(0);
1083 985
1084 Node* check = ObjectIsSmi(value); 986 Node* check = ObjectIsSmi(value);
1085 Node* branch = 987 __ GotoUnless(check, &if_not_smi);
1086 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); 988 __ Goto(&done, ChangeSmiToInt32(value));
1087 989
1088 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); 990 __ Bind(&if_not_smi);
1089 Node* etrue = effect; 991 STATIC_ASSERT(HeapNumber::kValueOffset == Oddball::kToNumberRawOffset);
992 Node* vfalse = __ LoadField(AccessBuilder::ForHeapNumberValue(), value);
993 vfalse = __ ChangeFloat64ToInt32(vfalse);
994 __ Goto(&done, vfalse);
995
996 __ Bind(&done);
997 return done.PhiAt(0);
998 }
999
1000 Node* EffectControlLinearizer::LowerChangeTaggedToUint32(Node* node) {
1001 Node* value = node->InputAt(0);
1002
1003 auto if_not_smi = __ MakeDeferredLabel<1>();
1004 auto done = __ MakeLabel<2>(MachineRepresentation::kWord32);
1005
1006 Node* check = ObjectIsSmi(value);
1007 __ GotoUnless(check, &if_not_smi);
1008 __ Goto(&done, ChangeSmiToInt32(value));
1009
1010 __ Bind(&if_not_smi);
1011 STATIC_ASSERT(HeapNumber::kValueOffset == Oddball::kToNumberRawOffset);
1012 Node* vfalse = __ LoadField(AccessBuilder::ForHeapNumberValue(), value);
1013 vfalse = __ ChangeFloat64ToUint32(vfalse);
1014 __ Goto(&done, vfalse);
1015
1016 __ Bind(&done);
1017 return done.PhiAt(0);
1018 }
1019
1020 Node* EffectControlLinearizer::LowerChangeTaggedToFloat64(Node* node) {
1021 return LowerTruncateTaggedToFloat64(node);
1022 }
1023
1024 Node* EffectControlLinearizer::LowerTruncateTaggedToFloat64(Node* node) {
1025 Node* value = node->InputAt(0);
1026
1027 auto if_not_smi = __ MakeDeferredLabel<1>();
1028 auto done = __ MakeLabel<2>(MachineRepresentation::kFloat64);
1029
1030 Node* check = ObjectIsSmi(value);
1031 __ GotoUnless(check, &if_not_smi);
1090 Node* vtrue = ChangeSmiToInt32(value); 1032 Node* vtrue = ChangeSmiToInt32(value);
1091 1033 vtrue = __ ChangeInt32ToFloat64(vtrue);
1092 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); 1034 __ Goto(&done, vtrue);
1093 Node* efalse = effect; 1035
1094 Node* vfalse; 1036 __ Bind(&if_not_smi);
1095 { 1037 STATIC_ASSERT(HeapNumber::kValueOffset == Oddball::kToNumberRawOffset);
1096 STATIC_ASSERT(HeapNumber::kValueOffset == Oddball::kToNumberRawOffset); 1038 Node* vfalse = __ LoadField(AccessBuilder::ForHeapNumberValue(), value);
1097 vfalse = efalse = graph()->NewNode( 1039 __ Goto(&done, vfalse);
1098 simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), value, 1040
1099 efalse, if_false); 1041 __ Bind(&done);
1100 vfalse = graph()->NewNode(machine()->ChangeFloat64ToInt32(), vfalse); 1042 return done.PhiAt(0);
1101 } 1043 }
1102 1044
1103 control = graph()->NewNode(common()->Merge(2), if_true, if_false); 1045 Node* EffectControlLinearizer::LowerCheckBounds(Node* node, Node* frame_state) {
1104 effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control);
1105 value = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
1106 vtrue, vfalse, control);
1107
1108 return ValueEffectControl(value, effect, control);
1109 }
1110
1111 EffectControlLinearizer::ValueEffectControl
1112 EffectControlLinearizer::LowerChangeTaggedToUint32(Node* node, Node* effect,
1113 Node* control) {
1114 Node* value = node->InputAt(0);
1115
1116 Node* check = ObjectIsSmi(value);
1117 Node* branch =
1118 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
1119
1120 Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
1121 Node* etrue = effect;
1122 Node* vtrue = ChangeSmiToInt32(value);
1123
1124 Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
1125 Node* efalse = effect;
1126 Node* vfalse;
1127 {
1128 STATIC_ASSERT(HeapNumber::kValueOffset == Oddball::kToNumberRawOffset);
1129 vfalse = efalse = graph()->NewNode(
1130 simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), value,
1131 efalse, if_false);
1132 vfalse = graph()->NewNode(machine()->ChangeFloat64ToUint32(), vfalse);
1133 }
1134
1135 control = graph()->NewNode(common()->Merge(2), if_true, if_false);
1136 effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control);
1137 value = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
1138 vtrue, vfalse, control);
1139
1140 return ValueEffectControl(value, effect, control);
1141 }
1142
1143 EffectControlLinearizer::ValueEffectControl
1144 EffectControlLinearizer::LowerChangeTaggedToFloat64(Node* node, Node* effect,
1145 Node* control) {
1146 return LowerTruncateTaggedToFloat64(node, effect, control);
1147 }
1148
1149 EffectControlLinearizer::ValueEffectControl
1150 EffectControlLinearizer::LowerTruncateTaggedToFloat64(Node* node, Node* effect,
1151 Node* control) {
1152 Node* value = node->InputAt(0);
1153
1154 Node* check = ObjectIsSmi(value);
1155 Node* branch =
1156 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
1157
1158 Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
1159 Node* etrue = effect;
1160 Node* vtrue;
1161 {
1162 vtrue = ChangeSmiToInt32(value);
1163 vtrue = graph()->NewNode(machine()->ChangeInt32ToFloat64(), vtrue);
1164 }
1165
1166 Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
1167 Node* efalse = effect;
1168 Node* vfalse;
1169 {
1170 STATIC_ASSERT(HeapNumber::kValueOffset == Oddball::kToNumberRawOffset);
1171 vfalse = efalse = graph()->NewNode(
1172 simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), value,
1173 efalse, if_false);
1174 }
1175
1176 control = graph()->NewNode(common()->Merge(2), if_true, if_false);
1177 effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control);
1178 value = graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
1179 vtrue, vfalse, control);
1180
1181 return ValueEffectControl(value, effect, control);
1182 }
1183
1184 EffectControlLinearizer::ValueEffectControl
1185 EffectControlLinearizer::LowerCheckBounds(Node* node, Node* frame_state,
1186 Node* effect, Node* control) {
1187 Node* index = node->InputAt(0); 1046 Node* index = node->InputAt(0);
1188 Node* limit = node->InputAt(1); 1047 Node* limit = node->InputAt(1);
1189 1048
1190 Node* check = graph()->NewNode(machine()->Uint32LessThan(), index, limit); 1049 Node* check = __ Uint32LessThan(index, limit);
1191 control = effect = graph()->NewNode( 1050 __ DeoptimizeUnless(DeoptimizeReason::kOutOfBounds, check, frame_state);
1192 common()->DeoptimizeUnless(DeoptimizeReason::kOutOfBounds), check, 1051 return index;
1193 frame_state, effect, control); 1052 }
1194 1053
1195 return ValueEffectControl(index, effect, control); 1054 Node* EffectControlLinearizer::LowerCheckMaps(Node* node, Node* frame_state) {
1196 } 1055 Node* value = node->InputAt(0);
1197 1056
1198 EffectControlLinearizer::ValueEffectControl 1057 int const map_count = node->op()->ValueInputCount() - 1;
1199 EffectControlLinearizer::LowerCheckMaps(Node* node, Node* frame_state, 1058 auto done = __ MakeLabelFor(GraphAssemblerLabelType::kNonDeferred,
1200 Node* effect, Node* control) { 1059 static_cast<size_t>(map_count));
1201 Node* value = node->InputAt(0);
1202 1060
1203 // Load the current map of the {value}. 1061 // Load the current map of the {value}.
1204 Node* value_map = effect = graph()->NewNode( 1062 Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
1205 simplified()->LoadField(AccessBuilder::ForMap()), value, effect, control);
1206
1207 int const map_count = node->op()->ValueInputCount() - 1;
1208 Node** controls = temp_zone()->NewArray<Node*>(map_count);
1209 Node** effects = temp_zone()->NewArray<Node*>(map_count + 1);
1210 1063
1211 for (int i = 0; i < map_count; ++i) { 1064 for (int i = 0; i < map_count; ++i) {
1212 Node* map = node->InputAt(1 + i); 1065 Node* map = node->InputAt(1 + i);
1213 1066 Node* check = __ WordEqual(value_map, map);
1214 Node* check = graph()->NewNode(machine()->WordEqual(), value_map, map);
1215 if (i == map_count - 1) { 1067 if (i == map_count - 1) {
1216 controls[i] = effects[i] = graph()->NewNode( 1068 __ DeoptimizeUnless(DeoptimizeReason::kWrongMap, check, frame_state);
1217 common()->DeoptimizeUnless(DeoptimizeReason::kWrongMap), check,
1218 frame_state, effect, control);
1219 } else { 1069 } else {
1220 control = graph()->NewNode(common()->Branch(), check, control); 1070 __ GotoIf(check, &done);
1221 controls[i] = graph()->NewNode(common()->IfTrue(), control);
1222 control = graph()->NewNode(common()->IfFalse(), control);
1223 effects[i] = effect;
1224 } 1071 }
1225 } 1072 }
1226 1073 __ Goto(&done);
1227 control = graph()->NewNode(common()->Merge(map_count), map_count, controls); 1074 __ Bind(&done);
1228 effects[map_count] = control; 1075 return value;
1229 effect = 1076 }
1230 graph()->NewNode(common()->EffectPhi(map_count), map_count + 1, effects); 1077
1231 1078 Node* EffectControlLinearizer::LowerCheckNumber(Node* node, Node* frame_state) {
1232 return ValueEffectControl(value, effect, control); 1079 Node* value = node->InputAt(0);
1233 } 1080
1234 1081 auto if_not_smi = __ MakeDeferredLabel<1>();
1235 EffectControlLinearizer::ValueEffectControl 1082 auto done = __ MakeLabel<2>();
1236 EffectControlLinearizer::LowerCheckNumber(Node* node, Node* frame_state,
1237 Node* effect, Node* control) {
1238 Node* value = node->InputAt(0);
1239 1083
1240 Node* check0 = ObjectIsSmi(value); 1084 Node* check0 = ObjectIsSmi(value);
1241 Node* branch0 = 1085 __ GotoUnless(check0, &if_not_smi);
1242 graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control); 1086 __ Goto(&done);
1243 1087
1244 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); 1088 __ Bind(&if_not_smi);
1245 Node* etrue0 = effect; 1089 Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
1246 1090 Node* check1 = __ WordEqual(value_map, __ HeapNumberMapConstant());
1247 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0); 1091 __ DeoptimizeUnless(DeoptimizeReason::kNotAHeapNumber, check1, frame_state);
1248 Node* efalse0 = effect; 1092 __ Goto(&done);
1249 { 1093
1250 Node* value_map = efalse0 = 1094 __ Bind(&done);
1251 graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), 1095 return value;
1252 value, efalse0, if_false0); 1096 }
1253 Node* check1 = graph()->NewNode(machine()->WordEqual(), value_map, 1097
1254 jsgraph()->HeapNumberMapConstant()); 1098 Node* EffectControlLinearizer::LowerCheckString(Node* node, Node* frame_state) {
1255 if_false0 = efalse0 = graph()->NewNode(
1256 common()->DeoptimizeUnless(DeoptimizeReason::kNotAHeapNumber), check1,
1257 frame_state, efalse0, if_false0);
1258 }
1259
1260 control = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
1261 effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control);
1262
1263 return ValueEffectControl(value, effect, control);
1264 }
1265
1266 EffectControlLinearizer::ValueEffectControl
1267 EffectControlLinearizer::LowerCheckString(Node* node, Node* frame_state,
1268 Node* effect, Node* control) {
1269 Node* value = node->InputAt(0); 1099 Node* value = node->InputAt(0);
1270 1100
1271 Node* check0 = ObjectIsSmi(value); 1101 Node* check0 = ObjectIsSmi(value);
1272 control = effect = 1102 __ DeoptimizeIf(DeoptimizeReason::kSmi, check0, frame_state);
1273 graph()->NewNode(common()->DeoptimizeIf(DeoptimizeReason::kSmi), check0, 1103
1274 frame_state, effect, control); 1104 Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
1275 1105 Node* value_instance_type =
1276 Node* value_map = effect = graph()->NewNode( 1106 __ LoadField(AccessBuilder::ForMapInstanceType(), value_map);
1277 simplified()->LoadField(AccessBuilder::ForMap()), value, effect, control); 1107
1278 Node* value_instance_type = effect = graph()->NewNode( 1108 Node* check1 = __ Uint32LessThan(value_instance_type,
1279 simplified()->LoadField(AccessBuilder::ForMapInstanceType()), value_map, 1109 __ Uint32Constant(FIRST_NONSTRING_TYPE));
1280 effect, control); 1110 __ DeoptimizeUnless(DeoptimizeReason::kWrongInstanceType, check1,
1281 1111 frame_state);
1282 Node* check1 = 1112 return value;
1283 graph()->NewNode(machine()->Uint32LessThan(), value_instance_type, 1113 }
1284 jsgraph()->Uint32Constant(FIRST_NONSTRING_TYPE)); 1114
1285 control = effect = graph()->NewNode( 1115 Node* EffectControlLinearizer::LowerCheckIf(Node* node, Node* frame_state) {
1286 common()->DeoptimizeUnless(DeoptimizeReason::kWrongInstanceType), check1, 1116 Node* value = node->InputAt(0);
1287 frame_state, effect, control); 1117 __ DeoptimizeUnless(DeoptimizeReason::kNoReason, value, frame_state);
1288 1118 return value;
1289 return ValueEffectControl(value, effect, control); 1119 }
1290 } 1120
1291 1121 Node* EffectControlLinearizer::LowerCheckedInt32Add(Node* node,
1292 EffectControlLinearizer::ValueEffectControl 1122 Node* frame_state) {
1293 EffectControlLinearizer::LowerCheckIf(Node* node, Node* frame_state,
1294 Node* effect, Node* control) {
1295 Node* value = node->InputAt(0);
1296
1297 control = effect =
1298 graph()->NewNode(common()->DeoptimizeUnless(DeoptimizeReason::kNoReason),
1299 value, frame_state, effect, control);
1300
1301 return ValueEffectControl(value, effect, control);
1302 }
1303
1304 EffectControlLinearizer::ValueEffectControl
1305 EffectControlLinearizer::LowerCheckedInt32Add(Node* node, Node* frame_state,
1306 Node* effect, Node* control) {
1307 Node* lhs = node->InputAt(0); 1123 Node* lhs = node->InputAt(0);
1308 Node* rhs = node->InputAt(1); 1124 Node* rhs = node->InputAt(1);
1309 1125
1310 Node* value = 1126 Node* value = __ Int32AddWithOverflow(lhs, rhs);
1311 graph()->NewNode(machine()->Int32AddWithOverflow(), lhs, rhs, control); 1127 Node* check = __ Projection(1, value);
1312 1128 __ DeoptimizeIf(DeoptimizeReason::kOverflow, check, frame_state);
1313 Node* check = graph()->NewNode(common()->Projection(1), value, control); 1129 return __ Projection(0, value);
1314 control = effect = 1130 }
1315 graph()->NewNode(common()->DeoptimizeIf(DeoptimizeReason::kOverflow), 1131
1316 check, frame_state, effect, control); 1132 Node* EffectControlLinearizer::LowerCheckedInt32Sub(Node* node,
1317 1133 Node* frame_state) {
1318 value = graph()->NewNode(common()->Projection(0), value, control);
1319
1320 return ValueEffectControl(value, effect, control);
1321 }
1322
1323 EffectControlLinearizer::ValueEffectControl
1324 EffectControlLinearizer::LowerCheckedInt32Sub(Node* node, Node* frame_state,
1325 Node* effect, Node* control) {
1326 Node* lhs = node->InputAt(0); 1134 Node* lhs = node->InputAt(0);
1327 Node* rhs = node->InputAt(1); 1135 Node* rhs = node->InputAt(1);
1328 1136
1329 Node* value = 1137 Node* value = __ Int32SubWithOverflow(lhs, rhs);
1330 graph()->NewNode(machine()->Int32SubWithOverflow(), lhs, rhs, control); 1138 Node* check = __ Projection(1, value);
1331 1139 __ DeoptimizeIf(DeoptimizeReason::kOverflow, check, frame_state);
1332 Node* check = graph()->NewNode(common()->Projection(1), value, control); 1140 return __ Projection(0, value);
1333 control = effect = 1141 }
1334 graph()->NewNode(common()->DeoptimizeIf(DeoptimizeReason::kOverflow), 1142
1335 check, frame_state, effect, control); 1143 Node* EffectControlLinearizer::LowerCheckedInt32Div(Node* node,
1336 1144 Node* frame_state) {
1337 value = graph()->NewNode(common()->Projection(0), value, control);
1338
1339 return ValueEffectControl(value, effect, control);
1340 }
1341
1342 EffectControlLinearizer::ValueEffectControl
1343 EffectControlLinearizer::LowerCheckedInt32Div(Node* node, Node* frame_state,
1344 Node* effect, Node* control) {
1345 Node* zero = jsgraph()->Int32Constant(0);
1346 Node* minusone = jsgraph()->Int32Constant(-1);
1347 Node* minint = jsgraph()->Int32Constant(std::numeric_limits<int32_t>::min());
1348
1349 Node* lhs = node->InputAt(0); 1145 Node* lhs = node->InputAt(0);
1350 Node* rhs = node->InputAt(1); 1146 Node* rhs = node->InputAt(1);
1351 1147
1148 auto if_not_positive = __ MakeDeferredLabel<1>();
1149 auto if_is_minint = __ MakeDeferredLabel<1>();
1150 auto done = __ MakeLabel<2>(MachineRepresentation::kWord32);
1151 auto minint_check_done = __ MakeLabel<2>();
1152
1153 Node* zero = __ Int32Constant(0);
1154
1352 // Check if {rhs} is positive (and not zero). 1155 // Check if {rhs} is positive (and not zero).
1353 Node* check0 = graph()->NewNode(machine()->Int32LessThan(), zero, rhs); 1156 Node* check0 = __ Int32LessThan(zero, rhs);
1354 Node* branch0 = 1157 __ GotoUnless(check0, &if_not_positive);
1355 graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control); 1158
1356 1159 // Fast case, no additional checking required.
1357 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); 1160 __ Goto(&done, __ Int32Div(lhs, rhs));
1358 Node* etrue0 = effect; 1161
1359 Node* vtrue0;
1360 { 1162 {
1361 // Fast case, no additional checking required. 1163 __ Bind(&if_not_positive);
1362 vtrue0 = graph()->NewNode(machine()->Int32Div(), lhs, rhs, if_true0); 1164
1363 }
1364
1365 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
1366 Node* efalse0 = effect;
1367 Node* vfalse0;
1368 {
1369 // Check if {rhs} is zero. 1165 // Check if {rhs} is zero.
1370 Node* check = graph()->NewNode(machine()->Word32Equal(), rhs, zero); 1166 Node* check = __ Word32Equal(rhs, zero);
1371 if_false0 = efalse0 = graph()->NewNode( 1167 __ DeoptimizeIf(DeoptimizeReason::kDivisionByZero, check, frame_state);
1372 common()->DeoptimizeIf(DeoptimizeReason::kDivisionByZero), check,
1373 frame_state, efalse0, if_false0);
1374 1168
1375 // Check if {lhs} is zero, as that would produce minus zero. 1169 // Check if {lhs} is zero, as that would produce minus zero.
1376 check = graph()->NewNode(machine()->Word32Equal(), lhs, zero); 1170 check = __ Word32Equal(lhs, zero);
1377 if_false0 = efalse0 = 1171 __ DeoptimizeIf(DeoptimizeReason::kMinusZero, check, frame_state);
1378 graph()->NewNode(common()->DeoptimizeIf(DeoptimizeReason::kMinusZero),
1379 check, frame_state, efalse0, if_false0);
1380 1172
1381 // Check if {lhs} is kMinInt and {rhs} is -1, in which case we'd have 1173 // Check if {lhs} is kMinInt and {rhs} is -1, in which case we'd have
1382 // to return -kMinInt, which is not representable. 1174 // to return -kMinInt, which is not representable.
1175 Node* minint = __ Int32Constant(std::numeric_limits<int32_t>::min());
1383 Node* check1 = graph()->NewNode(machine()->Word32Equal(), lhs, minint); 1176 Node* check1 = graph()->NewNode(machine()->Word32Equal(), lhs, minint);
1384 Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kFalse), 1177 __ GotoIf(check1, &if_is_minint);
1385 check1, if_false0); 1178 __ Goto(&minint_check_done);
1386 1179
1387 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); 1180 __ Bind(&if_is_minint);
1388 Node* etrue1 = efalse0; 1181 // Check if {rhs} is -1.
1389 { 1182 Node* minusone = __ Int32Constant(-1);
1390 // Check if {rhs} is -1. 1183 Node* is_minus_one = __ Word32Equal(rhs, minusone);
1391 Node* check = graph()->NewNode(machine()->Word32Equal(), rhs, minusone); 1184 __ DeoptimizeIf(DeoptimizeReason::kOverflow, is_minus_one, frame_state);
1392 if_true1 = etrue1 = 1185 __ Goto(&minint_check_done);
1393 graph()->NewNode(common()->DeoptimizeIf(DeoptimizeReason::kOverflow), 1186
1394 check, frame_state, etrue1, if_true1); 1187 __ Bind(&minint_check_done);
1395 }
1396
1397 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
1398 Node* efalse1 = efalse0;
1399
1400 if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
1401 efalse0 =
1402 graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, if_false0);
1403
1404 // Perform the actual integer division. 1188 // Perform the actual integer division.
1405 vfalse0 = graph()->NewNode(machine()->Int32Div(), lhs, rhs, if_false0); 1189 __ Goto(&done, __ Int32Div(lhs, rhs));
1406 } 1190 }
1407 1191
1408 control = graph()->NewNode(common()->Merge(2), if_true0, if_false0); 1192 __ Bind(&done);
1409 effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control); 1193 Node* value = done.PhiAt(0);
1410 Node* value =
1411 graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2), vtrue0,
1412 vfalse0, control);
1413 1194
1414 // Check if the remainder is non-zero. 1195 // Check if the remainder is non-zero.
1415 Node* check = 1196 Node* check = __ Word32Equal(lhs, __ Int32Mul(rhs, value));
1416 graph()->NewNode(machine()->Word32Equal(), lhs, 1197 __ DeoptimizeUnless(DeoptimizeReason::kLostPrecision, check, frame_state);
1417 graph()->NewNode(machine()->Int32Mul(), rhs, value)); 1198
1418 control = effect = graph()->NewNode( 1199 return value;
1419 common()->DeoptimizeUnless(DeoptimizeReason::kLostPrecision), check, 1200 }
1420 frame_state, effect, control); 1201
1421 1202 Node* EffectControlLinearizer::LowerCheckedInt32Mod(Node* node,
1422 return ValueEffectControl(value, effect, control); 1203 Node* frame_state) {
1423 }
1424
1425 EffectControlLinearizer::ValueEffectControl
1426 EffectControlLinearizer::LowerCheckedInt32Mod(Node* node, Node* frame_state,
1427 Node* effect, Node* control) {
1428 Node* zero = jsgraph()->Int32Constant(0);
1429 Node* one = jsgraph()->Int32Constant(1);
1430
1431 // General case for signed integer modulus, with optimization for (unknown) 1204 // General case for signed integer modulus, with optimization for (unknown)
1432 // power of 2 right hand side. 1205 // power of 2 right hand side.
1433 // 1206 //
1434 // if rhs <= 0 then 1207 // if rhs <= 0 then
1435 // rhs = -rhs 1208 // rhs = -rhs
1436 // deopt if rhs == 0 1209 // deopt if rhs == 0
1437 // if lhs < 0 then 1210 // if lhs < 0 then
1438 // let res = lhs % rhs in 1211 // let res = lhs % rhs in
1439 // deopt if res == 0 1212 // deopt if res == 0
1440 // res 1213 // res
1441 // else 1214 // else
1442 // let msk = rhs - 1 in 1215 // let msk = rhs - 1 in
1443 // if rhs & msk == 0 then 1216 // if rhs & msk == 0 then
1444 // lhs & msk 1217 // lhs & msk
1445 // else 1218 // else
1446 // lhs % rhs 1219 // lhs % rhs
1447 // 1220 //
1448 Node* lhs = node->InputAt(0); 1221 Node* lhs = node->InputAt(0);
1449 Node* rhs = node->InputAt(1); 1222 Node* rhs = node->InputAt(1);
1450 1223
1224 auto if_rhs_not_positive = __ MakeDeferredLabel<1>();
1225 auto if_lhs_negative = __ MakeDeferredLabel<1>();
1226 auto if_power_of_two = __ MakeLabel<1>();
1227 auto rhs_checked = __ MakeLabel<2>(MachineRepresentation::kWord32);
1228 auto done = __ MakeLabel<3>(MachineRepresentation::kWord32);
1229
1230 Node* zero = __ Int32Constant(0);
1231
1451 // Check if {rhs} is not strictly positive. 1232 // Check if {rhs} is not strictly positive.
1452 Node* check0 = graph()->NewNode(machine()->Int32LessThanOrEqual(), rhs, zero); 1233 Node* check0 = __ Int32LessThanOrEqual(rhs, zero);
1453 Node* branch0 = 1234 __ GotoIf(check0, &if_rhs_not_positive);
1454 graph()->NewNode(common()->Branch(BranchHint::kFalse), check0, control); 1235 __ Goto(&rhs_checked, rhs);
1455 1236
1456 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); 1237 __ Bind(&if_rhs_not_positive);
1457 Node* etrue0 = effect;
1458 Node* vtrue0;
1459 { 1238 {
1460 // Negate {rhs}, might still produce a negative result in case of 1239 // Negate {rhs}, might still produce a negative result in case of
1461 // -2^31, but that is handled safely below. 1240 // -2^31, but that is handled safely below.
1462 vtrue0 = graph()->NewNode(machine()->Int32Sub(), zero, rhs); 1241 Node* vtrue0 = __ Int32Sub(zero, rhs);
1463 1242
1464 // Ensure that {rhs} is not zero, otherwise we'd have to return NaN. 1243 // Ensure that {rhs} is not zero, otherwise we'd have to return NaN.
1465 Node* check = graph()->NewNode(machine()->Word32Equal(), vtrue0, zero); 1244 Node* check = __ Word32Equal(vtrue0, zero);
1466 if_true0 = etrue0 = graph()->NewNode( 1245 __ DeoptimizeIf(DeoptimizeReason::kDivisionByZero, check, frame_state);
1467 common()->DeoptimizeIf(DeoptimizeReason::kDivisionByZero), check, 1246 __ Goto(&rhs_checked, vtrue0);
1468 frame_state, etrue0, if_true0); 1247 }
1469 } 1248
1470 1249 __ Bind(&rhs_checked);
1471 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0); 1250 rhs = rhs_checked.PhiAt(0);
1472 Node* efalse0 = effect;
1473 Node* vfalse0 = rhs;
1474
1475 // At this point {rhs} is either greater than zero or -2^31, both are
1476 // fine for the code that follows.
1477 control = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
1478 effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control);
1479 rhs = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
1480 vtrue0, vfalse0, control);
1481 1251
1482 // Check if {lhs} is negative. 1252 // Check if {lhs} is negative.
1483 Node* check1 = graph()->NewNode(machine()->Int32LessThan(), lhs, zero); 1253 Node* check1 = __ Int32LessThan(lhs, zero);
1484 Node* branch1 = 1254 __ GotoIf(check1, &if_lhs_negative);
1485 graph()->NewNode(common()->Branch(BranchHint::kFalse), check1, control); 1255
1486 1256 // {lhs} non-negative.
1487 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); 1257 {
1488 Node* etrue1 = effect; 1258 Node* one = __ Int32Constant(1);
1489 Node* vtrue1; 1259 Node* msk = __ Int32Sub(rhs, one);
1260
1261 // Check if {rhs} minus one is a valid mask.
1262 Node* check2 = __ Word32Equal(__ Word32And(rhs, msk), zero);
1263 __ GotoIf(check2, &if_power_of_two);
1264 // Compute the remainder using the generic {lhs % rhs}.
1265 __ Goto(&done, __ Int32Mod(lhs, rhs));
1266
1267 __ Bind(&if_power_of_two);
1268 // Compute the remainder using {lhs & msk}.
1269 __ Goto(&done, __ Word32And(lhs, msk));
1270 }
1271
1272 __ Bind(&if_lhs_negative);
1490 { 1273 {
1491 // Compute the remainder using {lhs % msk}. 1274 // Compute the remainder using {lhs % msk}.
1492 vtrue1 = graph()->NewNode(machine()->Int32Mod(), lhs, rhs, if_true1); 1275 Node* vtrue1 = __ Int32Mod(lhs, rhs);
1493 1276
1494 // Check if we would have to return -0. 1277 // Check if we would have to return -0.
1495 Node* check = graph()->NewNode(machine()->Word32Equal(), vtrue1, zero); 1278 Node* check = __ Word32Equal(vtrue1, zero);
1496 if_true1 = etrue1 = 1279 __ DeoptimizeIf(DeoptimizeReason::kMinusZero, check, frame_state);
1497 graph()->NewNode(common()->DeoptimizeIf(DeoptimizeReason::kMinusZero), 1280 __ Goto(&done, vtrue1);
1498 check, frame_state, etrue1, if_true1); 1281 }
1499 } 1282
1500 1283 __ Bind(&done);
1501 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); 1284 return done.PhiAt(0);
1502 Node* efalse1 = effect; 1285 }
1503 Node* vfalse1; 1286
1504 { 1287 Node* EffectControlLinearizer::LowerCheckedUint32Div(Node* node,
1505 Node* msk = graph()->NewNode(machine()->Int32Sub(), rhs, one); 1288 Node* frame_state) {
1506
1507 // Check if {rhs} minus one is a valid mask.
1508 Node* check2 = graph()->NewNode(
1509 machine()->Word32Equal(),
1510 graph()->NewNode(machine()->Word32And(), rhs, msk), zero);
1511 Node* branch2 = graph()->NewNode(common()->Branch(), check2, if_false1);
1512
1513 // Compute the remainder using {lhs & msk}.
1514 Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
1515 Node* vtrue2 = graph()->NewNode(machine()->Word32And(), lhs, msk);
1516
1517 // Compute the remainder using the generic {lhs % rhs}.
1518 Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
1519 Node* vfalse2 =
1520 graph()->NewNode(machine()->Int32Mod(), lhs, rhs, if_false2);
1521
1522 if_false1 = graph()->NewNode(common()->Merge(2), if_true2, if_false2);
1523 vfalse1 = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
1524 vtrue2, vfalse2, if_false1);
1525 }
1526
1527 control = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
1528 effect = graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, control);
1529 Node* value =
1530 graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2), vtrue1,
1531 vfalse1, control);
1532
1533 return ValueEffectControl(value, effect, control);
1534 }
1535
1536 EffectControlLinearizer::ValueEffectControl
1537 EffectControlLinearizer::LowerCheckedUint32Div(Node* node, Node* frame_state,
1538 Node* effect, Node* control) {
1539 Node* zero = jsgraph()->Int32Constant(0);
1540
1541 Node* lhs = node->InputAt(0); 1289 Node* lhs = node->InputAt(0);
1542 Node* rhs = node->InputAt(1); 1290 Node* rhs = node->InputAt(1);
1543 1291
1292 Node* zero = __ Int32Constant(0);
1293
1544 // Ensure that {rhs} is not zero, otherwise we'd have to return NaN. 1294 // Ensure that {rhs} is not zero, otherwise we'd have to return NaN.
1545 Node* check = graph()->NewNode(machine()->Word32Equal(), rhs, zero); 1295 Node* check = __ Word32Equal(rhs, zero);
1546 control = effect = graph()->NewNode( 1296 __ DeoptimizeIf(DeoptimizeReason::kDivisionByZero, check, frame_state);
1547 common()->DeoptimizeIf(DeoptimizeReason::kDivisionByZero), check,
1548 frame_state, effect, control);
1549 1297
1550 // Perform the actual unsigned integer division. 1298 // Perform the actual unsigned integer division.
1551 Node* value = graph()->NewNode(machine()->Uint32Div(), lhs, rhs, control); 1299 Node* value = __ Uint32Div(lhs, rhs);
1552 1300
1553 // Check if the remainder is non-zero. 1301 // Check if the remainder is non-zero.
1554 check = graph()->NewNode(machine()->Word32Equal(), lhs, 1302 check = __ Word32Equal(lhs, __ Int32Mul(rhs, value));
1555 graph()->NewNode(machine()->Int32Mul(), rhs, value)); 1303 __ DeoptimizeUnless(DeoptimizeReason::kLostPrecision, check, frame_state);
1556 control = effect = graph()->NewNode( 1304 return value;
1557 common()->DeoptimizeUnless(DeoptimizeReason::kLostPrecision), check, 1305 }
1558 frame_state, effect, control); 1306
1559 1307 Node* EffectControlLinearizer::LowerCheckedUint32Mod(Node* node,
1560 return ValueEffectControl(value, effect, control); 1308 Node* frame_state) {
1561 }
1562
1563 EffectControlLinearizer::ValueEffectControl
1564 EffectControlLinearizer::LowerCheckedUint32Mod(Node* node, Node* frame_state,
1565 Node* effect, Node* control) {
1566 Node* zero = jsgraph()->Int32Constant(0);
1567
1568 Node* lhs = node->InputAt(0); 1309 Node* lhs = node->InputAt(0);
1569 Node* rhs = node->InputAt(1); 1310 Node* rhs = node->InputAt(1);
1570 1311
1312 Node* zero = __ Int32Constant(0);
1313
1571 // Ensure that {rhs} is not zero, otherwise we'd have to return NaN. 1314 // Ensure that {rhs} is not zero, otherwise we'd have to return NaN.
1572 Node* check = graph()->NewNode(machine()->Word32Equal(), rhs, zero); 1315 Node* check = __ Word32Equal(rhs, zero);
1573 control = effect = graph()->NewNode( 1316 __ DeoptimizeIf(DeoptimizeReason::kDivisionByZero, check, frame_state);
1574 common()->DeoptimizeIf(DeoptimizeReason::kDivisionByZero), check,
1575 frame_state, effect, control);
1576 1317
1577 // Perform the actual unsigned integer modulus. 1318 // Perform the actual unsigned integer modulus.
1578 Node* value = graph()->NewNode(machine()->Uint32Mod(), lhs, rhs, control); 1319 return __ Uint32Mod(lhs, rhs);
1579 1320 }
1580 return ValueEffectControl(value, effect, control); 1321
1581 } 1322 Node* EffectControlLinearizer::LowerCheckedInt32Mul(Node* node,
1582 1323 Node* frame_state) {
1583 EffectControlLinearizer::ValueEffectControl
1584 EffectControlLinearizer::LowerCheckedInt32Mul(Node* node, Node* frame_state,
1585 Node* effect, Node* control) {
1586 CheckForMinusZeroMode mode = CheckMinusZeroModeOf(node->op()); 1324 CheckForMinusZeroMode mode = CheckMinusZeroModeOf(node->op());
1587 Node* zero = jsgraph()->Int32Constant(0);
1588 Node* lhs = node->InputAt(0); 1325 Node* lhs = node->InputAt(0);
1589 Node* rhs = node->InputAt(1); 1326 Node* rhs = node->InputAt(1);
1590 1327
1591 Node* projection = 1328 Node* projection = __ Int32MulWithOverflow(lhs, rhs);
1592 graph()->NewNode(machine()->Int32MulWithOverflow(), lhs, rhs, control); 1329 Node* check = __ Projection(1, projection);
1593 1330 __ DeoptimizeIf(DeoptimizeReason::kOverflow, check, frame_state);
1594 Node* check = graph()->NewNode(common()->Projection(1), projection, control); 1331
1595 control = effect = 1332 Node* value = __ Projection(0, projection);
1596 graph()->NewNode(common()->DeoptimizeIf(DeoptimizeReason::kOverflow),
1597 check, frame_state, effect, control);
1598
1599 Node* value = graph()->NewNode(common()->Projection(0), projection, control);
1600 1333
1601 if (mode == CheckForMinusZeroMode::kCheckForMinusZero) { 1334 if (mode == CheckForMinusZeroMode::kCheckForMinusZero) {
1602 Node* check_zero = graph()->NewNode(machine()->Word32Equal(), value, zero); 1335 auto if_zero = __ MakeDeferredLabel<1>();
1603 Node* branch_zero = graph()->NewNode(common()->Branch(BranchHint::kFalse), 1336 auto check_done = __ MakeLabel<2>();
1604 check_zero, control); 1337 Node* zero = __ Int32Constant(0);
1605 1338 Node* check_zero = __ Word32Equal(value, zero);
1606 Node* if_zero = graph()->NewNode(common()->IfTrue(), branch_zero); 1339 __ GotoIf(check_zero, &if_zero);
1607 Node* e_if_zero = effect; 1340 __ Goto(&check_done);
1608 { 1341
1609 // We may need to return negative zero. 1342 __ Bind(&if_zero);
1610 Node* or_inputs = graph()->NewNode(machine()->Word32Or(), lhs, rhs); 1343 // We may need to return negative zero.
1611 Node* check_or = 1344 Node* check_or = __ Int32LessThan(__ Word32Or(lhs, rhs), zero);
1612 graph()->NewNode(machine()->Int32LessThan(), or_inputs, zero); 1345 __ DeoptimizeIf(DeoptimizeReason::kMinusZero, check_or, frame_state);
1613 if_zero = e_if_zero = 1346 __ Goto(&check_done);
1614 graph()->NewNode(common()->DeoptimizeIf(DeoptimizeReason::kMinusZero), 1347
1615 check_or, frame_state, e_if_zero, if_zero); 1348 __ Bind(&check_done);
1616 } 1349 }
1617 1350
1618 Node* if_not_zero = graph()->NewNode(common()->IfFalse(), branch_zero); 1351 return value;
1619 Node* e_if_not_zero = effect; 1352 }
1620 1353
1621 control = graph()->NewNode(common()->Merge(2), if_zero, if_not_zero); 1354 Node* EffectControlLinearizer::LowerCheckedInt32ToTaggedSigned(
1622 effect = graph()->NewNode(common()->EffectPhi(2), e_if_zero, e_if_not_zero, 1355 Node* node, Node* frame_state) {
1623 control);
1624 }
1625
1626 return ValueEffectControl(value, effect, control);
1627 }
1628
1629 EffectControlLinearizer::ValueEffectControl
1630 EffectControlLinearizer::LowerCheckedInt32ToTaggedSigned(Node* node,
1631 Node* frame_state,
1632 Node* effect,
1633 Node* control) {
1634 DCHECK(SmiValuesAre31Bits()); 1356 DCHECK(SmiValuesAre31Bits());
1635 Node* value = node->InputAt(0); 1357 Node* value = node->InputAt(0);
1636 1358
1637 Node* add = graph()->NewNode(machine()->Int32AddWithOverflow(), value, value, 1359 Node* add = __ Int32AddWithOverflow(value, value);
1638 control); 1360 Node* check = __ Projection(1, add);
1639 1361 __ DeoptimizeIf(DeoptimizeReason::kOverflow, check, frame_state);
1640 Node* check = graph()->NewNode(common()->Projection(1), add, control); 1362 return __ Projection(0, add);
1641 control = effect = 1363 }
1642 graph()->NewNode(common()->DeoptimizeIf(DeoptimizeReason::kOverflow), 1364
1643 check, frame_state, effect, control); 1365 Node* EffectControlLinearizer::LowerCheckedUint32ToInt32(Node* node,
1644 1366 Node* frame_state) {
1645 value = graph()->NewNode(common()->Projection(0), add, control); 1367 Node* value = node->InputAt(0);
1646 1368 Node* max_int = __ Int32Constant(std::numeric_limits<int32_t>::max());
1647 return ValueEffectControl(value, effect, control); 1369 Node* is_safe = __ Uint32LessThanOrEqual(value, max_int);
1648 } 1370 __ DeoptimizeUnless(DeoptimizeReason::kLostPrecision, is_safe, frame_state);
1649 1371 return value;
1650 EffectControlLinearizer::ValueEffectControl 1372 }
1651 EffectControlLinearizer::LowerCheckedUint32ToInt32(Node* node, 1373
1652 Node* frame_state, 1374 Node* EffectControlLinearizer::LowerCheckedUint32ToTaggedSigned(
1653 Node* effect, 1375 Node* node, Node* frame_state) {
1654 Node* control) { 1376 Node* value = node->InputAt(0);
1655 Node* value = node->InputAt(0); 1377 Node* check = __ Uint32LessThanOrEqual(value, SmiMaxValueConstant());
1656 Node* max_int = jsgraph()->Int32Constant(std::numeric_limits<int32_t>::max()); 1378 __ DeoptimizeUnless(DeoptimizeReason::kLostPrecision, check, frame_state);
1657 Node* is_safe = 1379 return ChangeUint32ToSmi(value);
1658 graph()->NewNode(machine()->Uint32LessThanOrEqual(), value, max_int); 1380 }
1659 control = effect = graph()->NewNode( 1381
1660 common()->DeoptimizeUnless(DeoptimizeReason::kLostPrecision), is_safe, 1382 Node* EffectControlLinearizer::BuildCheckedFloat64ToInt32(
1661 frame_state, effect, control); 1383 CheckForMinusZeroMode mode, Node* value, Node* frame_state) {
1662 1384 Node* value32 = __ RoundFloat64ToInt32(value);
1663 return ValueEffectControl(value, effect, control); 1385 Node* check_same = __ Float64Equal(value, __ ChangeInt32ToFloat64(value32));
1664 } 1386 __ DeoptimizeUnless(DeoptimizeReason::kLostPrecisionOrNaN, check_same,
1665 1387 frame_state);
1666 EffectControlLinearizer::ValueEffectControl
1667 EffectControlLinearizer::LowerCheckedUint32ToTaggedSigned(Node* node,
1668 Node* frame_state,
1669 Node* effect,
1670 Node* control) {
1671 Node* value = node->InputAt(0);
1672 Node* check = graph()->NewNode(machine()->Uint32LessThanOrEqual(), value,
1673 SmiMaxValueConstant());
1674 control = effect = graph()->NewNode(
1675 common()->DeoptimizeUnless(DeoptimizeReason::kLostPrecision), check,
1676 frame_state, effect, control);
1677 value = ChangeUint32ToSmi(value);
1678
1679 return ValueEffectControl(value, effect, control);
1680 }
1681
1682 EffectControlLinearizer::ValueEffectControl
1683 EffectControlLinearizer::BuildCheckedFloat64ToInt32(CheckForMinusZeroMode mode,
1684 Node* value,
1685 Node* frame_state,
1686 Node* effect,
1687 Node* control) {
1688 Node* value32 = graph()->NewNode(machine()->RoundFloat64ToInt32(), value);
1689 Node* check_same = graph()->NewNode(
1690 machine()->Float64Equal(), value,
1691 graph()->NewNode(machine()->ChangeInt32ToFloat64(), value32));
1692 control = effect = graph()->NewNode(
1693 common()->DeoptimizeUnless(DeoptimizeReason::kLostPrecisionOrNaN),
1694 check_same, frame_state, effect, control);
1695 1388
1696 if (mode == CheckForMinusZeroMode::kCheckForMinusZero) { 1389 if (mode == CheckForMinusZeroMode::kCheckForMinusZero) {
1697 // Check if {value} is -0. 1390 // Check if {value} is -0.
1698 Node* check_zero = graph()->NewNode(machine()->Word32Equal(), value32, 1391 auto if_zero = __ MakeDeferredLabel<1>();
1699 jsgraph()->Int32Constant(0)); 1392 auto check_done = __ MakeLabel<2>();
1700 Node* branch_zero = graph()->NewNode(common()->Branch(BranchHint::kFalse), 1393
1701 check_zero, control); 1394 Node* check_zero = __ Word32Equal(value32, __ Int32Constant(0));
1702 1395 __ GotoIf(check_zero, &if_zero);
1703 Node* if_zero = graph()->NewNode(common()->IfTrue(), branch_zero); 1396 __ Goto(&check_done);
1704 Node* if_notzero = graph()->NewNode(common()->IfFalse(), branch_zero); 1397
1705 1398 __ Bind(&if_zero);
1706 // In case of 0, we need to check the high bits for the IEEE -0 pattern. 1399 // In case of 0, we need to check the high bits for the IEEE -0 pattern.
1707 Node* check_negative = graph()->NewNode( 1400 Node* check_negative = __ Int32LessThan(__ Float64ExtractHighWord32(value),
1708 machine()->Int32LessThan(), 1401 __ Int32Constant(0));
1709 graph()->NewNode(machine()->Float64ExtractHighWord32(), value), 1402 __ DeoptimizeIf(DeoptimizeReason::kMinusZero, check_negative, frame_state);
1710 jsgraph()->Int32Constant(0)); 1403 __ Goto(&check_done);
1711 1404
1712 Node* deopt_minus_zero = 1405 __ Bind(&check_done);
1713 graph()->NewNode(common()->DeoptimizeIf(DeoptimizeReason::kMinusZero), 1406 }
1714 check_negative, frame_state, effect, if_zero); 1407 return value32;
1715 1408 }
1716 control = 1409
1717 graph()->NewNode(common()->Merge(2), deopt_minus_zero, if_notzero); 1410 Node* EffectControlLinearizer::LowerCheckedFloat64ToInt32(Node* node,
1718 effect = graph()->NewNode(common()->EffectPhi(2), deopt_minus_zero, effect, 1411 Node* frame_state) {
1719 control);
1720 }
1721
1722 return ValueEffectControl(value32, effect, control);
1723 }
1724
1725 EffectControlLinearizer::ValueEffectControl
1726 EffectControlLinearizer::LowerCheckedFloat64ToInt32(Node* node,
1727 Node* frame_state,
1728 Node* effect,
1729 Node* control) {
1730 CheckForMinusZeroMode mode = CheckMinusZeroModeOf(node->op()); 1412 CheckForMinusZeroMode mode = CheckMinusZeroModeOf(node->op());
1731 Node* value = node->InputAt(0); 1413 Node* value = node->InputAt(0);
1732 1414 return BuildCheckedFloat64ToInt32(mode, value, frame_state);
1733 return BuildCheckedFloat64ToInt32(mode, value, frame_state, effect, control); 1415 }
1734 } 1416
1735 1417 Node* EffectControlLinearizer::LowerCheckedTaggedSignedToInt32(
1736 EffectControlLinearizer::ValueEffectControl 1418 Node* node, Node* frame_state) {
1737 EffectControlLinearizer::LowerCheckedTaggedSignedToInt32(Node* node, 1419 Node* value = node->InputAt(0);
1738 Node* frame_state, 1420 Node* check = ObjectIsSmi(value);
1739 Node* effect, 1421 __ DeoptimizeUnless(DeoptimizeReason::kNotASmi, check, frame_state);
1740 Node* control) { 1422 return ChangeSmiToInt32(value);
1741 Node* value = node->InputAt(0); 1423 }
1742 1424
1743 Node* check = ObjectIsSmi(value); 1425 Node* EffectControlLinearizer::LowerCheckedTaggedToInt32(Node* node,
1744 control = effect = 1426 Node* frame_state) {
1745 graph()->NewNode(common()->DeoptimizeUnless(DeoptimizeReason::kNotASmi),
1746 check, frame_state, effect, control);
1747 value = ChangeSmiToInt32(value);
1748
1749 return ValueEffectControl(value, effect, control);
1750 }
1751
1752 EffectControlLinearizer::ValueEffectControl
1753 EffectControlLinearizer::LowerCheckedTaggedToInt32(Node* node,
1754 Node* frame_state,
1755 Node* effect,
1756 Node* control) {
1757 CheckForMinusZeroMode mode = CheckMinusZeroModeOf(node->op()); 1427 CheckForMinusZeroMode mode = CheckMinusZeroModeOf(node->op());
1758 Node* value = node->InputAt(0); 1428 Node* value = node->InputAt(0);
1759 1429
1760 Node* check = ObjectIsSmi(value); 1430 auto if_not_smi = __ MakeDeferredLabel<1>();
1761 Node* branch = 1431 auto done = __ MakeLabel<2>(MachineRepresentation::kWord32);
1762 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); 1432
1763 1433 Node* check = ObjectIsSmi(value);
1434 __ GotoUnless(check, &if_not_smi);
1764 // In the Smi case, just convert to int32. 1435 // In the Smi case, just convert to int32.
1765 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); 1436 __ Goto(&done, ChangeSmiToInt32(value));
1766 Node* etrue = effect;
1767 Node* vtrue = ChangeSmiToInt32(value);
1768 1437
1769 // In the non-Smi case, check the heap numberness, load the number and convert 1438 // In the non-Smi case, check the heap numberness, load the number and convert
1770 // to int32. 1439 // to int32.
1771 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); 1440 __ Bind(&if_not_smi);
1772 Node* efalse = effect; 1441 Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
1773 Node* vfalse; 1442 Node* check_map = __ WordEqual(value_map, __ HeapNumberMapConstant());
1774 { 1443 __ DeoptimizeUnless(DeoptimizeReason::kNotAHeapNumber, check_map,
1775 Node* value_map = efalse = 1444 frame_state);
1776 graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), 1445 Node* vfalse = __ LoadField(AccessBuilder::ForHeapNumberValue(), value);
1777 value, efalse, if_false); 1446 vfalse = BuildCheckedFloat64ToInt32(mode, vfalse, frame_state);
1778 Node* check = graph()->NewNode(machine()->WordEqual(), value_map, 1447 __ Goto(&done, vfalse);
1779 jsgraph()->HeapNumberMapConstant()); 1448
1780 if_false = efalse = graph()->NewNode( 1449 __ Bind(&done);
1781 common()->DeoptimizeUnless(DeoptimizeReason::kNotAHeapNumber), check, 1450 return done.PhiAt(0);
1782 frame_state, efalse, if_false); 1451 }
1783 vfalse = efalse = graph()->NewNode( 1452
1784 simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), value, 1453 Node* EffectControlLinearizer::BuildCheckedHeapNumberOrOddballToFloat64(
1785 efalse, if_false); 1454 CheckTaggedInputMode mode, Node* value, Node* frame_state) {
1786 ValueEffectControl state = 1455 Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
1787 BuildCheckedFloat64ToInt32(mode, vfalse, frame_state, efalse, if_false); 1456 Node* check_number = __ WordEqual(value_map, __ HeapNumberMapConstant());
1788 if_false = state.control;
1789 efalse = state.effect;
1790 vfalse = state.value;
1791 }
1792
1793 control = graph()->NewNode(common()->Merge(2), if_true, if_false);
1794 effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control);
1795 value = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
1796 vtrue, vfalse, control);
1797
1798 return ValueEffectControl(value, effect, control);
1799 }
1800
1801 EffectControlLinearizer::ValueEffectControl
1802 EffectControlLinearizer::BuildCheckedHeapNumberOrOddballToFloat64(
1803 CheckTaggedInputMode mode, Node* value, Node* frame_state, Node* effect,
1804 Node* control) {
1805 Node* value_map = effect = graph()->NewNode(
1806 simplified()->LoadField(AccessBuilder::ForMap()), value, effect, control);
1807
1808 Node* check_number = graph()->NewNode(machine()->WordEqual(), value_map,
1809 jsgraph()->HeapNumberMapConstant());
1810
1811 switch (mode) { 1457 switch (mode) {
1812 case CheckTaggedInputMode::kNumber: { 1458 case CheckTaggedInputMode::kNumber: {
1813 control = effect = graph()->NewNode( 1459 __ DeoptimizeUnless(DeoptimizeReason::kNotAHeapNumber, check_number,
1814 common()->DeoptimizeUnless(DeoptimizeReason::kNotAHeapNumber), 1460 frame_state);
1815 check_number, frame_state, effect, control);
1816 break; 1461 break;
1817 } 1462 }
1818 case CheckTaggedInputMode::kNumberOrOddball: { 1463 case CheckTaggedInputMode::kNumberOrOddball: {
1819 Node* branch = 1464 auto check_done = __ MakeLabel<2>();
1820 graph()->NewNode(common()->Branch(), check_number, control); 1465
1821 1466 __ GotoIf(check_number, &check_done);
1822 Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
1823 Node* etrue = effect;
1824
1825 Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
1826 // For oddballs also contain the numeric value, let us just check that 1467 // For oddballs also contain the numeric value, let us just check that
1827 // we have an oddball here. 1468 // we have an oddball here.
1828 Node* efalse = effect; 1469 Node* instance_type =
1829 Node* instance_type = efalse = graph()->NewNode( 1470 __ LoadField(AccessBuilder::ForMapInstanceType(), value_map);
1830 simplified()->LoadField(AccessBuilder::ForMapInstanceType()),
1831 value_map, efalse, if_false);
1832 Node* check_oddball = 1471 Node* check_oddball =
1833 graph()->NewNode(machine()->Word32Equal(), instance_type, 1472 __ Word32Equal(instance_type, __ Int32Constant(ODDBALL_TYPE));
1834 jsgraph()->Int32Constant(ODDBALL_TYPE)); 1473 __ DeoptimizeUnless(DeoptimizeReason::kNotANumberOrOddball, check_oddball,
1835 if_false = efalse = graph()->NewNode( 1474 frame_state);
1836 common()->DeoptimizeUnless(DeoptimizeReason::kNotANumberOrOddball),
1837 check_oddball, frame_state, efalse, if_false);
1838 STATIC_ASSERT(HeapNumber::kValueOffset == Oddball::kToNumberRawOffset); 1475 STATIC_ASSERT(HeapNumber::kValueOffset == Oddball::kToNumberRawOffset);
1839 1476 __ Goto(&check_done);
1840 control = graph()->NewNode(common()->Merge(2), if_true, if_false); 1477
1841 effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control); 1478 __ Bind(&check_done);
1842 break; 1479 break;
1843 } 1480 }
1844 } 1481 }
1845 1482 return __ LoadField(AccessBuilder::ForHeapNumberValue(), value);
1846 value = effect = graph()->NewNode( 1483 }
1847 simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), value, 1484
1848 effect, control); 1485 Node* EffectControlLinearizer::LowerCheckedTaggedToFloat64(Node* node,
1849 return ValueEffectControl(value, effect, control); 1486 Node* frame_state) {
1850 }
1851
1852 EffectControlLinearizer::ValueEffectControl
1853 EffectControlLinearizer::LowerCheckedTaggedToFloat64(Node* node,
1854 Node* frame_state,
1855 Node* effect,
1856 Node* control) {
1857 CheckTaggedInputMode mode = CheckTaggedInputModeOf(node->op()); 1487 CheckTaggedInputMode mode = CheckTaggedInputModeOf(node->op());
1858 Node* value = node->InputAt(0); 1488 Node* value = node->InputAt(0);
1859 1489
1860 Node* check = ObjectIsSmi(value); 1490 auto if_smi = __ MakeLabel<1>();
1861 Node* branch = graph()->NewNode(common()->Branch(), check, control); 1491 auto done = __ MakeLabel<2>(MachineRepresentation::kFloat64);
1492
1493 Node* check = ObjectIsSmi(value);
1494 __ GotoIf(check, &if_smi);
1862 1495
1863 // In the Smi case, just convert to int32 and then float64. 1496 // In the Smi case, just convert to int32 and then float64.
1864 Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
1865 Node* etrue = effect;
1866 Node* vtrue = ChangeSmiToInt32(value);
1867 vtrue = graph()->NewNode(machine()->ChangeInt32ToFloat64(), vtrue);
1868
1869 // Otherwise, check heap numberness and load the number. 1497 // Otherwise, check heap numberness and load the number.
1870 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); 1498 Node* number =
1871 ValueEffectControl number_state = BuildCheckedHeapNumberOrOddballToFloat64( 1499 BuildCheckedHeapNumberOrOddballToFloat64(mode, value, frame_state);
1872 mode, value, frame_state, effect, if_false); 1500 __ Goto(&done, number);
1873 1501
1874 Node* merge = 1502 __ Bind(&if_smi);
1875 graph()->NewNode(common()->Merge(2), if_true, number_state.control); 1503 Node* from_smi = ChangeSmiToInt32(value);
1876 Node* effect_phi = graph()->NewNode(common()->EffectPhi(2), etrue, 1504 from_smi = __ ChangeInt32ToFloat64(from_smi);
1877 number_state.effect, merge); 1505 __ Goto(&done, from_smi);
1878 Node* result = 1506
1879 graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), vtrue, 1507 __ Bind(&done);
1880 number_state.value, merge); 1508 return done.PhiAt(0);
1881 1509 }
1882 return ValueEffectControl(result, effect_phi, merge); 1510
1883 } 1511 Node* EffectControlLinearizer::LowerCheckedTaggedToTaggedSigned(
1884 1512 Node* node, Node* frame_state) {
1885 EffectControlLinearizer::ValueEffectControl 1513 Node* value = node->InputAt(0);
1886 EffectControlLinearizer::LowerCheckedTaggedToTaggedSigned(Node* node, 1514
1887 Node* frame_state, 1515 Node* check = ObjectIsSmi(value);
1888 Node* effect, 1516 __ DeoptimizeUnless(DeoptimizeReason::kNotASmi, check, frame_state);
1889 Node* control) { 1517
1890 Node* value = node->InputAt(0); 1518 return value;
1891 1519 }
1892 Node* check = ObjectIsSmi(value); 1520
1893 control = effect = 1521 Node* EffectControlLinearizer::LowerCheckedTaggedToTaggedPointer(
1894 graph()->NewNode(common()->DeoptimizeUnless(DeoptimizeReason::kNotASmi), 1522 Node* node, Node* frame_state) {
1895 check, frame_state, effect, control); 1523 Node* value = node->InputAt(0);
1896 1524
1897 return ValueEffectControl(value, effect, control); 1525 Node* check = ObjectIsSmi(value);
1898 } 1526 __ DeoptimizeIf(DeoptimizeReason::kSmi, check, frame_state);
1899 1527 return value;
1900 EffectControlLinearizer::ValueEffectControl 1528 }
1901 EffectControlLinearizer::LowerCheckedTaggedToTaggedPointer(Node* node, 1529
1902 Node* frame_state, 1530 Node* EffectControlLinearizer::LowerTruncateTaggedToWord32(Node* node) {
1903 Node* effect, 1531 Node* value = node->InputAt(0);
1904 Node* control) { 1532
1905 Node* value = node->InputAt(0); 1533 auto if_not_smi = __ MakeDeferredLabel<1>();
1906 1534 auto done = __ MakeLabel<2>(MachineRepresentation::kWord32);
1907 Node* check = ObjectIsSmi(value); 1535
1908 control = effect = 1536 Node* check = ObjectIsSmi(value);
1909 graph()->NewNode(common()->DeoptimizeIf(DeoptimizeReason::kSmi), check, 1537 __ GotoUnless(check, &if_not_smi);
1910 frame_state, effect, control); 1538 __ Goto(&done, ChangeSmiToInt32(value));
1911 1539
1912 return ValueEffectControl(value, effect, control); 1540 __ Bind(&if_not_smi);
1913 } 1541 STATIC_ASSERT(HeapNumber::kValueOffset == Oddball::kToNumberRawOffset);
1914 1542 Node* vfalse = __ LoadField(AccessBuilder::ForHeapNumberValue(), value);
1915 EffectControlLinearizer::ValueEffectControl 1543 vfalse = __ TruncateFloat64ToWord32(vfalse);
1916 EffectControlLinearizer::LowerTruncateTaggedToWord32(Node* node, Node* effect, 1544 __ Goto(&done, vfalse);
1917 Node* control) { 1545
1918 Node* value = node->InputAt(0); 1546 __ Bind(&done);
1919 1547 return done.PhiAt(0);
1920 Node* check = ObjectIsSmi(value); 1548 }
1921 Node* branch = 1549
1922 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); 1550 Node* EffectControlLinearizer::LowerCheckedTruncateTaggedToWord32(
1923 1551 Node* node, Node* frame_state) {
1924 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); 1552 Node* value = node->InputAt(0);
1925 Node* etrue = effect; 1553
1926 Node* vtrue = ChangeSmiToInt32(value); 1554 auto if_not_smi = __ MakeLabel<1>();
1927 1555 auto done = __ MakeLabel<2>(MachineRepresentation::kWord32);
1928 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); 1556
1929 Node* efalse = effect; 1557 Node* check = ObjectIsSmi(value);
1930 Node* vfalse; 1558 __ GotoUnless(check, &if_not_smi);
1931 {
1932 STATIC_ASSERT(HeapNumber::kValueOffset == Oddball::kToNumberRawOffset);
1933 vfalse = efalse = graph()->NewNode(
1934 simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), value,
1935 efalse, if_false);
1936 vfalse = graph()->NewNode(machine()->TruncateFloat64ToWord32(), vfalse);
1937 }
1938
1939 control = graph()->NewNode(common()->Merge(2), if_true, if_false);
1940 effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control);
1941 value = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
1942 vtrue, vfalse, control);
1943
1944 return ValueEffectControl(value, effect, control);
1945 }
1946
1947 EffectControlLinearizer::ValueEffectControl
1948 EffectControlLinearizer::LowerCheckedTruncateTaggedToWord32(Node* node,
1949 Node* frame_state,
1950 Node* effect,
1951 Node* control) {
1952 Node* value = node->InputAt(0);
1953
1954 Node* check = ObjectIsSmi(value);
1955 Node* branch =
1956 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
1957
1958 // In the Smi case, just convert to int32. 1559 // In the Smi case, just convert to int32.
1959 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); 1560 __ Goto(&done, ChangeSmiToInt32(value));
1960 Node* etrue = effect;
1961 Node* vtrue = ChangeSmiToInt32(value);
1962 1561
1963 // Otherwise, check that it's a heap number or oddball and truncate the value 1562 // Otherwise, check that it's a heap number or oddball and truncate the value
1964 // to int32. 1563 // to int32.
1965 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); 1564 __ Bind(&if_not_smi);
1966 ValueEffectControl false_state = BuildCheckedHeapNumberOrOddballToFloat64( 1565 Node* number = BuildCheckedHeapNumberOrOddballToFloat64(
1967 CheckTaggedInputMode::kNumberOrOddball, value, frame_state, effect, 1566 CheckTaggedInputMode::kNumberOrOddball, value, frame_state);
1968 if_false); 1567 number = __ TruncateFloat64ToWord32(number);
1969 false_state.value = 1568 __ Goto(&done, number);
1970 graph()->NewNode(machine()->TruncateFloat64ToWord32(), false_state.value); 1569
1971 1570 __ Bind(&done);
1972 Node* merge = 1571 return done.PhiAt(0);
1973 graph()->NewNode(common()->Merge(2), if_true, false_state.control); 1572 }
1974 Node* effect_phi = graph()->NewNode(common()->EffectPhi(2), etrue, 1573
1975 false_state.effect, merge); 1574 Node* EffectControlLinearizer::LowerObjectIsCallable(Node* node) {
1976 Node* result = 1575 Node* value = node->InputAt(0);
1977 graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2), vtrue, 1576
1978 false_state.value, merge); 1577 auto if_smi = __ MakeDeferredLabel<1>();
1979 1578 auto done = __ MakeLabel<2>(MachineRepresentation::kBit);
1980 return ValueEffectControl(result, effect_phi, merge); 1579
1981 } 1580 Node* check = ObjectIsSmi(value);
1982 1581 __ GotoIf(check, &if_smi);
1983 EffectControlLinearizer::ValueEffectControl 1582
1984 EffectControlLinearizer::LowerObjectIsCallable(Node* node, Node* effect, 1583 Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
1985 Node* control) { 1584 Node* value_bit_field =
1986 Node* value = node->InputAt(0); 1585 __ LoadField(AccessBuilder::ForMapBitField(), value_map);
1987 1586 Node* vfalse = __ Word32Equal(
1988 Node* check = ObjectIsSmi(value); 1587 __ Int32Constant(1 << Map::kIsCallable),
1989 Node* branch = 1588 __ Word32And(value_bit_field,
1990 graph()->NewNode(common()->Branch(BranchHint::kFalse), check, control); 1589 __ Int32Constant((1 << Map::kIsCallable) |
1991 1590 (1 << Map::kIsUndetectable))));
1992 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); 1591 __ Goto(&done, vfalse);
1993 Node* etrue = effect; 1592
1994 Node* vtrue = jsgraph()->Int32Constant(0); 1593 __ Bind(&if_smi);
1995 1594 __ Goto(&done, __ Int32Constant(0));
1996 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); 1595
1997 Node* efalse = effect; 1596 __ Bind(&done);
1998 Node* vfalse; 1597 return done.PhiAt(0);
1999 { 1598 }
2000 Node* value_map = efalse = 1599
2001 graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), 1600 Node* EffectControlLinearizer::LowerObjectIsNumber(Node* node) {
2002 value, efalse, if_false); 1601 Node* value = node->InputAt(0);
2003 Node* value_bit_field = efalse = graph()->NewNode( 1602
2004 simplified()->LoadField(AccessBuilder::ForMapBitField()), value_map, 1603 auto if_smi = __ MakeLabel<1>();
2005 efalse, if_false); 1604 auto done = __ MakeLabel<2>(MachineRepresentation::kBit);
2006 vfalse = graph()->NewNode( 1605
2007 machine()->Word32Equal(), 1606 __ GotoIf(ObjectIsSmi(value), &if_smi);
2008 jsgraph()->Int32Constant(1 << Map::kIsCallable), 1607 Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
2009 graph()->NewNode( 1608 __ Goto(&done, __ WordEqual(value_map, __ HeapNumberMapConstant()));
2010 machine()->Word32And(), value_bit_field, 1609
2011 jsgraph()->Int32Constant((1 << Map::kIsCallable) | 1610 __ Bind(&if_smi);
2012 (1 << Map::kIsUndetectable)))); 1611 __ Goto(&done, __ Int32Constant(1));
2013 } 1612
2014 1613 __ Bind(&done);
2015 control = graph()->NewNode(common()->Merge(2), if_true, if_false); 1614 return done.PhiAt(0);
2016 effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control); 1615 }
2017 value = graph()->NewNode(common()->Phi(MachineRepresentation::kBit, 2), vtrue, 1616
2018 vfalse, control); 1617 Node* EffectControlLinearizer::LowerObjectIsReceiver(Node* node) {
2019 1618 Node* value = node->InputAt(0);
2020 return ValueEffectControl(value, effect, control); 1619
2021 } 1620 auto if_smi = __ MakeDeferredLabel<1>();
2022 1621 auto done = __ MakeLabel<2>(MachineRepresentation::kBit);
2023 EffectControlLinearizer::ValueEffectControl 1622
2024 EffectControlLinearizer::LowerObjectIsNumber(Node* node, Node* effect, 1623 __ GotoIf(ObjectIsSmi(value), &if_smi);
2025 Node* control) { 1624
2026 Node* value = node->InputAt(0); 1625 STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE);
2027 1626 Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
2028 Node* check = ObjectIsSmi(value); 1627 Node* value_instance_type =
2029 Node* branch = graph()->NewNode(common()->Branch(), check, control); 1628 __ LoadField(AccessBuilder::ForMapInstanceType(), value_map);
2030 1629 Node* result = __ Uint32LessThanOrEqual(
2031 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); 1630 __ Uint32Constant(FIRST_JS_RECEIVER_TYPE), value_instance_type);
2032 Node* etrue = effect; 1631 __ Goto(&done, result);
2033 Node* vtrue = jsgraph()->Int32Constant(1); 1632
2034 1633 __ Bind(&if_smi);
2035 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); 1634 __ Goto(&done, __ Int32Constant(0));
2036 Node* efalse = effect; 1635
2037 Node* vfalse; 1636 __ Bind(&done);
2038 { 1637 return done.PhiAt(0);
2039 Node* value_map = efalse = 1638 }
2040 graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), 1639
2041 value, efalse, if_false); 1640 Node* EffectControlLinearizer::LowerObjectIsSmi(Node* node) {
2042 vfalse = graph()->NewNode(machine()->WordEqual(), value_map, 1641 Node* value = node->InputAt(0);
2043 jsgraph()->HeapNumberMapConstant()); 1642 return ObjectIsSmi(value);
2044 } 1643 }
2045 1644
2046 control = graph()->NewNode(common()->Merge(2), if_true, if_false); 1645 Node* EffectControlLinearizer::LowerObjectIsString(Node* node) {
2047 effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control); 1646 Node* value = node->InputAt(0);
2048 value = graph()->NewNode(common()->Phi(MachineRepresentation::kBit, 2), vtrue, 1647
2049 vfalse, control); 1648 auto if_smi = __ MakeDeferredLabel<1>();
2050 1649 auto done = __ MakeLabel<2>(MachineRepresentation::kBit);
2051 return ValueEffectControl(value, effect, control); 1650
2052 } 1651 Node* check = ObjectIsSmi(value);
2053 1652 __ GotoIf(check, &if_smi);
2054 EffectControlLinearizer::ValueEffectControl 1653 Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
2055 EffectControlLinearizer::LowerObjectIsReceiver(Node* node, Node* effect, 1654 Node* value_instance_type =
2056 Node* control) { 1655 __ LoadField(AccessBuilder::ForMapInstanceType(), value_map);
2057 Node* value = node->InputAt(0); 1656 Node* vfalse = __ Uint32LessThan(value_instance_type,
2058 1657 __ Uint32Constant(FIRST_NONSTRING_TYPE));
2059 Node* check = ObjectIsSmi(value); 1658 __ Goto(&done, vfalse);
2060 Node* branch = 1659
2061 graph()->NewNode(common()->Branch(BranchHint::kFalse), check, control); 1660 __ Bind(&if_smi);
2062 1661 __ Goto(&done, __ Int32Constant(0));
2063 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); 1662
2064 Node* etrue = effect; 1663 __ Bind(&done);
2065 Node* vtrue = jsgraph()->Int32Constant(0); 1664 return done.PhiAt(0);
2066 1665 }
2067 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); 1666
2068 Node* efalse = effect; 1667 Node* EffectControlLinearizer::LowerObjectIsUndetectable(Node* node) {
2069 Node* vfalse; 1668 Node* value = node->InputAt(0);
2070 { 1669
2071 STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE); 1670 auto if_smi = __ MakeDeferredLabel<1>();
2072 Node* value_map = efalse = 1671 auto done = __ MakeLabel<2>(MachineRepresentation::kBit);
2073 graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), 1672
2074 value, efalse, if_false); 1673 Node* check = ObjectIsSmi(value);
2075 Node* value_instance_type = efalse = graph()->NewNode( 1674 __ GotoIf(check, &if_smi);
2076 simplified()->LoadField(AccessBuilder::ForMapInstanceType()), value_map, 1675
2077 efalse, if_false); 1676 Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
2078 vfalse = graph()->NewNode(machine()->Uint32LessThanOrEqual(), 1677 Node* value_bit_field =
2079 jsgraph()->Uint32Constant(FIRST_JS_RECEIVER_TYPE), 1678 __ LoadField(AccessBuilder::ForMapBitField(), value_map);
2080 value_instance_type); 1679 Node* vfalse = __ Word32Equal(
2081 } 1680 __ Word32Equal(__ Int32Constant(0),
2082 1681 __ Word32And(value_bit_field,
2083 control = graph()->NewNode(common()->Merge(2), if_true, if_false); 1682 __ Int32Constant(1 << Map::kIsUndetectable))),
2084 effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control); 1683 __ Int32Constant(0));
2085 value = graph()->NewNode(common()->Phi(MachineRepresentation::kBit, 2), vtrue, 1684 __ Goto(&done, vfalse);
2086 vfalse, control); 1685
2087 1686 __ Bind(&if_smi);
2088 return ValueEffectControl(value, effect, control); 1687 __ Goto(&done, __ Int32Constant(0));
2089 } 1688
2090 1689 __ Bind(&done);
2091 EffectControlLinearizer::ValueEffectControl 1690 return done.PhiAt(0);
2092 EffectControlLinearizer::LowerObjectIsSmi(Node* node, Node* effect, 1691 }
2093 Node* control) { 1692
2094 Node* value = node->InputAt(0); 1693 Node* EffectControlLinearizer::LowerNewRestParameterElements(Node* node) {
2095 value = ObjectIsSmi(value);
2096 return ValueEffectControl(value, effect, control);
2097 }
2098
2099 EffectControlLinearizer::ValueEffectControl
2100 EffectControlLinearizer::LowerObjectIsString(Node* node, Node* effect,
2101 Node* control) {
2102 Node* value = node->InputAt(0);
2103
2104 Node* check = ObjectIsSmi(value);
2105 Node* branch =
2106 graph()->NewNode(common()->Branch(BranchHint::kFalse), check, control);
2107
2108 Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
2109 Node* etrue = effect;
2110 Node* vtrue = jsgraph()->Int32Constant(0);
2111
2112 Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
2113 Node* efalse = effect;
2114 Node* vfalse;
2115 {
2116 Node* value_map = efalse =
2117 graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
2118 value, efalse, if_false);
2119 Node* value_instance_type = efalse = graph()->NewNode(
2120 simplified()->LoadField(AccessBuilder::ForMapInstanceType()), value_map,
2121 efalse, if_false);
2122 vfalse = graph()->NewNode(machine()->Uint32LessThan(), value_instance_type,
2123 jsgraph()->Uint32Constant(FIRST_NONSTRING_TYPE));
2124 }
2125
2126 control = graph()->NewNode(common()->Merge(2), if_true, if_false);
2127 effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control);
2128 value = graph()->NewNode(common()->Phi(MachineRepresentation::kBit, 2), vtrue,
2129 vfalse, control);
2130
2131 return ValueEffectControl(value, effect, control);
2132 }
2133
2134 EffectControlLinearizer::ValueEffectControl
2135 EffectControlLinearizer::LowerObjectIsUndetectable(Node* node, Node* effect,
2136 Node* control) {
2137 Node* value = node->InputAt(0);
2138
2139 Node* check = ObjectIsSmi(value);
2140 Node* branch =
2141 graph()->NewNode(common()->Branch(BranchHint::kFalse), check, control);
2142
2143 Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
2144 Node* etrue = effect;
2145 Node* vtrue = jsgraph()->Int32Constant(0);
2146
2147 Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
2148 Node* efalse = effect;
2149 Node* vfalse;
2150 {
2151 Node* value_map = efalse =
2152 graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
2153 value, efalse, if_false);
2154 Node* value_bit_field = efalse = graph()->NewNode(
2155 simplified()->LoadField(AccessBuilder::ForMapBitField()), value_map,
2156 efalse, if_false);
2157 vfalse = graph()->NewNode(
2158 machine()->Word32Equal(),
2159 graph()->NewNode(
2160 machine()->Word32Equal(), jsgraph()->Int32Constant(0),
2161 graph()->NewNode(
2162 machine()->Word32And(), value_bit_field,
2163 jsgraph()->Int32Constant(1 << Map::kIsUndetectable))),
2164 jsgraph()->Int32Constant(0));
2165 }
2166
2167 control = graph()->NewNode(common()->Merge(2), if_true, if_false);
2168 effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control);
2169 value = graph()->NewNode(common()->Phi(MachineRepresentation::kBit, 2), vtrue,
2170 vfalse, control);
2171
2172 return ValueEffectControl(value, effect, control);
2173 }
2174
2175 EffectControlLinearizer::ValueEffectControl
2176 EffectControlLinearizer::LowerNewRestParameterElements(Node* node, Node* effect,
2177 Node* control) {
2178 int const formal_parameter_count = ParameterCountOf(node->op()); 1694 int const formal_parameter_count = ParameterCountOf(node->op());
2179 1695
2180 Callable const callable = CodeFactory::NewRestParameterElements(isolate()); 1696 Callable const callable = CodeFactory::NewRestParameterElements(isolate());
2181 Operator::Properties const properties = node->op()->properties(); 1697 Operator::Properties const properties = node->op()->properties();
2182 CallDescriptor::Flags const flags = CallDescriptor::kNoFlags; 1698 CallDescriptor::Flags const flags = CallDescriptor::kNoFlags;
2183 CallDescriptor* desc = Linkage::GetStubCallDescriptor( 1699 CallDescriptor* desc = Linkage::GetStubCallDescriptor(
2184 isolate(), graph()->zone(), callable.descriptor(), 0, flags, properties); 1700 isolate(), graph()->zone(), callable.descriptor(), 0, flags, properties);
2185 Node* value = effect = graph()->NewNode( 1701 return __ Call(desc, __ HeapConstant(callable.code()),
2186 common()->Call(desc), jsgraph()->HeapConstant(callable.code()), 1702 __ IntPtrConstant(formal_parameter_count),
2187 jsgraph()->IntPtrConstant(formal_parameter_count), 1703 __ NoContextConstant());
2188 jsgraph()->NoContextConstant(), effect);
2189 return ValueEffectControl(value, effect, control);
2190 } 1704 }
2191 1705
2192 EffectControlLinearizer::ValueEffectControl 1706 Node* EffectControlLinearizer::LowerNewUnmappedArgumentsElements(Node* node) {
2193 EffectControlLinearizer::LowerNewUnmappedArgumentsElements(Node* node,
2194 Node* effect,
2195 Node* control) {
2196 int const formal_parameter_count = ParameterCountOf(node->op()); 1707 int const formal_parameter_count = ParameterCountOf(node->op());
2197 1708
2198 Callable const callable = 1709 Callable const callable =
2199 CodeFactory::NewUnmappedArgumentsElements(isolate()); 1710 CodeFactory::NewUnmappedArgumentsElements(isolate());
2200 Operator::Properties const properties = node->op()->properties(); 1711 Operator::Properties const properties = node->op()->properties();
2201 CallDescriptor::Flags const flags = CallDescriptor::kNoFlags; 1712 CallDescriptor::Flags const flags = CallDescriptor::kNoFlags;
2202 CallDescriptor* desc = Linkage::GetStubCallDescriptor( 1713 CallDescriptor* desc = Linkage::GetStubCallDescriptor(
2203 isolate(), graph()->zone(), callable.descriptor(), 0, flags, properties); 1714 isolate(), graph()->zone(), callable.descriptor(), 0, flags, properties);
2204 Node* value = effect = graph()->NewNode( 1715 return __ Call(desc, __ HeapConstant(callable.code()),
2205 common()->Call(desc), jsgraph()->HeapConstant(callable.code()), 1716 __ IntPtrConstant(formal_parameter_count),
2206 jsgraph()->IntPtrConstant(formal_parameter_count), 1717 __ NoContextConstant());
2207 jsgraph()->NoContextConstant(), effect);
2208 return ValueEffectControl(value, effect, control);
2209 } 1718 }
2210 1719
2211 EffectControlLinearizer::ValueEffectControl 1720 Node* EffectControlLinearizer::LowerArrayBufferWasNeutered(Node* node) {
2212 EffectControlLinearizer::LowerArrayBufferWasNeutered(Node* node, Node* effect,
2213 Node* control) {
2214 Node* value = node->InputAt(0); 1721 Node* value = node->InputAt(0);
2215 1722
2216 Node* value_bit_field = effect = graph()->NewNode( 1723 Node* value_bit_field =
2217 simplified()->LoadField(AccessBuilder::ForJSArrayBufferBitField()), value, 1724 __ LoadField(AccessBuilder::ForJSArrayBufferBitField(), value);
2218 effect, control); 1725 return __ Word32Equal(
2219 value = graph()->NewNode( 1726 __ Word32Equal(
2220 machine()->Word32Equal(), 1727 __ Word32And(value_bit_field,
2221 graph()->NewNode(machine()->Word32Equal(), 1728 __ Int32Constant(JSArrayBuffer::WasNeutered::kMask)),
2222 graph()->NewNode(machine()->Word32And(), value_bit_field, 1729 __ Int32Constant(0)),
2223 jsgraph()->Int32Constant( 1730 __ Int32Constant(0));
2224 JSArrayBuffer::WasNeutered::kMask)),
2225 jsgraph()->Int32Constant(0)),
2226 jsgraph()->Int32Constant(0));
2227
2228 return ValueEffectControl(value, effect, control);
2229 } 1731 }
2230 1732
2231 EffectControlLinearizer::ValueEffectControl 1733 Node* EffectControlLinearizer::LowerStringCharAt(Node* node) {
2232 EffectControlLinearizer::LowerStringCharAt(Node* node, Node* effect, 1734 Node* receiver = node->InputAt(0);
2233 Node* control) { 1735 Node* position = node->InputAt(1);
1736
2234 Callable const callable = CodeFactory::StringCharAt(isolate()); 1737 Callable const callable = CodeFactory::StringCharAt(isolate());
2235 Operator::Properties properties = Operator::kNoThrow | Operator::kNoWrite; 1738 Operator::Properties properties = Operator::kNoThrow | Operator::kNoWrite;
2236 CallDescriptor::Flags flags = CallDescriptor::kNoFlags; 1739 CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
2237 CallDescriptor* desc = Linkage::GetStubCallDescriptor( 1740 CallDescriptor* desc = Linkage::GetStubCallDescriptor(
2238 isolate(), graph()->zone(), callable.descriptor(), 0, flags, properties); 1741 isolate(), graph()->zone(), callable.descriptor(), 0, flags, properties);
2239 node->InsertInput(graph()->zone(), 0, 1742 return __ Call(desc, __ HeapConstant(callable.code()), receiver, position,
2240 jsgraph()->HeapConstant(callable.code())); 1743 __ NoContextConstant());
2241 node->InsertInput(graph()->zone(), 3, jsgraph()->NoContextConstant());
2242 node->InsertInput(graph()->zone(), 4, effect);
2243 NodeProperties::ChangeOp(node, common()->Call(desc));
2244 return ValueEffectControl(node, node, control);
2245 } 1744 }
2246 1745
2247 EffectControlLinearizer::ValueEffectControl 1746 Node* EffectControlLinearizer::LowerStringCharCodeAt(Node* node) {
2248 EffectControlLinearizer::LowerStringCharCodeAt(Node* node, Node* effect, 1747 Node* receiver = node->InputAt(0);
2249 Node* control) { 1748 Node* position = node->InputAt(1);
1749
2250 Callable const callable = CodeFactory::StringCharCodeAt(isolate()); 1750 Callable const callable = CodeFactory::StringCharCodeAt(isolate());
2251 Operator::Properties properties = Operator::kNoThrow | Operator::kNoWrite; 1751 Operator::Properties properties = Operator::kNoThrow | Operator::kNoWrite;
2252 CallDescriptor::Flags flags = CallDescriptor::kNoFlags; 1752 CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
2253 CallDescriptor* desc = Linkage::GetStubCallDescriptor( 1753 CallDescriptor* desc = Linkage::GetStubCallDescriptor(
2254 isolate(), graph()->zone(), callable.descriptor(), 0, flags, properties, 1754 isolate(), graph()->zone(), callable.descriptor(), 0, flags, properties,
2255 MachineType::TaggedSigned()); 1755 MachineType::TaggedSigned());
2256 node->InsertInput(graph()->zone(), 0, 1756 return __ Call(desc, __ HeapConstant(callable.code()), receiver, position,
2257 jsgraph()->HeapConstant(callable.code())); 1757 __ NoContextConstant());
2258 node->InsertInput(graph()->zone(), 3, jsgraph()->NoContextConstant());
2259 node->InsertInput(graph()->zone(), 4, effect);
2260 NodeProperties::ChangeOp(node, common()->Call(desc));
2261 return ValueEffectControl(node, node, control);
2262 } 1758 }
2263 1759
2264 EffectControlLinearizer::ValueEffectControl 1760 Node* EffectControlLinearizer::LowerStringFromCharCode(Node* node) {
2265 EffectControlLinearizer::LowerStringFromCharCode(Node* node, Node* effect,
2266 Node* control) {
2267 Node* value = node->InputAt(0); 1761 Node* value = node->InputAt(0);
2268 1762
1763 auto runtime_call = __ MakeDeferredLabel<2>();
1764 auto if_undefined = __ MakeDeferredLabel<1>();
1765 auto done = __ MakeLabel<2>(MachineRepresentation::kTagged);
1766
2269 // Compute the character code. 1767 // Compute the character code.
2270 Node* code = 1768 Node* code = __ Word32And(value, __ Int32Constant(String::kMaxUtf16CodeUnit));
2271 graph()->NewNode(machine()->Word32And(), value,
2272 jsgraph()->Int32Constant(String::kMaxUtf16CodeUnit));
2273 1769
2274 // Check if the {code} is a one-byte char code. 1770 // Check if the {code} is a one-byte char code.
2275 Node* check0 = 1771 Node* check0 = __ Int32LessThanOrEqual(
2276 graph()->NewNode(machine()->Int32LessThanOrEqual(), code, 1772 code, __ Int32Constant(String::kMaxOneByteCharCode));
2277 jsgraph()->Int32Constant(String::kMaxOneByteCharCode)); 1773 __ GotoUnless(check0, &runtime_call);
2278 Node* branch0 =
2279 graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control);
2280
2281 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
2282 Node* efalse0 = effect;
2283
2284 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
2285 Node* etrue0 = effect;
2286 1774
2287 // Load the isolate wide single character string cache. 1775 // Load the isolate wide single character string cache.
2288 Node* cache = 1776 Node* cache = __ HeapConstant(factory()->single_character_string_cache());
2289 jsgraph()->HeapConstant(factory()->single_character_string_cache());
2290 1777
2291 // Compute the {cache} index for {code}. 1778 // Compute the {cache} index for {code}.
2292 Node* index = machine()->Is32() 1779 Node* index = machine()->Is32() ? code : __ ChangeUint32ToUint64(code);
2293 ? code
2294 : graph()->NewNode(machine()->ChangeUint32ToUint64(), code);
2295 1780
2296 // Check if we have an entry for the {code} in the single character string 1781 // Check if we have an entry for the {code} in the single character string
2297 // cache already. 1782 // cache already.
2298 Node* entry = etrue0 = graph()->NewNode( 1783 Node* entry =
2299 simplified()->LoadElement(AccessBuilder::ForFixedArrayElement()), cache, 1784 __ LoadElement(AccessBuilder::ForFixedArrayElement(), cache, index);
2300 index, etrue0, if_true0);
2301 1785
2302 Node* check1 = graph()->NewNode(machine()->WordEqual(), entry, 1786 Node* check1 = __ WordEqual(entry, __ UndefinedConstant());
2303 jsgraph()->UndefinedConstant()); 1787 __ GotoIf(check1, &runtime_call);
2304 Node* branch1 = 1788 __ Goto(&done, entry);
2305 graph()->NewNode(common()->Branch(BranchHint::kFalse), check1, if_true0);
2306
2307 // Use the {entry} from the {cache}.
2308 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
2309 Node* efalse1 = etrue0;
2310 Node* vfalse1 = entry;
2311 1789
2312 // Let %StringFromCharCode handle this case. 1790 // Let %StringFromCharCode handle this case.
2313 // TODO(turbofan): At some point we may consider adding a stub for this 1791 // TODO(turbofan): At some point we may consider adding a stub for this
2314 // deferred case, so that we don't need to call to C++ here. 1792 // deferred case, so that we don't need to call to C++ here.
2315 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); 1793 __ Bind(&runtime_call);
2316 Node* etrue1 = etrue0;
2317 Node* vtrue1;
2318 { 1794 {
2319 if_true1 = graph()->NewNode(common()->Merge(2), if_true1, if_false0);
2320 etrue1 =
2321 graph()->NewNode(common()->EffectPhi(2), etrue1, efalse0, if_true1);
2322 Operator::Properties properties = Operator::kNoDeopt | Operator::kNoThrow; 1795 Operator::Properties properties = Operator::kNoDeopt | Operator::kNoThrow;
2323 Runtime::FunctionId id = Runtime::kStringCharFromCode; 1796 Runtime::FunctionId id = Runtime::kStringCharFromCode;
2324 CallDescriptor const* desc = Linkage::GetRuntimeCallDescriptor( 1797 CallDescriptor const* desc = Linkage::GetRuntimeCallDescriptor(
2325 graph()->zone(), id, 1, properties, CallDescriptor::kNoFlags); 1798 graph()->zone(), id, 1, properties, CallDescriptor::kNoFlags);
2326 vtrue1 = etrue1 = graph()->NewNode( 1799 Node* vtrue1 =
2327 common()->Call(desc), jsgraph()->CEntryStubConstant(1), 1800 __ Call(desc, __ CEntryStubConstant(1), ChangeInt32ToSmi(code),
2328 ChangeInt32ToSmi(code), 1801 __ ExternalConstant(ExternalReference(id, isolate())),
2329 jsgraph()->ExternalConstant(ExternalReference(id, isolate())), 1802 __ Int32Constant(1), __ NoContextConstant());
2330 jsgraph()->Int32Constant(1), jsgraph()->NoContextConstant(), etrue1, 1803 __ Goto(&done, vtrue1);
2331 if_true1);
2332 } 1804 }
2333 1805 __ Bind(&done);
2334 control = graph()->NewNode(common()->Merge(2), if_true1, if_false1); 1806 return done.PhiAt(0);
2335 effect = graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, control);
2336 value = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
2337 vtrue1, vfalse1, control);
2338
2339 return ValueEffectControl(value, effect, control);
2340 } 1807 }
2341 1808
2342 EffectControlLinearizer::ValueEffectControl 1809 Node* EffectControlLinearizer::LowerStringFromCodePoint(Node* node) {
2343 EffectControlLinearizer::LowerStringFromCodePoint(Node* node, Node* effect,
2344 Node* control) {
2345 Node* value = node->InputAt(0); 1810 Node* value = node->InputAt(0);
2346 Node* code = value; 1811 Node* code = value;
2347 1812
2348 Node* etrue0 = effect; 1813 auto if_not_single_code = __ MakeDeferredLabel<1>();
2349 Node* vtrue0; 1814 auto if_not_one_byte = __ MakeDeferredLabel<1>();
1815 auto cache_miss = __ MakeDeferredLabel<1>();
1816 auto done = __ MakeLabel<4>(MachineRepresentation::kTagged);
2350 1817
2351 // Check if the {code} is a single code unit 1818 // Check if the {code} is a single code unit
2352 Node* check0 = graph()->NewNode(machine()->Uint32LessThanOrEqual(), code, 1819 Node* check0 = __ Uint32LessThanOrEqual(code, __ Uint32Constant(0xFFFF));
2353 jsgraph()->Uint32Constant(0xFFFF)); 1820 __ GotoUnless(check0, &if_not_single_code);
2354 Node* branch0 =
2355 graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control);
2356 1821
2357 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
2358 { 1822 {
2359 // Check if the {code} is a one byte character 1823 // Check if the {code} is a one byte character
2360 Node* check1 = graph()->NewNode( 1824 Node* check1 = __ Uint32LessThanOrEqual(
2361 machine()->Uint32LessThanOrEqual(), code, 1825 code, __ Uint32Constant(String::kMaxOneByteCharCode));
2362 jsgraph()->Uint32Constant(String::kMaxOneByteCharCode)); 1826 __ GotoUnless(check1, &if_not_one_byte);
2363 Node* branch1 =
2364 graph()->NewNode(common()->Branch(BranchHint::kTrue), check1, if_true0);
2365
2366 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
2367 Node* etrue1 = etrue0;
2368 Node* vtrue1;
2369 { 1827 {
2370 // Load the isolate wide single character string cache. 1828 // Load the isolate wide single character string cache.
2371 Node* cache = 1829 Node* cache = __ HeapConstant(factory()->single_character_string_cache());
2372 jsgraph()->HeapConstant(factory()->single_character_string_cache());
2373 1830
2374 // Compute the {cache} index for {code}. 1831 // Compute the {cache} index for {code}.
2375 Node* index = 1832 Node* index = machine()->Is32() ? code : __ ChangeUint32ToUint64(code);
2376 machine()->Is32()
2377 ? code
2378 : graph()->NewNode(machine()->ChangeUint32ToUint64(), code);
2379 1833
2380 // Check if we have an entry for the {code} in the single character string 1834 // Check if we have an entry for the {code} in the single character string
2381 // cache already. 1835 // cache already.
2382 Node* entry = etrue1 = graph()->NewNode( 1836 Node* entry =
2383 simplified()->LoadElement(AccessBuilder::ForFixedArrayElement()), 1837 __ LoadElement(AccessBuilder::ForFixedArrayElement(), cache, index);
2384 cache, index, etrue1, if_true1);
2385 1838
2386 Node* check2 = graph()->NewNode(machine()->WordEqual(), entry, 1839 Node* check2 = __ WordEqual(entry, __ UndefinedConstant());
2387 jsgraph()->UndefinedConstant()); 1840 __ GotoIf(check2, &cache_miss);
2388 Node* branch2 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
2389 check2, if_true1);
2390 1841
2391 Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2); 1842 // Use the {entry} from the {cache}.
2392 Node* etrue2 = etrue1; 1843 __ Goto(&done, entry);
2393 Node* vtrue2; 1844
1845 __ Bind(&cache_miss);
2394 { 1846 {
2395 // Allocate a new SeqOneByteString for {code}. 1847 // Allocate a new SeqOneByteString for {code}.
2396 vtrue2 = etrue2 = graph()->NewNode( 1848 Node* vtrue2 = __ Allocate(
2397 simplified()->Allocate(NOT_TENURED), 1849 NOT_TENURED, __ Int32Constant(SeqOneByteString::SizeFor(1)));
2398 jsgraph()->Int32Constant(SeqOneByteString::SizeFor(1)), etrue2, 1850 __ StoreField(AccessBuilder::ForMap(), vtrue2,
2399 if_true2); 1851 __ HeapConstant(factory()->one_byte_string_map()));
2400 etrue2 = graph()->NewNode( 1852 __ StoreField(AccessBuilder::ForNameHashField(), vtrue2,
2401 simplified()->StoreField(AccessBuilder::ForMap()), vtrue2, 1853 __ IntPtrConstant(Name::kEmptyHashField));
2402 jsgraph()->HeapConstant(factory()->one_byte_string_map()), etrue2, 1854 __ StoreField(AccessBuilder::ForStringLength(), vtrue2,
2403 if_true2); 1855 __ SmiConstant(1));
2404 etrue2 = graph()->NewNode( 1856 __ Store(
2405 simplified()->StoreField(AccessBuilder::ForNameHashField()), vtrue2, 1857 StoreRepresentation(MachineRepresentation::kWord8, kNoWriteBarrier),
2406 jsgraph()->IntPtrConstant(Name::kEmptyHashField), etrue2, if_true2); 1858 vtrue2,
2407 etrue2 = graph()->NewNode( 1859 __ IntPtrConstant(SeqOneByteString::kHeaderSize - kHeapObjectTag),
2408 simplified()->StoreField(AccessBuilder::ForStringLength()), vtrue2, 1860 code);
2409 jsgraph()->SmiConstant(1), etrue2, if_true2);
2410 etrue2 = graph()->NewNode(
2411 machine()->Store(StoreRepresentation(MachineRepresentation::kWord8,
2412 kNoWriteBarrier)),
2413 vtrue2, jsgraph()->IntPtrConstant(SeqOneByteString::kHeaderSize -
2414 kHeapObjectTag),
2415 code, etrue2, if_true2);
2416 1861
2417 // Remember it in the {cache}. 1862 // Remember it in the {cache}.
2418 etrue2 = graph()->NewNode( 1863 __ StoreElement(AccessBuilder::ForFixedArrayElement(), cache, index,
2419 simplified()->StoreElement(AccessBuilder::ForFixedArrayElement()), 1864 vtrue2);
2420 cache, index, vtrue2, etrue2, if_true2); 1865 __ Goto(&done, vtrue2);
2421 } 1866 }
2422
2423 // Use the {entry} from the {cache}.
2424 Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
2425 Node* efalse2 = etrue0;
2426 Node* vfalse2 = entry;
2427
2428 if_true1 = graph()->NewNode(common()->Merge(2), if_true2, if_false2);
2429 etrue1 =
2430 graph()->NewNode(common()->EffectPhi(2), etrue2, efalse2, if_true1);
2431 vtrue1 =
2432 graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
2433 vtrue2, vfalse2, if_true1);
2434 } 1867 }
2435 1868
2436 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); 1869 __ Bind(&if_not_one_byte);
2437 Node* efalse1 = effect;
2438 Node* vfalse1;
2439 { 1870 {
2440 // Allocate a new SeqTwoByteString for {code}. 1871 // Allocate a new SeqTwoByteString for {code}.
2441 vfalse1 = efalse1 = graph()->NewNode( 1872 Node* vfalse1 = __ Allocate(
2442 simplified()->Allocate(NOT_TENURED), 1873 NOT_TENURED, __ Int32Constant(SeqTwoByteString::SizeFor(1)));
2443 jsgraph()->Int32Constant(SeqTwoByteString::SizeFor(1)), efalse1, 1874 __ StoreField(AccessBuilder::ForMap(), vfalse1,
2444 if_false1); 1875 __ HeapConstant(factory()->string_map()));
2445 efalse1 = graph()->NewNode( 1876 __ StoreField(AccessBuilder::ForNameHashField(), vfalse1,
2446 simplified()->StoreField(AccessBuilder::ForMap()), vfalse1, 1877 __ IntPtrConstant(Name::kEmptyHashField));
2447 jsgraph()->HeapConstant(factory()->string_map()), efalse1, if_false1); 1878 __ StoreField(AccessBuilder::ForStringLength(), vfalse1,
2448 efalse1 = graph()->NewNode( 1879 __ SmiConstant(1));
2449 simplified()->StoreField(AccessBuilder::ForNameHashField()), vfalse1, 1880 __ Store(
2450 jsgraph()->IntPtrConstant(Name::kEmptyHashField), efalse1, if_false1); 1881 StoreRepresentation(MachineRepresentation::kWord16, kNoWriteBarrier),
2451 efalse1 = graph()->NewNode( 1882 vfalse1,
2452 simplified()->StoreField(AccessBuilder::ForStringLength()), vfalse1, 1883 __ IntPtrConstant(SeqTwoByteString::kHeaderSize - kHeapObjectTag),
2453 jsgraph()->SmiConstant(1), efalse1, if_false1); 1884 code);
2454 efalse1 = graph()->NewNode( 1885 __ Goto(&done, vfalse1);
2455 machine()->Store(StoreRepresentation(MachineRepresentation::kWord16,
2456 kNoWriteBarrier)),
2457 vfalse1, jsgraph()->IntPtrConstant(SeqTwoByteString::kHeaderSize -
2458 kHeapObjectTag),
2459 code, efalse1, if_false1);
2460 } 1886 }
2461
2462 if_true0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
2463 etrue0 =
2464 graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, if_true0);
2465 vtrue0 = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
2466 vtrue1, vfalse1, if_true0);
2467 } 1887 }
2468 1888
1889 __ Bind(&if_not_single_code);
2469 // Generate surrogate pair string 1890 // Generate surrogate pair string
2470 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
2471 Node* efalse0 = effect;
2472 Node* vfalse0;
2473 { 1891 {
2474 switch (UnicodeEncodingOf(node->op())) { 1892 switch (UnicodeEncodingOf(node->op())) {
2475 case UnicodeEncoding::UTF16: 1893 case UnicodeEncoding::UTF16:
2476 break; 1894 break;
2477 1895
2478 case UnicodeEncoding::UTF32: { 1896 case UnicodeEncoding::UTF32: {
2479 // Convert UTF32 to UTF16 code units, and store as a 32 bit word. 1897 // Convert UTF32 to UTF16 code units, and store as a 32 bit word.
2480 Node* lead_offset = jsgraph()->Int32Constant(0xD800 - (0x10000 >> 10)); 1898 Node* lead_offset = __ Int32Constant(0xD800 - (0x10000 >> 10));
2481 1899
2482 // lead = (codepoint >> 10) + LEAD_OFFSET 1900 // lead = (codepoint >> 10) + LEAD_OFFSET
2483 Node* lead = 1901 Node* lead =
2484 graph()->NewNode(machine()->Int32Add(), 1902 __ Int32Add(__ Word32Shr(code, __ Int32Constant(10)), lead_offset);
2485 graph()->NewNode(machine()->Word32Shr(), code,
2486 jsgraph()->Int32Constant(10)),
2487 lead_offset);
2488 1903
2489 // trail = (codepoint & 0x3FF) + 0xDC00; 1904 // trail = (codepoint & 0x3FF) + 0xDC00;
2490 Node* trail = 1905 Node* trail = __ Int32Add(__ Word32And(code, __ Int32Constant(0x3FF)),
2491 graph()->NewNode(machine()->Int32Add(), 1906 __ Int32Constant(0xDC00));
2492 graph()->NewNode(machine()->Word32And(), code,
2493 jsgraph()->Int32Constant(0x3FF)),
2494 jsgraph()->Int32Constant(0xDC00));
2495 1907
2496 // codpoint = (trail << 16) | lead; 1908 // codpoint = (trail << 16) | lead;
2497 code = graph()->NewNode(machine()->Word32Or(), 1909 code = __ Word32Or(__ Word32Shl(trail, __ Int32Constant(16)), lead);
2498 graph()->NewNode(machine()->Word32Shl(), trail,
2499 jsgraph()->Int32Constant(16)),
2500 lead);
2501 break; 1910 break;
2502 } 1911 }
2503 } 1912 }
2504 1913
2505 // Allocate a new SeqTwoByteString for {code}. 1914 // Allocate a new SeqTwoByteString for {code}.
2506 vfalse0 = efalse0 = 1915 Node* vfalse0 = __ Allocate(NOT_TENURED,
2507 graph()->NewNode(simplified()->Allocate(NOT_TENURED), 1916 __ Int32Constant(SeqTwoByteString::SizeFor(2)));
2508 jsgraph()->Int32Constant(SeqTwoByteString::SizeFor(2)), 1917 __ StoreField(AccessBuilder::ForMap(), vfalse0,
2509 efalse0, if_false0); 1918 __ HeapConstant(factory()->string_map()));
2510 efalse0 = graph()->NewNode( 1919 __ StoreField(AccessBuilder::ForNameHashField(), vfalse0,
2511 simplified()->StoreField(AccessBuilder::ForMap()), vfalse0, 1920 __ IntPtrConstant(Name::kEmptyHashField));
2512 jsgraph()->HeapConstant(factory()->string_map()), efalse0, if_false0); 1921 __ StoreField(AccessBuilder::ForStringLength(), vfalse0, __ SmiConstant(2));
2513 efalse0 = graph()->NewNode( 1922 __ Store(
2514 simplified()->StoreField(AccessBuilder::ForNameHashField()), vfalse0, 1923 StoreRepresentation(MachineRepresentation::kWord32, kNoWriteBarrier),
2515 jsgraph()->IntPtrConstant(Name::kEmptyHashField), efalse0, if_false0); 1924 vfalse0,
2516 efalse0 = graph()->NewNode( 1925 __ IntPtrConstant(SeqTwoByteString::kHeaderSize - kHeapObjectTag),
2517 simplified()->StoreField(AccessBuilder::ForStringLength()), vfalse0, 1926 code);
2518 jsgraph()->SmiConstant(2), efalse0, if_false0); 1927 __ Goto(&done, vfalse0);
2519 efalse0 = graph()->NewNode( 1928 }
2520 machine()->Store(StoreRepresentation(MachineRepresentation::kWord32, 1929
2521 kNoWriteBarrier)), 1930 __ Bind(&done);
2522 vfalse0, jsgraph()->IntPtrConstant(SeqTwoByteString::kHeaderSize - 1931 return done.PhiAt(0);
2523 kHeapObjectTag), 1932 }
2524 code, efalse0, if_false0); 1933
2525 } 1934 Node* EffectControlLinearizer::LowerStringComparison(Callable const& callable,
2526 1935 Node* node) {
2527 control = graph()->NewNode(common()->Merge(2), if_true0, if_false0); 1936 Node* lhs = node->InputAt(0);
2528 effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control); 1937 Node* rhs = node->InputAt(1);
2529 value = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2), 1938
2530 vtrue0, vfalse0, control);
2531
2532 return ValueEffectControl(value, effect, control);
2533 }
2534
2535 EffectControlLinearizer::ValueEffectControl
2536 EffectControlLinearizer::LowerStringComparison(Callable const& callable,
2537 Node* node, Node* effect,
2538 Node* control) {
2539 Operator::Properties properties = Operator::kEliminatable; 1939 Operator::Properties properties = Operator::kEliminatable;
2540 CallDescriptor::Flags flags = CallDescriptor::kNoFlags; 1940 CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
2541 CallDescriptor* desc = Linkage::GetStubCallDescriptor( 1941 CallDescriptor* desc = Linkage::GetStubCallDescriptor(
2542 isolate(), graph()->zone(), callable.descriptor(), 0, flags, properties); 1942 isolate(), graph()->zone(), callable.descriptor(), 0, flags, properties);
2543 node->InsertInput(graph()->zone(), 0, 1943 return __ Call(desc, __ HeapConstant(callable.code()), lhs, rhs,
2544 jsgraph()->HeapConstant(callable.code())); 1944 __ NoContextConstant());
2545 node->AppendInput(graph()->zone(), jsgraph()->NoContextConstant()); 1945 }
2546 node->AppendInput(graph()->zone(), effect); 1946
2547 NodeProperties::ChangeOp(node, common()->Call(desc)); 1947 Node* EffectControlLinearizer::LowerStringEqual(Node* node) {
2548 return ValueEffectControl(node, node, control); 1948 return LowerStringComparison(CodeFactory::StringEqual(isolate()), node);
2549 } 1949 }
2550 1950
2551 EffectControlLinearizer::ValueEffectControl 1951 Node* EffectControlLinearizer::LowerStringLessThan(Node* node) {
2552 EffectControlLinearizer::LowerStringEqual(Node* node, Node* effect, 1952 return LowerStringComparison(CodeFactory::StringLessThan(isolate()), node);
2553 Node* control) { 1953 }
2554 return LowerStringComparison(CodeFactory::StringEqual(isolate()), node, 1954
2555 effect, control); 1955 Node* EffectControlLinearizer::LowerStringLessThanOrEqual(Node* node) {
2556 }
2557
2558 EffectControlLinearizer::ValueEffectControl
2559 EffectControlLinearizer::LowerStringLessThan(Node* node, Node* effect,
2560 Node* control) {
2561 return LowerStringComparison(CodeFactory::StringLessThan(isolate()), node,
2562 effect, control);
2563 }
2564
2565 EffectControlLinearizer::ValueEffectControl
2566 EffectControlLinearizer::LowerStringLessThanOrEqual(Node* node, Node* effect,
2567 Node* control) {
2568 return LowerStringComparison(CodeFactory::StringLessThanOrEqual(isolate()), 1956 return LowerStringComparison(CodeFactory::StringLessThanOrEqual(isolate()),
2569 node, effect, control); 1957 node);
2570 } 1958 }
2571 1959
2572 EffectControlLinearizer::ValueEffectControl 1960 Node* EffectControlLinearizer::LowerCheckFloat64Hole(Node* node,
2573 EffectControlLinearizer::LowerCheckFloat64Hole(Node* node, Node* frame_state, 1961 Node* frame_state) {
2574 Node* effect, Node* control) {
2575 // If we reach this point w/o eliminating the {node} that's marked 1962 // If we reach this point w/o eliminating the {node} that's marked
2576 // with allow-return-hole, we cannot do anything, so just deoptimize 1963 // with allow-return-hole, we cannot do anything, so just deoptimize
2577 // in case of the hole NaN (similar to Crankshaft). 1964 // in case of the hole NaN (similar to Crankshaft).
2578 Node* value = node->InputAt(0); 1965 Node* value = node->InputAt(0);
2579 Node* check = graph()->NewNode( 1966 Node* check = __ Word32Equal(__ Float64ExtractHighWord32(value),
2580 machine()->Word32Equal(), 1967 __ Int32Constant(kHoleNanUpper32));
2581 graph()->NewNode(machine()->Float64ExtractHighWord32(), value), 1968 __ DeoptimizeIf(DeoptimizeReason::kHole, check, frame_state);
2582 jsgraph()->Int32Constant(kHoleNanUpper32)); 1969 return value;
2583 control = effect = 1970 }
2584 graph()->NewNode(common()->DeoptimizeIf(DeoptimizeReason::kHole), check, 1971
2585 frame_state, effect, control); 1972 Node* EffectControlLinearizer::LowerCheckTaggedHole(Node* node,
2586 1973 Node* frame_state) {
2587 return ValueEffectControl(value, effect, control); 1974 Node* value = node->InputAt(0);
2588 } 1975 Node* check = __ WordEqual(value, __ TheHoleConstant());
2589 1976 __ DeoptimizeIf(DeoptimizeReason::kHole, check, frame_state);
2590 EffectControlLinearizer::ValueEffectControl 1977 return value;
2591 EffectControlLinearizer::LowerCheckTaggedHole(Node* node, Node* frame_state, 1978 }
2592 Node* effect, Node* control) { 1979
2593 Node* value = node->InputAt(0); 1980 Node* EffectControlLinearizer::LowerConvertTaggedHoleToUndefined(Node* node) {
2594 Node* check = graph()->NewNode(machine()->WordEqual(), value, 1981 Node* value = node->InputAt(0);
2595 jsgraph()->TheHoleConstant()); 1982
2596 control = effect = 1983 auto if_is_hole = __ MakeDeferredLabel<1>();
2597 graph()->NewNode(common()->DeoptimizeIf(DeoptimizeReason::kHole), check, 1984 auto done = __ MakeLabel<2>(MachineRepresentation::kTagged);
2598 frame_state, effect, control); 1985
2599 1986 Node* check = __ WordEqual(value, __ TheHoleConstant());
2600 return ValueEffectControl(value, effect, control); 1987 __ GotoIf(check, &if_is_hole);
2601 } 1988 __ Goto(&done, value);
2602 1989
2603 EffectControlLinearizer::ValueEffectControl 1990 __ Bind(&if_is_hole);
2604 EffectControlLinearizer::LowerConvertTaggedHoleToUndefined(Node* node, 1991 __ Goto(&done, __ UndefinedConstant());
2605 Node* effect, 1992
2606 Node* control) { 1993 __ Bind(&done);
2607 Node* value = node->InputAt(0); 1994 return done.PhiAt(0);
2608 Node* check = graph()->NewNode(machine()->WordEqual(), value, 1995 }
2609 jsgraph()->TheHoleConstant()); 1996
2610 Node* branch = 1997 Node* EffectControlLinearizer::AllocateHeapNumberWithValue(Node* value) {
2611 graph()->NewNode(common()->Branch(BranchHint::kFalse), check, control); 1998 Node* result = __ Allocate(NOT_TENURED, __ Int32Constant(HeapNumber::kSize));
2612 1999 __ StoreField(AccessBuilder::ForMap(), result, __ HeapNumberMapConstant());
2613 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); 2000 __ StoreField(AccessBuilder::ForHeapNumberValue(), result, value);
2614 Node* vtrue = jsgraph()->UndefinedConstant(); 2001 return result;
2615
2616 Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
2617 Node* vfalse = value;
2618
2619 control = graph()->NewNode(common()->Merge(2), if_true, if_false);
2620 value = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
2621 vtrue, vfalse, control);
2622
2623 return ValueEffectControl(value, effect, control);
2624 }
2625
2626 EffectControlLinearizer::ValueEffectControl
2627 EffectControlLinearizer::AllocateHeapNumberWithValue(Node* value, Node* effect,
2628 Node* control) {
2629 Node* result = effect = graph()->NewNode(
2630 simplified()->Allocate(NOT_TENURED),
2631 jsgraph()->Int32Constant(HeapNumber::kSize), effect, control);
2632 effect = graph()->NewNode(simplified()->StoreField(AccessBuilder::ForMap()),
2633 result, jsgraph()->HeapNumberMapConstant(), effect,
2634 control);
2635 effect = graph()->NewNode(
2636 simplified()->StoreField(AccessBuilder::ForHeapNumberValue()), result,
2637 value, effect, control);
2638 return ValueEffectControl(result, effect, control);
2639 } 2002 }
2640 2003
2641 Node* EffectControlLinearizer::ChangeInt32ToSmi(Node* value) { 2004 Node* EffectControlLinearizer::ChangeInt32ToSmi(Node* value) {
2642 if (machine()->Is64()) { 2005 if (machine()->Is64()) {
2643 value = graph()->NewNode(machine()->ChangeInt32ToInt64(), value); 2006 value = __ ChangeInt32ToInt64(value);
2644 } 2007 }
2645 return graph()->NewNode(machine()->WordShl(), value, SmiShiftBitsConstant()); 2008 return __ WordShl(value, SmiShiftBitsConstant());
2646 } 2009 }
2647 2010
2648 Node* EffectControlLinearizer::ChangeUint32ToSmi(Node* value) { 2011 Node* EffectControlLinearizer::ChangeUint32ToSmi(Node* value) {
2649 if (machine()->Is64()) { 2012 if (machine()->Is64()) {
2650 value = graph()->NewNode(machine()->ChangeUint32ToUint64(), value); 2013 value = __ ChangeUint32ToUint64(value);
2651 } 2014 }
2652 return graph()->NewNode(machine()->WordShl(), value, SmiShiftBitsConstant()); 2015 return __ WordShl(value, SmiShiftBitsConstant());
2653 }
2654
2655 Node* EffectControlLinearizer::ChangeInt32ToFloat64(Node* value) {
2656 return graph()->NewNode(machine()->ChangeInt32ToFloat64(), value);
2657 }
2658
2659 Node* EffectControlLinearizer::ChangeUint32ToFloat64(Node* value) {
2660 return graph()->NewNode(machine()->ChangeUint32ToFloat64(), value);
2661 } 2016 }
2662 2017
2663 Node* EffectControlLinearizer::ChangeSmiToInt32(Node* value) { 2018 Node* EffectControlLinearizer::ChangeSmiToInt32(Node* value) {
2664 value = graph()->NewNode(machine()->WordSar(), value, SmiShiftBitsConstant()); 2019 value = __ WordSar(value, SmiShiftBitsConstant());
2665 if (machine()->Is64()) { 2020 if (machine()->Is64()) {
2666 value = graph()->NewNode(machine()->TruncateInt64ToInt32(), value); 2021 value = __ TruncateInt64ToInt32(value);
2667 } 2022 }
2668 return value; 2023 return value;
2669 } 2024 }
2025
2670 Node* EffectControlLinearizer::ObjectIsSmi(Node* value) { 2026 Node* EffectControlLinearizer::ObjectIsSmi(Node* value) {
2671 return graph()->NewNode( 2027 return __ WordEqual(__ WordAnd(value, __ IntPtrConstant(kSmiTagMask)),
2672 machine()->WordEqual(), 2028 __ IntPtrConstant(kSmiTag));
2673 graph()->NewNode(machine()->WordAnd(), value,
2674 jsgraph()->IntPtrConstant(kSmiTagMask)),
2675 jsgraph()->IntPtrConstant(kSmiTag));
2676 } 2029 }
2677 2030
2678 Node* EffectControlLinearizer::SmiMaxValueConstant() { 2031 Node* EffectControlLinearizer::SmiMaxValueConstant() {
2679 return jsgraph()->Int32Constant(Smi::kMaxValue); 2032 return __ Int32Constant(Smi::kMaxValue);
2680 } 2033 }
2681 2034
2682 Node* EffectControlLinearizer::SmiShiftBitsConstant() { 2035 Node* EffectControlLinearizer::SmiShiftBitsConstant() {
2683 return jsgraph()->IntPtrConstant(kSmiShiftSize + kSmiTagSize); 2036 return __ IntPtrConstant(kSmiShiftSize + kSmiTagSize);
2684 } 2037 }
2685 2038
2686 EffectControlLinearizer::ValueEffectControl 2039 Node* EffectControlLinearizer::LowerPlainPrimitiveToNumber(Node* node) {
2687 EffectControlLinearizer::LowerPlainPrimitiveToNumber(Node* node, Node* effect, 2040 Node* value = node->InputAt(0);
2688 Node* control) { 2041 return __ ToNumber(value);
2689 Node* value = node->InputAt(0); 2042 }
2690 Node* result = effect = 2043
2691 graph()->NewNode(ToNumberOperator(), jsgraph()->ToNumberBuiltinConstant(), 2044 Node* EffectControlLinearizer::LowerPlainPrimitiveToWord32(Node* node) {
2692 value, jsgraph()->NoContextConstant(), effect); 2045 Node* value = node->InputAt(0);
2693 return ValueEffectControl(result, effect, control); 2046
2694 } 2047 auto if_not_smi = __ MakeDeferredLabel<1>();
2695 2048 auto if_to_number_smi = __ MakeLabel<1>();
2696 EffectControlLinearizer::ValueEffectControl 2049 auto done = __ MakeLabel<3>(MachineRepresentation::kWord32);
2697 EffectControlLinearizer::LowerPlainPrimitiveToWord32(Node* node, Node* effect,
2698 Node* control) {
2699 Node* value = node->InputAt(0);
2700 2050
2701 Node* check0 = ObjectIsSmi(value); 2051 Node* check0 = ObjectIsSmi(value);
2702 Node* branch0 = 2052 __ GotoUnless(check0, &if_not_smi);
2703 graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control); 2053 __ Goto(&done, ChangeSmiToInt32(value));
2704 2054
2705 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); 2055 __ Bind(&if_not_smi);
2706 Node* etrue0 = effect; 2056 Node* to_number = __ ToNumber(value);
2707 Node* vtrue0 = ChangeSmiToInt32(value); 2057
2708 2058 Node* check1 = ObjectIsSmi(to_number);
2709 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0); 2059 __ GotoIf(check1, &if_to_number_smi);
2710 Node* efalse0 = effect; 2060 Node* number = __ LoadField(AccessBuilder::ForHeapNumberValue(), to_number);
2711 Node* vfalse0; 2061 __ Goto(&done, __ TruncateFloat64ToWord32(number));
2712 { 2062
2713 vfalse0 = efalse0 = graph()->NewNode( 2063 __ Bind(&if_to_number_smi);
2714 ToNumberOperator(), jsgraph()->ToNumberBuiltinConstant(), value, 2064 __ Goto(&done, ChangeSmiToInt32(to_number));
2715 jsgraph()->NoContextConstant(), efalse0); 2065
2716 2066 __ Bind(&done);
2717 Node* check1 = ObjectIsSmi(vfalse0); 2067 return done.PhiAt(0);
2718 Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_false0); 2068 }
2719 2069
2720 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); 2070 Node* EffectControlLinearizer::LowerPlainPrimitiveToFloat64(Node* node) {
2721 Node* etrue1 = efalse0; 2071 Node* value = node->InputAt(0);
2722 Node* vtrue1 = ChangeSmiToInt32(vfalse0); 2072
2723 2073 auto if_not_smi = __ MakeDeferredLabel<1>();
2724 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); 2074 auto if_to_number_smi = __ MakeLabel<1>();
2725 Node* efalse1 = efalse0; 2075 auto done = __ MakeLabel<3>(MachineRepresentation::kFloat64);
2726 Node* vfalse1;
2727 {
2728 vfalse1 = efalse1 = graph()->NewNode(
2729 simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), efalse0,
2730 efalse1, if_false1);
2731 vfalse1 = graph()->NewNode(machine()->TruncateFloat64ToWord32(), vfalse1);
2732 }
2733
2734 if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
2735 efalse0 =
2736 graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, if_false0);
2737 vfalse0 = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
2738 vtrue1, vfalse1, if_false0);
2739 }
2740
2741 control = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
2742 effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control);
2743 value = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
2744 vtrue0, vfalse0, control);
2745 return ValueEffectControl(value, effect, control);
2746 }
2747
2748 EffectControlLinearizer::ValueEffectControl
2749 EffectControlLinearizer::LowerPlainPrimitiveToFloat64(Node* node, Node* effect,
2750 Node* control) {
2751 Node* value = node->InputAt(0);
2752 2076
2753 Node* check0 = ObjectIsSmi(value); 2077 Node* check0 = ObjectIsSmi(value);
2754 Node* branch0 = 2078 __ GotoUnless(check0, &if_not_smi);
2755 graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control); 2079 Node* from_smi = ChangeSmiToInt32(value);
2756 2080 __ Goto(&done, __ ChangeInt32ToFloat64(from_smi));
2757 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); 2081
2758 Node* etrue0 = effect; 2082 __ Bind(&if_not_smi);
2759 Node* vtrue0; 2083 Node* to_number = __ ToNumber(value);
2760 { 2084 Node* check1 = ObjectIsSmi(to_number);
2761 vtrue0 = ChangeSmiToInt32(value); 2085 __ GotoIf(check1, &if_to_number_smi);
2762 vtrue0 = graph()->NewNode(machine()->ChangeInt32ToFloat64(), vtrue0); 2086
2763 } 2087 Node* number = __ LoadField(AccessBuilder::ForHeapNumberValue(), to_number);
2764 2088 __ Goto(&done, number);
2765 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0); 2089
2766 Node* efalse0 = effect; 2090 __ Bind(&if_to_number_smi);
2767 Node* vfalse0; 2091 Node* number_from_smi = ChangeSmiToInt32(to_number);
2768 { 2092 number_from_smi = __ ChangeInt32ToFloat64(number_from_smi);
2769 vfalse0 = efalse0 = graph()->NewNode( 2093 __ Goto(&done, number_from_smi);
2770 ToNumberOperator(), jsgraph()->ToNumberBuiltinConstant(), value, 2094
2771 jsgraph()->NoContextConstant(), efalse0); 2095 __ Bind(&done);
2772 2096 return done.PhiAt(0);
2773 Node* check1 = ObjectIsSmi(vfalse0); 2097 }
2774 Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_false0); 2098
2775 2099 Node* EffectControlLinearizer::LowerEnsureWritableFastElements(Node* node) {
2776 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
2777 Node* etrue1 = efalse0;
2778 Node* vtrue1;
2779 {
2780 vtrue1 = ChangeSmiToInt32(vfalse0);
2781 vtrue1 = graph()->NewNode(machine()->ChangeInt32ToFloat64(), vtrue1);
2782 }
2783
2784 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
2785 Node* efalse1 = efalse0;
2786 Node* vfalse1;
2787 {
2788 vfalse1 = efalse1 = graph()->NewNode(
2789 simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), efalse0,
2790 efalse1, if_false1);
2791 }
2792
2793 if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
2794 efalse0 =
2795 graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, if_false0);
2796 vfalse0 =
2797 graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
2798 vtrue1, vfalse1, if_false0);
2799 }
2800
2801 control = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
2802 effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control);
2803 value = graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
2804 vtrue0, vfalse0, control);
2805 return ValueEffectControl(value, effect, control);
2806 }
2807
2808 EffectControlLinearizer::ValueEffectControl
2809 EffectControlLinearizer::LowerEnsureWritableFastElements(Node* node,
2810 Node* effect,
2811 Node* control) {
2812 Node* object = node->InputAt(0); 2100 Node* object = node->InputAt(0);
2813 Node* elements = node->InputAt(1); 2101 Node* elements = node->InputAt(1);
2814 2102
2103 auto if_not_fixed_array = __ MakeDeferredLabel<1>();
2104 auto done = __ MakeLabel<2>(MachineRepresentation::kTagged);
2105
2815 // Load the current map of {elements}. 2106 // Load the current map of {elements}.
2816 Node* elements_map = effect = 2107 Node* elements_map = __ LoadField(AccessBuilder::ForMap(), elements);
2817 graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
2818 elements, effect, control);
2819 2108
2820 // Check if {elements} is not a copy-on-write FixedArray. 2109 // Check if {elements} is not a copy-on-write FixedArray.
2821 Node* check = graph()->NewNode(machine()->WordEqual(), elements_map, 2110 Node* check = __ WordEqual(elements_map, __ FixedArrayMapConstant());
2822 jsgraph()->FixedArrayMapConstant()); 2111 __ GotoUnless(check, &if_not_fixed_array);
2823 Node* branch =
2824 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
2825
2826 // Nothing to do if the {elements} are not copy-on-write. 2112 // Nothing to do if the {elements} are not copy-on-write.
2827 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); 2113 __ Goto(&done, elements);
2828 Node* etrue = effect; 2114
2829 Node* vtrue = elements; 2115 __ Bind(&if_not_fixed_array);
2830
2831 // We need to take a copy of the {elements} and set them up for {object}. 2116 // We need to take a copy of the {elements} and set them up for {object}.
2832 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); 2117 Operator::Properties properties = Operator::kEliminatable;
2833 Node* efalse = effect; 2118 Callable callable = CodeFactory::CopyFastSmiOrObjectElements(isolate());
2834 Node* vfalse; 2119 CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
2835 { 2120 CallDescriptor const* const desc = Linkage::GetStubCallDescriptor(
2836 // We need to create a copy of the {elements} for {object}. 2121 isolate(), graph()->zone(), callable.descriptor(), 0, flags, properties);
2837 Operator::Properties properties = Operator::kEliminatable; 2122 Node* result = __ Call(desc, __ HeapConstant(callable.code()), object,
2838 Callable callable = CodeFactory::CopyFastSmiOrObjectElements(isolate()); 2123 __ NoContextConstant());
2839 CallDescriptor::Flags flags = CallDescriptor::kNoFlags; 2124 __ Goto(&done, result);
2840 CallDescriptor const* const desc = Linkage::GetStubCallDescriptor( 2125
2841 isolate(), graph()->zone(), callable.descriptor(), 0, flags, 2126 __ Bind(&done);
2842 properties); 2127 return done.PhiAt(0);
2843 vfalse = efalse = graph()->NewNode( 2128 }
2844 common()->Call(desc), jsgraph()->HeapConstant(callable.code()), object, 2129
2845 jsgraph()->NoContextConstant(), efalse); 2130 Node* EffectControlLinearizer::LowerMaybeGrowFastElements(Node* node,
2846 } 2131 Node* frame_state) {
2847
2848 control = graph()->NewNode(common()->Merge(2), if_true, if_false);
2849 effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control);
2850 Node* value = graph()->NewNode(
2851 common()->Phi(MachineRepresentation::kTagged, 2), vtrue, vfalse, control);
2852
2853 return ValueEffectControl(value, effect, control);
2854 }
2855
2856 EffectControlLinearizer::ValueEffectControl
2857 EffectControlLinearizer::LowerMaybeGrowFastElements(Node* node,
2858 Node* frame_state,
2859 Node* effect,
2860 Node* control) {
2861 GrowFastElementsFlags flags = GrowFastElementsFlagsOf(node->op()); 2132 GrowFastElementsFlags flags = GrowFastElementsFlagsOf(node->op());
2862 Node* object = node->InputAt(0); 2133 Node* object = node->InputAt(0);
2863 Node* elements = node->InputAt(1); 2134 Node* elements = node->InputAt(1);
2864 Node* index = node->InputAt(2); 2135 Node* index = node->InputAt(2);
2865 Node* length = node->InputAt(3); 2136 Node* length = node->InputAt(3);
2866 2137
2867 Node* check0 = graph()->NewNode((flags & GrowFastElementsFlag::kHoleyElements) 2138 auto done = __ MakeLabel<2>(MachineRepresentation::kTagged);
2868 ? machine()->Uint32LessThanOrEqual() 2139 auto done_grow = __ MakeLabel<2>(MachineRepresentation::kTagged);
2869 : machine()->Word32Equal(), 2140 auto if_not_grow = __ MakeLabel<1>();
2870 length, index); 2141 auto if_not_grow_backing_store = __ MakeLabel<1>();
2871 Node* branch0 = graph()->NewNode(common()->Branch(), check0, control); 2142
2872 2143 Node* check0 = (flags & GrowFastElementsFlag::kHoleyElements)
2873 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); 2144 ? __ Uint32LessThanOrEqual(length, index)
2874 Node* etrue0 = effect; 2145 : __ Word32Equal(length, index);
2875 Node* vtrue0 = elements; 2146 __ GotoUnless(check0, &if_not_grow);
2876 { 2147 {
2877 // Load the length of the {elements} backing store. 2148 // Load the length of the {elements} backing store.
2878 Node* elements_length = etrue0 = graph()->NewNode( 2149 Node* elements_length =
2879 simplified()->LoadField(AccessBuilder::ForFixedArrayLength()), elements, 2150 __ LoadField(AccessBuilder::ForFixedArrayLength(), elements);
2880 etrue0, if_true0);
2881 elements_length = ChangeSmiToInt32(elements_length); 2151 elements_length = ChangeSmiToInt32(elements_length);
2882 2152
2883 // Check if we need to grow the {elements} backing store. 2153 // Check if we need to grow the {elements} backing store.
2884 Node* check1 = 2154 Node* check1 = __ Uint32LessThan(index, elements_length);
2885 graph()->NewNode(machine()->Uint32LessThan(), index, elements_length); 2155 __ GotoUnless(check1, &if_not_grow_backing_store);
2886 Node* branch1 = 2156 __ Goto(&done_grow, elements);
2887 graph()->NewNode(common()->Branch(BranchHint::kTrue), check1, if_true0); 2157
2888 2158 __ Bind(&if_not_grow_backing_store);
2889 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); 2159 // We need to grow the {elements} for {object}.
2890 Node* etrue1 = etrue0; 2160 Operator::Properties properties = Operator::kEliminatable;
2891 Node* vtrue1 = vtrue0; 2161 Callable callable =
2892 2162 (flags & GrowFastElementsFlag::kDoubleElements)
2893 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); 2163 ? CodeFactory::GrowFastDoubleElements(isolate())
2894 Node* efalse1 = etrue0; 2164 : CodeFactory::GrowFastSmiOrObjectElements(isolate());
2895 Node* vfalse1 = vtrue0; 2165 CallDescriptor::Flags call_flags = CallDescriptor::kNoFlags;
2896 { 2166 CallDescriptor const* const desc = Linkage::GetStubCallDescriptor(
2897 // We need to grow the {elements} for {object}. 2167 isolate(), graph()->zone(), callable.descriptor(), 0, call_flags,
2898 Operator::Properties properties = Operator::kEliminatable; 2168 properties);
2899 Callable callable = 2169 Node* new_object = __ Call(desc, __ HeapConstant(callable.code()), object,
2900 (flags & GrowFastElementsFlag::kDoubleElements) 2170 ChangeInt32ToSmi(index), __ NoContextConstant());
2901 ? CodeFactory::GrowFastDoubleElements(isolate()) 2171
2902 : CodeFactory::GrowFastSmiOrObjectElements(isolate()); 2172 // Ensure that we were able to grow the {elements}.
2903 CallDescriptor::Flags flags = CallDescriptor::kNoFlags; 2173 // TODO(turbofan): We use kSmi as reason here similar to Crankshaft,
2904 CallDescriptor const* const desc = Linkage::GetStubCallDescriptor( 2174 // but maybe we should just introduce a reason that makes sense.
2905 isolate(), graph()->zone(), callable.descriptor(), 0, flags, 2175 __ DeoptimizeIf(DeoptimizeReason::kSmi, ObjectIsSmi(new_object),
2906 properties); 2176 frame_state);
2907 vfalse1 = efalse1 = graph()->NewNode( 2177 __ Goto(&done_grow, new_object);
2908 common()->Call(desc), jsgraph()->HeapConstant(callable.code()), 2178
2909 object, ChangeInt32ToSmi(index), jsgraph()->NoContextConstant(), 2179 __ Bind(&done_grow);
2910 efalse1);
2911
2912 // Ensure that we were able to grow the {elements}.
2913 // TODO(turbofan): We use kSmi as reason here similar to Crankshaft,
2914 // but maybe we should just introduce a reason that makes sense.
2915 efalse1 = if_false1 = graph()->NewNode(
2916 common()->DeoptimizeIf(DeoptimizeReason::kSmi), ObjectIsSmi(vfalse1),
2917 frame_state, efalse1, if_false1);
2918 }
2919
2920 if_true0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
2921 etrue0 =
2922 graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, if_true0);
2923 vtrue0 = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
2924 vtrue1, vfalse1, if_true0);
2925 2180
2926 // For JSArray {object}s we also need to update the "length". 2181 // For JSArray {object}s we also need to update the "length".
2927 if (flags & GrowFastElementsFlag::kArrayObject) { 2182 if (flags & GrowFastElementsFlag::kArrayObject) {
2928 // Compute the new {length}. 2183 // Compute the new {length}.
2929 Node* object_length = ChangeInt32ToSmi(graph()->NewNode( 2184 Node* object_length =
2930 machine()->Int32Add(), index, jsgraph()->Int32Constant(1))); 2185 ChangeInt32ToSmi(__ Int32Add(index, __ Int32Constant(1)));
2931 2186
2932 // Update the "length" property of the {object}. 2187 // Update the "length" property of the {object}.
2933 etrue0 = 2188 __ StoreField(AccessBuilder::ForJSArrayLength(FAST_ELEMENTS), object,
2934 graph()->NewNode(simplified()->StoreField( 2189 object_length);
2935 AccessBuilder::ForJSArrayLength(FAST_ELEMENTS)),
2936 object, object_length, etrue0, if_true0);
2937 } 2190 }
2938 } 2191 __ Goto(&done, done_grow.PhiAt(0));
2939 2192 }
2940 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0); 2193
2941 Node* efalse0 = effect; 2194 __ Bind(&if_not_grow);
2942 Node* vfalse0 = elements;
2943 { 2195 {
2944 // In case of non-holey {elements}, we need to verify that the {index} is 2196 // In case of non-holey {elements}, we need to verify that the {index} is
2945 // in-bounds, otherwise for holey {elements}, the check above already 2197 // in-bounds, otherwise for holey {elements}, the check above already
2946 // guards the index (and the operator forces {index} to be unsigned). 2198 // guards the index (and the operator forces {index} to be unsigned).
2947 if (!(flags & GrowFastElementsFlag::kHoleyElements)) { 2199 if (!(flags & GrowFastElementsFlag::kHoleyElements)) {
2948 Node* check1 = 2200 Node* check1 = __ Uint32LessThan(index, length);
2949 graph()->NewNode(machine()->Uint32LessThan(), index, length); 2201 __ DeoptimizeUnless(DeoptimizeReason::kOutOfBounds, check1, frame_state);
2950 efalse0 = if_false0 = graph()->NewNode(
2951 common()->DeoptimizeUnless(DeoptimizeReason::kOutOfBounds), check1,
2952 frame_state, efalse0, if_false0);
2953 } 2202 }
2954 } 2203 __ Goto(&done, elements);
2955 2204 }
2956 control = graph()->NewNode(common()->Merge(2), if_true0, if_false0); 2205 __ Bind(&done);
2957 effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control); 2206 return done.PhiAt(0);
2958 Node* value = 2207 }
2959 graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2), vtrue0, 2208
2960 vfalse0, control); 2209 void EffectControlLinearizer::LowerTransitionElementsKind(Node* node) {
2961
2962 return ValueEffectControl(value, effect, control);
2963 }
2964
2965 EffectControlLinearizer::ValueEffectControl
2966 EffectControlLinearizer::LowerTransitionElementsKind(Node* node, Node* effect,
2967 Node* control) {
2968 ElementsTransition const transition = ElementsTransitionOf(node->op()); 2210 ElementsTransition const transition = ElementsTransitionOf(node->op());
2969 Node* object = node->InputAt(0); 2211 Node* object = node->InputAt(0);
2970 Node* source_map = node->InputAt(1); 2212 Node* source_map = node->InputAt(1);
2971 Node* target_map = node->InputAt(2); 2213 Node* target_map = node->InputAt(2);
2972 2214
2215 auto if_map_same = __ MakeDeferredLabel<1>();
2216 auto done = __ MakeLabel<2>();
2217
2973 // Load the current map of {object}. 2218 // Load the current map of {object}.
2974 Node* object_map = effect = 2219 Node* object_map = __ LoadField(AccessBuilder::ForMap(), object);
2975 graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), object,
2976 effect, control);
2977 2220
2978 // Check if {object_map} is the same as {source_map}. 2221 // Check if {object_map} is the same as {source_map}.
2979 Node* check = 2222 Node* check = __ WordEqual(object_map, source_map);
2980 graph()->NewNode(machine()->WordEqual(), object_map, source_map); 2223 __ GotoIf(check, &if_map_same);
2981 Node* branch = 2224 __ Goto(&done);
2982 graph()->NewNode(common()->Branch(BranchHint::kFalse), check, control); 2225
2983 2226 __ Bind(&if_map_same);
2984 // Migrate the {object} from {source_map} to {target_map}. 2227 switch (transition) {
2985 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); 2228 case ElementsTransition::kFastTransition:
2986 Node* etrue = effect; 2229 // In-place migration of {object}, just store the {target_map}.
2987 { 2230 __ StoreField(AccessBuilder::ForMap(), object, target_map);
2988 switch (transition) { 2231 break;
2989 case ElementsTransition::kFastTransition: { 2232 case ElementsTransition::kSlowTransition: {
2990 // In-place migration of {object}, just store the {target_map}. 2233 // Instance migration, call out to the runtime for {object}.
2991 etrue = 2234 Operator::Properties properties = Operator::kNoDeopt | Operator::kNoThrow;
2992 graph()->NewNode(simplified()->StoreField(AccessBuilder::ForMap()), 2235 Runtime::FunctionId id = Runtime::kTransitionElementsKind;
2993 object, target_map, etrue, if_true); 2236 CallDescriptor const* desc = Linkage::GetRuntimeCallDescriptor(
2994 break; 2237 graph()->zone(), id, 2, properties, CallDescriptor::kNoFlags);
2995 } 2238 __ Call(desc, __ CEntryStubConstant(1), object, target_map,
2996 case ElementsTransition::kSlowTransition: { 2239 __ ExternalConstant(ExternalReference(id, isolate())),
2997 // Instance migration, call out to the runtime for {object}. 2240 __ Int32Constant(2), __ NoContextConstant());
2998 Operator::Properties properties = 2241 break;
2999 Operator::kNoDeopt | Operator::kNoThrow;
3000 Runtime::FunctionId id = Runtime::kTransitionElementsKind;
3001 CallDescriptor const* desc = Linkage::GetRuntimeCallDescriptor(
3002 graph()->zone(), id, 2, properties, CallDescriptor::kNoFlags);
3003 etrue = graph()->NewNode(
3004 common()->Call(desc), jsgraph()->CEntryStubConstant(1), object,
3005 target_map,
3006 jsgraph()->ExternalConstant(ExternalReference(id, isolate())),
3007 jsgraph()->Int32Constant(2), jsgraph()->NoContextConstant(), etrue,
3008 if_true);
3009 break;
3010 }
3011 } 2242 }
3012 } 2243 }
3013 2244 __ Goto(&done);
3014 // Nothing to do if the {object} doesn't have the {source_map}. 2245
3015 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); 2246 __ Bind(&done);
3016 Node* efalse = effect; 2247 }
3017 2248
3018 control = graph()->NewNode(common()->Merge(2), if_true, if_false); 2249 Node* EffectControlLinearizer::LowerLoadTypedElement(Node* node) {
3019 effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control);
3020
3021 return ValueEffectControl(nullptr, effect, control);
3022 }
3023
3024 EffectControlLinearizer::ValueEffectControl
3025 EffectControlLinearizer::LowerLoadTypedElement(Node* node, Node* effect,
3026 Node* control) {
3027 ExternalArrayType array_type = ExternalArrayTypeOf(node->op()); 2250 ExternalArrayType array_type = ExternalArrayTypeOf(node->op());
3028 Node* buffer = node->InputAt(0); 2251 Node* buffer = node->InputAt(0);
3029 Node* base = node->InputAt(1); 2252 Node* base = node->InputAt(1);
3030 Node* external = node->InputAt(2); 2253 Node* external = node->InputAt(2);
3031 Node* index = node->InputAt(3); 2254 Node* index = node->InputAt(3);
3032 2255
3033 // We need to keep the {buffer} alive so that the GC will not release the 2256 // We need to keep the {buffer} alive so that the GC will not release the
3034 // ArrayBuffer (if there's any) as long as we are still operating on it. 2257 // ArrayBuffer (if there's any) as long as we are still operating on it.
3035 effect = graph()->NewNode(common()->Retain(), buffer, effect); 2258 __ Retain(buffer);
3036 2259
3037 // Compute the effective storage pointer, handling the case where the 2260 // Compute the effective storage pointer, handling the case where the
3038 // {external} pointer is the effective storage pointer (i.e. the {base} 2261 // {external} pointer is the effective storage pointer (i.e. the {base}
3039 // is Smi zero). 2262 // is Smi zero).
3040 Node* storage = 2263 Node* storage = NumberMatcher(base).Is(0) ? external : __ UnsafePointerAdd(
3041 NumberMatcher(base).Is(0) 2264 base, external);
3042 ? external
3043 : effect = graph()->NewNode(machine()->UnsafePointerAdd(), base,
3044 external, effect, control);
3045 2265
3046 // Perform the actual typed element access. 2266 // Perform the actual typed element access.
3047 Node* value = effect = graph()->NewNode( 2267 return __ LoadElement(AccessBuilder::ForTypedArrayElement(array_type, true),
3048 simplified()->LoadElement( 2268 storage, index);
3049 AccessBuilder::ForTypedArrayElement(array_type, true)),
3050 storage, index, effect, control);
3051
3052 return ValueEffectControl(value, effect, control);
3053 } 2269 }
3054 2270
3055 EffectControlLinearizer::ValueEffectControl 2271 void EffectControlLinearizer::LowerStoreTypedElement(Node* node) {
3056 EffectControlLinearizer::LowerStoreTypedElement(Node* node, Node* effect,
3057 Node* control) {
3058 ExternalArrayType array_type = ExternalArrayTypeOf(node->op()); 2272 ExternalArrayType array_type = ExternalArrayTypeOf(node->op());
3059 Node* buffer = node->InputAt(0); 2273 Node* buffer = node->InputAt(0);
3060 Node* base = node->InputAt(1); 2274 Node* base = node->InputAt(1);
3061 Node* external = node->InputAt(2); 2275 Node* external = node->InputAt(2);
3062 Node* index = node->InputAt(3); 2276 Node* index = node->InputAt(3);
3063 Node* value = node->InputAt(4); 2277 Node* value = node->InputAt(4);
3064 2278
3065 // We need to keep the {buffer} alive so that the GC will not release the 2279 // We need to keep the {buffer} alive so that the GC will not release the
3066 // ArrayBuffer (if there's any) as long as we are still operating on it. 2280 // ArrayBuffer (if there's any) as long as we are still operating on it.
3067 effect = graph()->NewNode(common()->Retain(), buffer, effect); 2281 __ Retain(buffer);
3068 2282
3069 // Compute the effective storage pointer, handling the case where the 2283 // Compute the effective storage pointer, handling the case where the
3070 // {external} pointer is the effective storage pointer (i.e. the {base} 2284 // {external} pointer is the effective storage pointer (i.e. the {base}
3071 // is Smi zero). 2285 // is Smi zero).
3072 Node* storage = 2286 Node* storage = NumberMatcher(base).Is(0) ? external : __ UnsafePointerAdd(
3073 NumberMatcher(base).Is(0) 2287 base, external);
3074 ? external
3075 : effect = graph()->NewNode(machine()->UnsafePointerAdd(), base,
3076 external, effect, control);
3077 2288
3078 // Perform the actual typed element access. 2289 // Perform the actual typed element access.
3079 effect = graph()->NewNode( 2290 __ StoreElement(AccessBuilder::ForTypedArrayElement(array_type, true),
3080 simplified()->StoreElement( 2291 storage, index, value);
3081 AccessBuilder::ForTypedArrayElement(array_type, true)),
3082 storage, index, value, effect, control);
3083
3084 return ValueEffectControl(nullptr, effect, control);
3085 } 2292 }
3086 2293
3087 EffectControlLinearizer::ValueEffectControl 2294 Maybe<Node*> EffectControlLinearizer::LowerFloat64RoundUp(Node* node) {
3088 EffectControlLinearizer::LowerFloat64RoundUp(Node* node, Node* effect,
3089 Node* control) {
3090 // Nothing to be done if a fast hardware instruction is available. 2295 // Nothing to be done if a fast hardware instruction is available.
3091 if (machine()->Float64RoundUp().IsSupported()) { 2296 if (machine()->Float64RoundUp().IsSupported()) {
3092 return ValueEffectControl(node, effect, control); 2297 return Nothing<Node*>();
3093 } 2298 }
3094 2299
3095 Node* const one = jsgraph()->Float64Constant(1.0);
3096 Node* const zero = jsgraph()->Float64Constant(0.0);
3097 Node* const minus_zero = jsgraph()->Float64Constant(-0.0);
3098 Node* const two_52 = jsgraph()->Float64Constant(4503599627370496.0E0);
3099 Node* const minus_two_52 = jsgraph()->Float64Constant(-4503599627370496.0E0);
3100 Node* const input = node->InputAt(0); 2300 Node* const input = node->InputAt(0);
3101 2301
3102 // General case for ceil. 2302 // General case for ceil.
3103 // 2303 //
3104 // if 0.0 < input then 2304 // if 0.0 < input then
3105 // if 2^52 <= input then 2305 // if 2^52 <= input then
3106 // input 2306 // input
3107 // else 2307 // else
3108 // let temp1 = (2^52 + input) - 2^52 in 2308 // let temp1 = (2^52 + input) - 2^52 in
3109 // if temp1 < input then 2309 // if temp1 < input then
3110 // temp1 + 1 2310 // temp1 + 1
3111 // else 2311 // else
3112 // temp1 2312 // temp1
3113 // else 2313 // else
3114 // if input == 0 then 2314 // if input == 0 then
3115 // input 2315 // input
3116 // else 2316 // else
3117 // if input <= -2^52 then 2317 // if input <= -2^52 then
3118 // input 2318 // input
3119 // else 2319 // else
3120 // let temp1 = -0 - input in 2320 // let temp1 = -0 - input in
3121 // let temp2 = (2^52 + temp1) - 2^52 in 2321 // let temp2 = (2^52 + temp1) - 2^52 in
3122 // let temp3 = (if temp1 < temp2 then temp2 - 1 else temp2) in 2322 // let temp3 = (if temp1 < temp2 then temp2 - 1 else temp2) in
3123 // -0 - temp3 2323 // -0 - temp3
3124 //
3125 // Note: We do not use the Diamond helper class here, because it really hurts
3126 // readability with nested diamonds.
3127 2324
3128 Node* check0 = graph()->NewNode(machine()->Float64LessThan(), zero, input); 2325 auto if_not_positive = __ MakeDeferredLabel<1>();
3129 Node* branch0 = 2326 auto if_greater_than_two_52 = __ MakeDeferredLabel<1>();
3130 graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control); 2327 auto if_less_than_minus_two_52 = __ MakeDeferredLabel<1>();
2328 auto if_zero = __ MakeDeferredLabel<1>();
2329 auto done_temp3 = __ MakeLabel<2>(MachineRepresentation::kFloat64);
2330 auto done = __ MakeLabel<6>(MachineRepresentation::kFloat64);
3131 2331
3132 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); 2332 Node* const zero = __ Float64Constant(0.0);
3133 Node* vtrue0; 2333 Node* const two_52 = __ Float64Constant(4503599627370496.0E0);
2334 Node* const one = __ Float64Constant(1.0);
2335
2336 Node* check0 = __ Float64LessThan(zero, input);
2337 __ GotoUnless(check0, &if_not_positive);
3134 { 2338 {
3135 Node* check1 = 2339 Node* check1 = __ Float64LessThanOrEqual(two_52, input);
3136 graph()->NewNode(machine()->Float64LessThanOrEqual(), two_52, input); 2340 __ GotoIf(check1, &if_greater_than_two_52);
3137 Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_true0);
3138
3139 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
3140 Node* vtrue1 = input;
3141
3142 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
3143 Node* vfalse1;
3144 { 2341 {
3145 Node* temp1 = graph()->NewNode( 2342 Node* temp1 = __ Float64Sub(__ Float64Add(two_52, input), two_52);
3146 machine()->Float64Sub(), 2343 __ GotoUnless(__ Float64LessThan(temp1, input), &done, temp1);
3147 graph()->NewNode(machine()->Float64Add(), two_52, input), two_52); 2344 __ Goto(&done, __ Float64Add(temp1, one));
3148 vfalse1 = graph()->NewNode(
3149 common()->Select(MachineRepresentation::kFloat64),
3150 graph()->NewNode(machine()->Float64LessThan(), temp1, input),
3151 graph()->NewNode(machine()->Float64Add(), temp1, one), temp1);
3152 } 2345 }
3153 2346
3154 if_true0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1); 2347 __ Bind(&if_greater_than_two_52);
3155 vtrue0 = graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), 2348 __ Goto(&done, input);
3156 vtrue1, vfalse1, if_true0);
3157 } 2349 }
3158 2350
3159 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0); 2351 __ Bind(&if_not_positive);
3160 Node* vfalse0;
3161 { 2352 {
3162 Node* check1 = graph()->NewNode(machine()->Float64Equal(), input, zero); 2353 Node* check1 = __ Float64Equal(input, zero);
3163 Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kFalse), 2354 __ GotoIf(check1, &if_zero);
3164 check1, if_false0);
3165 2355
3166 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); 2356 Node* const minus_two_52 = __ Float64Constant(-4503599627370496.0E0);
3167 Node* vtrue1 = input; 2357 Node* check2 = __ Float64LessThanOrEqual(input, minus_two_52);
2358 __ GotoIf(check2, &if_less_than_minus_two_52);
3168 2359
3169 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
3170 Node* vfalse1;
3171 { 2360 {
3172 Node* check2 = graph()->NewNode(machine()->Float64LessThanOrEqual(), 2361 Node* const minus_zero = __ Float64Constant(-0.0);
3173 input, minus_two_52); 2362 Node* temp1 = __ Float64Sub(minus_zero, input);
3174 Node* branch2 = graph()->NewNode(common()->Branch(BranchHint::kFalse), 2363 Node* temp2 = __ Float64Sub(__ Float64Add(two_52, temp1), two_52);
3175 check2, if_false1); 2364 Node* check3 = __ Float64LessThan(temp1, temp2);
2365 __ GotoUnless(check3, &done_temp3, temp2);
2366 __ Goto(&done_temp3, __ Float64Sub(temp2, one));
3176 2367
3177 Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2); 2368 __ Bind(&done_temp3);
3178 Node* vtrue2 = input; 2369 Node* temp3 = done_temp3.PhiAt(0);
2370 __ Goto(&done, __ Float64Sub(minus_zero, temp3));
2371 }
2372 __ Bind(&if_less_than_minus_two_52);
2373 __ Goto(&done, input);
3179 2374
3180 Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2); 2375 __ Bind(&if_zero);
3181 Node* vfalse2; 2376 __ Goto(&done, input);
3182 { 2377 }
3183 Node* temp1 = 2378 __ Bind(&done);
3184 graph()->NewNode(machine()->Float64Sub(), minus_zero, input); 2379 return Just(done.PhiAt(0));
3185 Node* temp2 = graph()->NewNode( 2380 }
3186 machine()->Float64Sub(),
3187 graph()->NewNode(machine()->Float64Add(), two_52, temp1), two_52);
3188 Node* temp3 = graph()->NewNode(
3189 common()->Select(MachineRepresentation::kFloat64),
3190 graph()->NewNode(machine()->Float64LessThan(), temp1, temp2),
3191 graph()->NewNode(machine()->Float64Sub(), temp2, one), temp2);
3192 vfalse2 = graph()->NewNode(machine()->Float64Sub(), minus_zero, temp3);
3193 }
3194 2381
3195 if_false1 = graph()->NewNode(common()->Merge(2), if_true2, if_false2); 2382 Node* EffectControlLinearizer::BuildFloat64RoundDown(Node* value) {
3196 vfalse1 = 2383 Node* round_down = __ Float64RoundDown(value);
3197 graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), 2384 if (round_down != nullptr) {
3198 vtrue2, vfalse2, if_false1); 2385 return round_down;
2386 }
2387
2388 Node* const input = value;
2389
2390 // General case for floor.
2391 //
2392 // if 0.0 < input then
2393 // if 2^52 <= input then
2394 // input
2395 // else
2396 // let temp1 = (2^52 + input) - 2^52 in
2397 // if input < temp1 then
2398 // temp1 - 1
2399 // else
2400 // temp1
2401 // else
2402 // if input == 0 then
2403 // input
2404 // else
2405 // if input <= -2^52 then
2406 // input
2407 // else
2408 // let temp1 = -0 - input in
2409 // let temp2 = (2^52 + temp1) - 2^52 in
2410 // if temp2 < temp1 then
2411 // -1 - temp2
2412 // else
2413 // -0 - temp2
2414
2415 auto if_not_positive = __ MakeDeferredLabel<1>();
2416 auto if_greater_than_two_52 = __ MakeDeferredLabel<1>();
2417 auto if_less_than_minus_two_52 = __ MakeDeferredLabel<1>();
2418 auto if_temp2_lt_temp1 = __ MakeLabel<1>();
2419 auto if_zero = __ MakeDeferredLabel<1>();
2420 auto done = __ MakeLabel<7>(MachineRepresentation::kFloat64);
2421
2422 Node* const zero = __ Float64Constant(0.0);
2423 Node* const two_52 = __ Float64Constant(4503599627370496.0E0);
2424
2425 Node* check0 = __ Float64LessThan(zero, input);
2426 __ GotoUnless(check0, &if_not_positive);
2427 {
2428 Node* check1 = __ Float64LessThanOrEqual(two_52, input);
2429 __ GotoIf(check1, &if_greater_than_two_52);
2430 {
2431 Node* const one = __ Float64Constant(1.0);
2432 Node* temp1 = __ Float64Sub(__ Float64Add(two_52, input), two_52);
2433 __ GotoUnless(__ Float64LessThan(input, temp1), &done, temp1);
2434 __ Goto(&done, __ Float64Sub(temp1, one));
3199 } 2435 }
3200 2436
3201 if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1); 2437 __ Bind(&if_greater_than_two_52);
3202 vfalse0 = 2438 __ Goto(&done, input);
3203 graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
3204 vtrue1, vfalse1, if_false0);
3205 } 2439 }
3206 2440
3207 Node* merge0 = graph()->NewNode(common()->Merge(2), if_true0, if_false0); 2441 __ Bind(&if_not_positive);
3208 Node* value = 2442 {
3209 graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), 2443 Node* check1 = __ Float64Equal(input, zero);
3210 vtrue0, vfalse0, merge0); 2444 __ GotoIf(check1, &if_zero);
3211 return ValueEffectControl(value, effect, merge0); 2445
2446 Node* const minus_two_52 = __ Float64Constant(-4503599627370496.0E0);
2447 Node* check2 = __ Float64LessThanOrEqual(input, minus_two_52);
2448 __ GotoIf(check2, &if_less_than_minus_two_52);
2449
2450 {
2451 Node* const minus_zero = __ Float64Constant(-0.0);
2452 Node* temp1 = __ Float64Sub(minus_zero, input);
2453 Node* temp2 = __ Float64Sub(__ Float64Add(two_52, temp1), two_52);
2454 Node* check3 = __ Float64LessThan(temp2, temp1);
2455 __ GotoIf(check3, &if_temp2_lt_temp1);
2456 __ Goto(&done, __ Float64Sub(minus_zero, temp2));
2457
2458 __ Bind(&if_temp2_lt_temp1);
2459 __ Goto(&done, __ Float64Sub(__ Float64Constant(-1.0), temp2));
2460 }
2461 __ Bind(&if_less_than_minus_two_52);
2462 __ Goto(&done, input);
2463
2464 __ Bind(&if_zero);
2465 __ Goto(&done, input);
2466 }
2467 __ Bind(&done);
2468 return done.PhiAt(0);
3212 } 2469 }
3213 2470
3214 EffectControlLinearizer::ValueEffectControl 2471 Maybe<Node*> EffectControlLinearizer::LowerFloat64RoundDown(Node* node) {
3215 EffectControlLinearizer::BuildFloat64RoundDown(Node* value, Node* effect,
3216 Node* control) {
3217 if (machine()->Float64RoundDown().IsSupported()) {
3218 value = graph()->NewNode(machine()->Float64RoundDown().op(), value);
3219 } else {
3220 Node* const one = jsgraph()->Float64Constant(1.0);
3221 Node* const zero = jsgraph()->Float64Constant(0.0);
3222 Node* const minus_one = jsgraph()->Float64Constant(-1.0);
3223 Node* const minus_zero = jsgraph()->Float64Constant(-0.0);
3224 Node* const two_52 = jsgraph()->Float64Constant(4503599627370496.0E0);
3225 Node* const minus_two_52 =
3226 jsgraph()->Float64Constant(-4503599627370496.0E0);
3227 Node* const input = value;
3228
3229 // General case for floor.
3230 //
3231 // if 0.0 < input then
3232 // if 2^52 <= input then
3233 // input
3234 // else
3235 // let temp1 = (2^52 + input) - 2^52 in
3236 // if input < temp1 then
3237 // temp1 - 1
3238 // else
3239 // temp1
3240 // else
3241 // if input == 0 then
3242 // input
3243 // else
3244 // if input <= -2^52 then
3245 // input
3246 // else
3247 // let temp1 = -0 - input in
3248 // let temp2 = (2^52 + temp1) - 2^52 in
3249 // if temp2 < temp1 then
3250 // -1 - temp2
3251 // else
3252 // -0 - temp2
3253 //
3254 // Note: We do not use the Diamond helper class here, because it really
3255 // hurts
3256 // readability with nested diamonds.
3257
3258 Node* check0 = graph()->NewNode(machine()->Float64LessThan(), zero, input);
3259 Node* branch0 =
3260 graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control);
3261
3262 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
3263 Node* vtrue0;
3264 {
3265 Node* check1 =
3266 graph()->NewNode(machine()->Float64LessThanOrEqual(), two_52, input);
3267 Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_true0);
3268
3269 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
3270 Node* vtrue1 = input;
3271
3272 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
3273 Node* vfalse1;
3274 {
3275 Node* temp1 = graph()->NewNode(
3276 machine()->Float64Sub(),
3277 graph()->NewNode(machine()->Float64Add(), two_52, input), two_52);
3278 vfalse1 = graph()->NewNode(
3279 common()->Select(MachineRepresentation::kFloat64),
3280 graph()->NewNode(machine()->Float64LessThan(), input, temp1),
3281 graph()->NewNode(machine()->Float64Sub(), temp1, one), temp1);
3282 }
3283
3284 if_true0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
3285 vtrue0 =
3286 graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
3287 vtrue1, vfalse1, if_true0);
3288 }
3289
3290 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
3291 Node* vfalse0;
3292 {
3293 Node* check1 = graph()->NewNode(machine()->Float64Equal(), input, zero);
3294 Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
3295 check1, if_false0);
3296
3297 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
3298 Node* vtrue1 = input;
3299
3300 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
3301 Node* vfalse1;
3302 {
3303 Node* check2 = graph()->NewNode(machine()->Float64LessThanOrEqual(),
3304 input, minus_two_52);
3305 Node* branch2 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
3306 check2, if_false1);
3307
3308 Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
3309 Node* vtrue2 = input;
3310
3311 Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
3312 Node* vfalse2;
3313 {
3314 Node* temp1 =
3315 graph()->NewNode(machine()->Float64Sub(), minus_zero, input);
3316 Node* temp2 = graph()->NewNode(
3317 machine()->Float64Sub(),
3318 graph()->NewNode(machine()->Float64Add(), two_52, temp1), two_52);
3319 vfalse2 = graph()->NewNode(
3320 common()->Select(MachineRepresentation::kFloat64),
3321 graph()->NewNode(machine()->Float64LessThan(), temp2, temp1),
3322 graph()->NewNode(machine()->Float64Sub(), minus_one, temp2),
3323 graph()->NewNode(machine()->Float64Sub(), minus_zero, temp2));
3324 }
3325
3326 if_false1 = graph()->NewNode(common()->Merge(2), if_true2, if_false2);
3327 vfalse1 =
3328 graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
3329 vtrue2, vfalse2, if_false1);
3330 }
3331
3332 if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
3333 vfalse0 =
3334 graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
3335 vtrue1, vfalse1, if_false0);
3336 }
3337
3338 control = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
3339 value = graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
3340 vtrue0, vfalse0, control);
3341 }
3342 return ValueEffectControl(value, effect, control);
3343 }
3344
3345 EffectControlLinearizer::ValueEffectControl
3346 EffectControlLinearizer::LowerFloat64RoundDown(Node* node, Node* effect,
3347 Node* control) {
3348 // Nothing to be done if a fast hardware instruction is available. 2472 // Nothing to be done if a fast hardware instruction is available.
3349 if (machine()->Float64RoundDown().IsSupported()) { 2473 if (machine()->Float64RoundDown().IsSupported()) {
3350 return ValueEffectControl(node, effect, control); 2474 return Nothing<Node*>();
3351 } 2475 }
3352 2476
3353 Node* const input = node->InputAt(0); 2477 Node* const input = node->InputAt(0);
3354 return BuildFloat64RoundDown(input, effect, control); 2478 return Just(BuildFloat64RoundDown(input));
3355 } 2479 }
3356 2480
3357 EffectControlLinearizer::ValueEffectControl 2481 Maybe<Node*> EffectControlLinearizer::LowerFloat64RoundTiesEven(Node* node) {
3358 EffectControlLinearizer::LowerFloat64RoundTiesEven(Node* node, Node* effect,
3359 Node* control) {
3360 // Nothing to be done if a fast hardware instruction is available. 2482 // Nothing to be done if a fast hardware instruction is available.
3361 if (machine()->Float64RoundTiesEven().IsSupported()) { 2483 if (machine()->Float64RoundTiesEven().IsSupported()) {
3362 return ValueEffectControl(node, effect, control); 2484 return Nothing<Node*>();
3363 } 2485 }
3364 2486
3365 Node* const one = jsgraph()->Float64Constant(1.0);
3366 Node* const two = jsgraph()->Float64Constant(2.0);
3367 Node* const half = jsgraph()->Float64Constant(0.5);
3368 Node* const zero = jsgraph()->Float64Constant(0.0);
3369 Node* const input = node->InputAt(0); 2487 Node* const input = node->InputAt(0);
3370 2488
3371 // Generate case for round ties to even: 2489 // Generate case for round ties to even:
3372 // 2490 //
3373 // let value = floor(input) in 2491 // let value = floor(input) in
3374 // let temp1 = input - value in 2492 // let temp1 = input - value in
3375 // if temp1 < 0.5 then 2493 // if temp1 < 0.5 then
3376 // value 2494 // value
3377 // else if 0.5 < temp1 then 2495 // else if 0.5 < temp1 then
3378 // value + 1.0 2496 // value + 1.0
3379 // else 2497 // else
3380 // let temp2 = value % 2.0 in 2498 // let temp2 = value % 2.0 in
3381 // if temp2 == 0.0 then 2499 // if temp2 == 0.0 then
3382 // value 2500 // value
3383 // else 2501 // else
3384 // value + 1.0 2502 // value + 1.0
3385 //
3386 // Note: We do not use the Diamond helper class here, because it really hurts
3387 // readability with nested diamonds.
3388 2503
3389 ValueEffectControl continuation = 2504 auto if_is_half = __ MakeLabel<1>();
3390 BuildFloat64RoundDown(input, effect, control); 2505 auto done = __ MakeLabel<4>(MachineRepresentation::kFloat64);
3391 Node* value = continuation.value;
3392 effect = continuation.effect;
3393 control = continuation.control;
3394 2506
3395 Node* temp1 = graph()->NewNode(machine()->Float64Sub(), input, value); 2507 Node* value = BuildFloat64RoundDown(input);
2508 Node* temp1 = __ Float64Sub(input, value);
3396 2509
3397 Node* check0 = graph()->NewNode(machine()->Float64LessThan(), temp1, half); 2510 Node* const half = __ Float64Constant(0.5);
3398 Node* branch0 = graph()->NewNode(common()->Branch(), check0, control); 2511 Node* check0 = __ Float64LessThan(temp1, half);
2512 __ GotoIf(check0, &done, value);
3399 2513
3400 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); 2514 Node* const one = __ Float64Constant(1.0);
3401 Node* vtrue0 = value; 2515 Node* check1 = __ Float64LessThan(half, temp1);
2516 __ GotoUnless(check1, &if_is_half);
2517 __ Goto(&done, __ Float64Add(value, one));
3402 2518
3403 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0); 2519 __ Bind(&if_is_half);
3404 Node* vfalse0; 2520 Node* temp2 = __ Float64Mod(value, __ Float64Constant(2.0));
3405 { 2521 Node* check2 = __ Float64Equal(temp2, __ Float64Constant(0.0));
3406 Node* check1 = graph()->NewNode(machine()->Float64LessThan(), half, temp1); 2522 __ GotoIf(check2, &done, value);
3407 Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_false0); 2523 __ Goto(&done, __ Float64Add(value, one));
3408 2524
3409 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); 2525 __ Bind(&done);
3410 Node* vtrue1 = graph()->NewNode(machine()->Float64Add(), value, one); 2526 return Just(done.PhiAt(0));
2527 }
3411 2528
3412 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); 2529 Maybe<Node*> EffectControlLinearizer::LowerFloat64RoundTruncate(Node* node) {
3413 Node* vfalse1; 2530 // Nothing to be done if a fast hardware instruction is available.
3414 { 2531 if (machine()->Float64RoundTruncate().IsSupported()) {
3415 Node* temp2 = graph()->NewNode(machine()->Float64Mod(), value, two); 2532 return Nothing<Node*>();
3416
3417 Node* check2 = graph()->NewNode(machine()->Float64Equal(), temp2, zero);
3418 Node* branch2 = graph()->NewNode(common()->Branch(), check2, if_false1);
3419
3420 Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
3421 Node* vtrue2 = value;
3422
3423 Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
3424 Node* vfalse2 = graph()->NewNode(machine()->Float64Add(), value, one);
3425
3426 if_false1 = graph()->NewNode(common()->Merge(2), if_true2, if_false2);
3427 vfalse1 =
3428 graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
3429 vtrue2, vfalse2, if_false1);
3430 }
3431
3432 if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
3433 vfalse0 =
3434 graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
3435 vtrue1, vfalse1, if_false0);
3436 } 2533 }
3437 2534
3438 control = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
3439 value = graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
3440 vtrue0, vfalse0, control);
3441
3442 return ValueEffectControl(value, effect, control);
3443 }
3444
3445 EffectControlLinearizer::ValueEffectControl
3446 EffectControlLinearizer::LowerFloat64RoundTruncate(Node* node, Node* effect,
3447 Node* control) {
3448 // Nothing to be done if a fast hardware instruction is available.
3449 if (machine()->Float64RoundTruncate().IsSupported()) {
3450 return ValueEffectControl(node, effect, control);
3451 }
3452
3453 Node* const one = jsgraph()->Float64Constant(1.0);
3454 Node* const zero = jsgraph()->Float64Constant(0.0);
3455 Node* const minus_zero = jsgraph()->Float64Constant(-0.0);
3456 Node* const two_52 = jsgraph()->Float64Constant(4503599627370496.0E0);
3457 Node* const minus_two_52 = jsgraph()->Float64Constant(-4503599627370496.0E0);
3458 Node* const input = node->InputAt(0); 2535 Node* const input = node->InputAt(0);
3459 2536
3460 // General case for trunc. 2537 // General case for trunc.
3461 // 2538 //
3462 // if 0.0 < input then 2539 // if 0.0 < input then
3463 // if 2^52 <= input then 2540 // if 2^52 <= input then
3464 // input 2541 // input
3465 // else 2542 // else
3466 // let temp1 = (2^52 + input) - 2^52 in 2543 // let temp1 = (2^52 + input) - 2^52 in
3467 // if input < temp1 then 2544 // if input < temp1 then
3468 // temp1 - 1 2545 // temp1 - 1
3469 // else 2546 // else
3470 // temp1 2547 // temp1
3471 // else 2548 // else
3472 // if input == 0 then 2549 // if input == 0 then
3473 // input 2550 // input
3474 // else 2551 // else
3475 // if input <= -2^52 then 2552 // if input <= -2^52 then
3476 // input 2553 // input
3477 // else 2554 // else
3478 // let temp1 = -0 - input in 2555 // let temp1 = -0 - input in
3479 // let temp2 = (2^52 + temp1) - 2^52 in 2556 // let temp2 = (2^52 + temp1) - 2^52 in
3480 // let temp3 = (if temp1 < temp2 then temp2 - 1 else temp2) in 2557 // let temp3 = (if temp1 < temp2 then temp2 - 1 else temp2) in
3481 // -0 - temp3 2558 // -0 - temp3
3482 // 2559 //
3483 // Note: We do not use the Diamond helper class here, because it really hurts 2560 // Note: We do not use the Diamond helper class here, because it really hurts
3484 // readability with nested diamonds. 2561 // readability with nested diamonds.
3485 2562
3486 Node* check0 = graph()->NewNode(machine()->Float64LessThan(), zero, input); 2563 auto if_not_positive = __ MakeDeferredLabel<1>();
3487 Node* branch0 = 2564 auto if_greater_than_two_52 = __ MakeDeferredLabel<1>();
3488 graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control); 2565 auto if_less_than_minus_two_52 = __ MakeDeferredLabel<1>();
2566 auto if_zero = __ MakeDeferredLabel<1>();
2567 auto done_temp3 = __ MakeLabel<2>(MachineRepresentation::kFloat64);
2568 auto done = __ MakeLabel<6>(MachineRepresentation::kFloat64);
3489 2569
3490 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); 2570 Node* const zero = __ Float64Constant(0.0);
3491 Node* vtrue0; 2571 Node* const two_52 = __ Float64Constant(4503599627370496.0E0);
2572 Node* const one = __ Float64Constant(1.0);
2573
2574 Node* check0 = __ Float64LessThan(zero, input);
2575 __ GotoUnless(check0, &if_not_positive);
3492 { 2576 {
3493 Node* check1 = 2577 Node* check1 = __ Float64LessThanOrEqual(two_52, input);
3494 graph()->NewNode(machine()->Float64LessThanOrEqual(), two_52, input); 2578 __ GotoIf(check1, &if_greater_than_two_52);
3495 Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_true0);
3496
3497 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
3498 Node* vtrue1 = input;
3499
3500 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
3501 Node* vfalse1;
3502 { 2579 {
3503 Node* temp1 = graph()->NewNode( 2580 Node* temp1 = __ Float64Sub(__ Float64Add(two_52, input), two_52);
3504 machine()->Float64Sub(), 2581 __ GotoUnless(__ Float64LessThan(input, temp1), &done, temp1);
3505 graph()->NewNode(machine()->Float64Add(), two_52, input), two_52); 2582 __ Goto(&done, __ Float64Sub(temp1, one));
3506 vfalse1 = graph()->NewNode(
3507 common()->Select(MachineRepresentation::kFloat64),
3508 graph()->NewNode(machine()->Float64LessThan(), input, temp1),
3509 graph()->NewNode(machine()->Float64Sub(), temp1, one), temp1);
3510 } 2583 }
3511 2584
3512 if_true0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1); 2585 __ Bind(&if_greater_than_two_52);
3513 vtrue0 = graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), 2586 __ Goto(&done, input);
3514 vtrue1, vfalse1, if_true0);
3515 } 2587 }
3516 2588
3517 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0); 2589 __ Bind(&if_not_positive);
3518 Node* vfalse0;
3519 { 2590 {
3520 Node* check1 = graph()->NewNode(machine()->Float64Equal(), input, zero); 2591 Node* check1 = __ Float64Equal(input, zero);
3521 Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kFalse), 2592 __ GotoIf(check1, &if_zero);
3522 check1, if_false0);
3523 2593
3524 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); 2594 Node* const minus_two_52 = __ Float64Constant(-4503599627370496.0E0);
3525 Node* vtrue1 = input; 2595 Node* check2 = __ Float64LessThanOrEqual(input, minus_two_52);
2596 __ GotoIf(check2, &if_less_than_minus_two_52);
3526 2597
3527 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
3528 Node* vfalse1;
3529 { 2598 {
3530 Node* check2 = graph()->NewNode(machine()->Float64LessThanOrEqual(), 2599 Node* const minus_zero = __ Float64Constant(-0.0);
3531 input, minus_two_52); 2600 Node* temp1 = __ Float64Sub(minus_zero, input);
3532 Node* branch2 = graph()->NewNode(common()->Branch(BranchHint::kFalse), 2601 Node* temp2 = __ Float64Sub(__ Float64Add(two_52, temp1), two_52);
3533 check2, if_false1); 2602 Node* check3 = __ Float64LessThan(temp1, temp2);
2603 __ GotoUnless(check3, &done_temp3, temp2);
2604 __ Goto(&done_temp3, __ Float64Sub(temp2, one));
3534 2605
3535 Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2); 2606 __ Bind(&done_temp3);
3536 Node* vtrue2 = input; 2607 Node* temp3 = done_temp3.PhiAt(0);
2608 __ Goto(&done, __ Float64Sub(minus_zero, temp3));
2609 }
2610 __ Bind(&if_less_than_minus_two_52);
2611 __ Goto(&done, input);
3537 2612
3538 Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2); 2613 __ Bind(&if_zero);
3539 Node* vfalse2; 2614 __ Goto(&done, input);
3540 { 2615 }
3541 Node* temp1 = 2616 __ Bind(&done);
3542 graph()->NewNode(machine()->Float64Sub(), minus_zero, input); 2617 return Just(done.PhiAt(0));
3543 Node* temp2 = graph()->NewNode( 2618 }
3544 machine()->Float64Sub(),
3545 graph()->NewNode(machine()->Float64Add(), two_52, temp1), two_52);
3546 Node* temp3 = graph()->NewNode(
3547 common()->Select(MachineRepresentation::kFloat64),
3548 graph()->NewNode(machine()->Float64LessThan(), temp1, temp2),
3549 graph()->NewNode(machine()->Float64Sub(), temp2, one), temp2);
3550 vfalse2 = graph()->NewNode(machine()->Float64Sub(), minus_zero, temp3);
3551 }
3552 2619
3553 if_false1 = graph()->NewNode(common()->Merge(2), if_true2, if_false2); 2620 #undef __
3554 vfalse1 =
3555 graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
3556 vtrue2, vfalse2, if_false1);
3557 }
3558
3559 if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
3560 vfalse0 =
3561 graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
3562 vtrue1, vfalse1, if_false0);
3563 }
3564
3565 Node* merge0 = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
3566 Node* value =
3567 graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
3568 vtrue0, vfalse0, merge0);
3569 return ValueEffectControl(value, effect, merge0);
3570 }
3571 2621
3572 Factory* EffectControlLinearizer::factory() const { 2622 Factory* EffectControlLinearizer::factory() const {
3573 return isolate()->factory(); 2623 return isolate()->factory();
3574 } 2624 }
3575 2625
3576 Isolate* EffectControlLinearizer::isolate() const { 2626 Isolate* EffectControlLinearizer::isolate() const {
3577 return jsgraph()->isolate(); 2627 return jsgraph()->isolate();
3578 } 2628 }
3579 2629
3580 Operator const* EffectControlLinearizer::ToNumberOperator() {
3581 if (!to_number_operator_.is_set()) {
3582 Callable callable = CodeFactory::ToNumber(isolate());
3583 CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
3584 CallDescriptor* desc = Linkage::GetStubCallDescriptor(
3585 isolate(), graph()->zone(), callable.descriptor(), 0, flags,
3586 Operator::kEliminatable);
3587 to_number_operator_.set(common()->Call(desc));
3588 }
3589 return to_number_operator_.get();
3590 }
3591
3592 } // namespace compiler 2630 } // namespace compiler
3593 } // namespace internal 2631 } // namespace internal
3594 } // namespace v8 2632 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698