OLD | NEW |
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/js-graph.h" | 9 #include "src/compiler/js-graph.h" |
10 #include "src/compiler/linkage.h" | 10 #include "src/compiler/linkage.h" |
(...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
380 break; | 380 break; |
381 case IrOpcode::kChangeTaggedToUint32: | 381 case IrOpcode::kChangeTaggedToUint32: |
382 state = LowerChangeTaggedToUint32(node, *effect, *control); | 382 state = LowerChangeTaggedToUint32(node, *effect, *control); |
383 break; | 383 break; |
384 case IrOpcode::kChangeTaggedToFloat64: | 384 case IrOpcode::kChangeTaggedToFloat64: |
385 state = LowerChangeTaggedToFloat64(node, *effect, *control); | 385 state = LowerChangeTaggedToFloat64(node, *effect, *control); |
386 break; | 386 break; |
387 case IrOpcode::kTruncateTaggedToFloat64: | 387 case IrOpcode::kTruncateTaggedToFloat64: |
388 state = LowerTruncateTaggedToFloat64(node, *effect, *control); | 388 state = LowerTruncateTaggedToFloat64(node, *effect, *control); |
389 break; | 389 break; |
| 390 case IrOpcode::kCheckedUint32ToInt32: |
| 391 state = LowerCheckedUint32ToInt32(node, *effect, *control); |
| 392 break; |
| 393 case IrOpcode::kCheckedFloat64ToInt32: |
| 394 state = LowerCheckedFloat64ToInt32(node, *effect, *control); |
| 395 break; |
| 396 case IrOpcode::kCheckedTaggedToInt32: |
| 397 state = LowerCheckedTaggedToInt32(node, *effect, *control); |
| 398 break; |
| 399 case IrOpcode::kCheckedTaggedToFloat64: |
| 400 state = LowerCheckedTaggedToFloat64(node, *effect, *control); |
| 401 break; |
390 case IrOpcode::kTruncateTaggedToWord32: | 402 case IrOpcode::kTruncateTaggedToWord32: |
391 state = LowerTruncateTaggedToWord32(node, *effect, *control); | 403 state = LowerTruncateTaggedToWord32(node, *effect, *control); |
392 break; | 404 break; |
393 case IrOpcode::kObjectIsCallable: | 405 case IrOpcode::kObjectIsCallable: |
394 state = LowerObjectIsCallable(node, *effect, *control); | 406 state = LowerObjectIsCallable(node, *effect, *control); |
395 break; | 407 break; |
396 case IrOpcode::kObjectIsNumber: | 408 case IrOpcode::kObjectIsNumber: |
397 state = LowerObjectIsNumber(node, *effect, *control); | 409 state = LowerObjectIsNumber(node, *effect, *control); |
398 break; | 410 break; |
399 case IrOpcode::kObjectIsReceiver: | 411 case IrOpcode::kObjectIsReceiver: |
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
699 | 711 |
700 control = graph()->NewNode(common()->Merge(2), if_true, if_false); | 712 control = graph()->NewNode(common()->Merge(2), if_true, if_false); |
701 effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control); | 713 effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control); |
702 value = graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), | 714 value = graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), |
703 vtrue, vfalse, control); | 715 vtrue, vfalse, control); |
704 | 716 |
705 return ValueEffectControl(value, effect, control); | 717 return ValueEffectControl(value, effect, control); |
706 } | 718 } |
707 | 719 |
708 EffectControlLinearizer::ValueEffectControl | 720 EffectControlLinearizer::ValueEffectControl |
| 721 EffectControlLinearizer::LowerCheckedUint32ToInt32(Node* node, Node* effect, |
| 722 Node* control) { |
| 723 Node* value = node->InputAt(0); |
| 724 Node* frame_state = NodeProperties::GetFrameStateInput(node, 0); |
| 725 Node* max_int = jsgraph()->Int32Constant(std::numeric_limits<int32_t>::max()); |
| 726 Node* is_safe = |
| 727 graph()->NewNode(machine()->Uint32LessThanOrEqual(), value, max_int); |
| 728 control = effect = graph()->NewNode(common()->DeoptimizeUnless(), is_safe, |
| 729 frame_state, effect, control); |
| 730 |
| 731 // Make sure the lowered node does not appear in any use lists. |
| 732 node->TrimInputCount(0); |
| 733 |
| 734 return ValueEffectControl(value, effect, control); |
| 735 } |
| 736 |
| 737 EffectControlLinearizer::ValueEffectControl |
| 738 EffectControlLinearizer::BuildCheckedFloat64ToInt32(Node* value, |
| 739 Node* frame_state, |
| 740 Node* effect, |
| 741 Node* control) { |
| 742 Node* value32 = graph()->NewNode(machine()->RoundFloat64ToInt32(), value); |
| 743 Node* check_same = graph()->NewNode( |
| 744 machine()->Float64Equal(), value, |
| 745 graph()->NewNode(machine()->ChangeInt32ToFloat64(), value32)); |
| 746 control = effect = graph()->NewNode(common()->DeoptimizeUnless(), check_same, |
| 747 frame_state, effect, control); |
| 748 |
| 749 // Check if {value} is -0. |
| 750 Node* check_zero = graph()->NewNode(machine()->Word32Equal(), value32, |
| 751 jsgraph()->Int32Constant(0)); |
| 752 Node* branch_zero = graph()->NewNode(common()->Branch(BranchHint::kFalse), |
| 753 check_zero, control); |
| 754 |
| 755 Node* if_zero = graph()->NewNode(common()->IfTrue(), branch_zero); |
| 756 Node* if_notzero = graph()->NewNode(common()->IfFalse(), branch_zero); |
| 757 |
| 758 // In case of 0, we need to check the high bits for the IEEE -0 pattern. |
| 759 Node* check_negative = graph()->NewNode( |
| 760 machine()->Int32LessThan(), |
| 761 graph()->NewNode(machine()->Float64ExtractHighWord32(), value), |
| 762 jsgraph()->Int32Constant(0)); |
| 763 |
| 764 Node* deopt_minus_zero = graph()->NewNode( |
| 765 common()->DeoptimizeIf(), check_negative, frame_state, effect, if_zero); |
| 766 |
| 767 Node* merge = |
| 768 graph()->NewNode(common()->Merge(2), deopt_minus_zero, if_notzero); |
| 769 |
| 770 effect = |
| 771 graph()->NewNode(common()->EffectPhi(2), deopt_minus_zero, effect, merge); |
| 772 |
| 773 return ValueEffectControl(value32, effect, merge); |
| 774 } |
| 775 |
| 776 EffectControlLinearizer::ValueEffectControl |
| 777 EffectControlLinearizer::LowerCheckedFloat64ToInt32(Node* node, Node* effect, |
| 778 Node* control) { |
| 779 Node* value = node->InputAt(0); |
| 780 Node* frame_state = NodeProperties::GetFrameStateInput(node, 0); |
| 781 |
| 782 // Make sure the lowered node does not appear in any use lists. |
| 783 node->TrimInputCount(0); |
| 784 |
| 785 return BuildCheckedFloat64ToInt32(value, frame_state, effect, control); |
| 786 } |
| 787 |
| 788 EffectControlLinearizer::ValueEffectControl |
| 789 EffectControlLinearizer::LowerCheckedTaggedToInt32(Node* node, Node* effect, |
| 790 Node* control) { |
| 791 Node* value = node->InputAt(0); |
| 792 Node* frame_state = NodeProperties::GetFrameStateInput(node, 0); |
| 793 |
| 794 Node* check = ObjectIsSmi(value); |
| 795 Node* branch = |
| 796 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); |
| 797 |
| 798 // In the Smi case, just convert to int32. |
| 799 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); |
| 800 Node* etrue = effect; |
| 801 Node* vtrue = ChangeSmiToInt32(value); |
| 802 |
| 803 // In the non-Smi case, check the heap numberness, load the number and convert |
| 804 // to int32. |
| 805 // TODO(jarin) Propagate/handle possible truncations here. |
| 806 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); |
| 807 ValueEffectControl number_state = BuildCheckedHeapNumberOrOddballToFloat64( |
| 808 value, frame_state, effect, if_false); |
| 809 number_state = |
| 810 BuildCheckedFloat64ToInt32(number_state.value, frame_state, |
| 811 number_state.effect, number_state.control); |
| 812 |
| 813 Node* merge = |
| 814 graph()->NewNode(common()->Merge(2), if_true, number_state.control); |
| 815 Node* effect_phi = graph()->NewNode(common()->EffectPhi(2), etrue, |
| 816 number_state.effect, merge); |
| 817 Node* result = |
| 818 graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2), vtrue, |
| 819 number_state.value, merge); |
| 820 |
| 821 // Make sure the lowered node does not appear in any use lists. |
| 822 node->TrimInputCount(0); |
| 823 |
| 824 return ValueEffectControl(result, effect_phi, merge); |
| 825 } |
| 826 |
| 827 EffectControlLinearizer::ValueEffectControl |
| 828 EffectControlLinearizer::BuildCheckedHeapNumberOrOddballToFloat64( |
| 829 Node* value, Node* frame_state, Node* effect, Node* control) { |
| 830 Node* value_map = effect = graph()->NewNode( |
| 831 simplified()->LoadField(AccessBuilder::ForMap()), value, effect, control); |
| 832 Node* check_number = graph()->NewNode(machine()->WordEqual(), value_map, |
| 833 jsgraph()->HeapNumberMapConstant()); |
| 834 |
| 835 Node* branch = graph()->NewNode(common()->Branch(BranchHint::kTrue), |
| 836 check_number, control); |
| 837 |
| 838 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); |
| 839 Node* etrue = effect; |
| 840 |
| 841 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); |
| 842 // For oddballs also contain the numeric value, let us just check that |
| 843 // we have an oddball here. |
| 844 Node* efalse = effect; |
| 845 Node* instance_type = efalse = graph()->NewNode( |
| 846 simplified()->LoadField(AccessBuilder::ForMapInstanceType()), value_map, |
| 847 efalse, if_false); |
| 848 Node* check_oddball = |
| 849 graph()->NewNode(machine()->Word32Equal(), instance_type, |
| 850 jsgraph()->Int32Constant(ODDBALL_TYPE)); |
| 851 if_false = efalse = |
| 852 graph()->NewNode(common()->DeoptimizeUnless(), check_oddball, frame_state, |
| 853 efalse, if_false); |
| 854 STATIC_ASSERT(HeapNumber::kValueOffset == Oddball::kToNumberRawOffset); |
| 855 |
| 856 control = graph()->NewNode(common()->Merge(2), if_true, if_false); |
| 857 effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control); |
| 858 |
| 859 Node* result = effect = graph()->NewNode( |
| 860 simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), value, |
| 861 effect, control); |
| 862 return ValueEffectControl(result, effect, control); |
| 863 } |
| 864 |
| 865 EffectControlLinearizer::ValueEffectControl |
| 866 EffectControlLinearizer::LowerCheckedTaggedToFloat64(Node* node, Node* effect, |
| 867 Node* control) { |
| 868 Node* value = node->InputAt(0); |
| 869 Node* frame_state = NodeProperties::GetFrameStateInput(node, 0); |
| 870 |
| 871 Node* check = ObjectIsSmi(value); |
| 872 Node* branch = |
| 873 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); |
| 874 |
| 875 // In the Smi case, just convert to int32 and then float64. |
| 876 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); |
| 877 Node* etrue = effect; |
| 878 Node* vtrue = ChangeSmiToInt32(value); |
| 879 vtrue = graph()->NewNode(machine()->ChangeInt32ToFloat64(), vtrue); |
| 880 |
| 881 // Otherwise, check heap numberness and load the number. |
| 882 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); |
| 883 ValueEffectControl number_state = BuildCheckedHeapNumberOrOddballToFloat64( |
| 884 value, frame_state, effect, if_false); |
| 885 |
| 886 Node* merge = |
| 887 graph()->NewNode(common()->Merge(2), if_true, number_state.control); |
| 888 Node* effect_phi = graph()->NewNode(common()->EffectPhi(2), etrue, |
| 889 number_state.effect, merge); |
| 890 Node* result = |
| 891 graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), vtrue, |
| 892 number_state.value, merge); |
| 893 |
| 894 // Make sure the lowered node does not appear in any use lists. |
| 895 node->TrimInputCount(0); |
| 896 |
| 897 return ValueEffectControl(result, effect_phi, merge); |
| 898 } |
| 899 |
| 900 EffectControlLinearizer::ValueEffectControl |
709 EffectControlLinearizer::LowerTruncateTaggedToWord32(Node* node, Node* effect, | 901 EffectControlLinearizer::LowerTruncateTaggedToWord32(Node* node, Node* effect, |
710 Node* control) { | 902 Node* control) { |
711 Node* value = node->InputAt(0); | 903 Node* value = node->InputAt(0); |
712 | 904 |
713 Node* check = ObjectIsSmi(value); | 905 Node* check = ObjectIsSmi(value); |
714 Node* branch = | 906 Node* branch = |
715 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); | 907 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); |
716 | 908 |
717 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); | 909 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); |
718 Node* etrue = effect; | 910 Node* etrue = effect; |
(...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1113 return isolate()->factory(); | 1305 return isolate()->factory(); |
1114 } | 1306 } |
1115 | 1307 |
1116 Isolate* EffectControlLinearizer::isolate() const { | 1308 Isolate* EffectControlLinearizer::isolate() const { |
1117 return jsgraph()->isolate(); | 1309 return jsgraph()->isolate(); |
1118 } | 1310 } |
1119 | 1311 |
1120 } // namespace compiler | 1312 } // namespace compiler |
1121 } // namespace internal | 1313 } // namespace internal |
1122 } // namespace v8 | 1314 } // namespace v8 |
OLD | NEW |