Chromium Code Reviews| 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 366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 377 break; | 377 break; |
| 378 case IrOpcode::kChangeTaggedToInt32: | 378 case IrOpcode::kChangeTaggedToInt32: |
| 379 state = LowerChangeTaggedToInt32(node, *effect, *control); | 379 state = LowerChangeTaggedToInt32(node, *effect, *control); |
| 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::kCheckedUint32ToInt32: | |
| 388 state = LowerCheckedUint32ToInt32(node, *effect, *control); | |
| 389 break; | |
| 390 case IrOpcode::kCheckedFloat64ToInt32: | |
| 391 state = LowerCheckedFloat64ToInt32(node, *effect, *control); | |
| 392 break; | |
| 393 case IrOpcode::kCheckedTaggedToInt32: | |
| 394 state = LowerCheckedTaggedToInt32(node, *effect, *control); | |
| 395 break; | |
| 396 case IrOpcode::kCheckedTaggedToFloat64: | |
| 397 state = LowerCheckedTaggedToFloat64(node, *effect, *control); | |
| 398 break; | |
| 387 case IrOpcode::kTruncateTaggedToWord32: | 399 case IrOpcode::kTruncateTaggedToWord32: |
| 388 state = LowerTruncateTaggedToWord32(node, *effect, *control); | 400 state = LowerTruncateTaggedToWord32(node, *effect, *control); |
| 389 break; | 401 break; |
| 390 case IrOpcode::kObjectIsCallable: | 402 case IrOpcode::kObjectIsCallable: |
| 391 state = LowerObjectIsCallable(node, *effect, *control); | 403 state = LowerObjectIsCallable(node, *effect, *control); |
| 392 break; | 404 break; |
| 393 case IrOpcode::kObjectIsNumber: | 405 case IrOpcode::kObjectIsNumber: |
| 394 state = LowerObjectIsNumber(node, *effect, *control); | 406 state = LowerObjectIsNumber(node, *effect, *control); |
| 395 break; | 407 break; |
| 396 case IrOpcode::kObjectIsReceiver: | 408 case IrOpcode::kObjectIsReceiver: |
| (...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 687 | 699 |
| 688 control = graph()->NewNode(common()->Merge(2), if_true, if_false); | 700 control = graph()->NewNode(common()->Merge(2), if_true, if_false); |
| 689 effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control); | 701 effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control); |
| 690 value = graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), | 702 value = graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), |
| 691 vtrue, vfalse, control); | 703 vtrue, vfalse, control); |
| 692 | 704 |
| 693 return ValueEffectControl(value, effect, control); | 705 return ValueEffectControl(value, effect, control); |
| 694 } | 706 } |
| 695 | 707 |
| 696 EffectControlLinearizer::ValueEffectControl | 708 EffectControlLinearizer::ValueEffectControl |
| 709 EffectControlLinearizer::LowerCheckedUint32ToInt32(Node* node, Node* effect, | |
| 710 Node* control) { | |
| 711 Node* value = node->InputAt(0); | |
| 712 Node* frame_state = NodeProperties::GetFrameStateInput(node, 0); | |
| 713 Node* max_int = jsgraph()->Int32Constant(std::numeric_limits<int32_t>::max()); | |
| 714 Node* is_safe = | |
| 715 graph()->NewNode(machine()->Uint32LessThanOrEqual(), value, max_int); | |
| 716 control = effect = graph()->NewNode(common()->DeoptimizeUnless(), is_safe, | |
| 717 frame_state, effect, control); | |
| 718 return ValueEffectControl(value, effect, control); | |
| 719 } | |
| 720 | |
| 721 EffectControlLinearizer::ValueEffectControl | |
| 722 EffectControlLinearizer::BuildCheckedFloat64ToInt32(Node* value, | |
| 723 Node* frame_state, | |
| 724 Node* effect, | |
| 725 Node* control) { | |
| 726 Node* value32 = graph()->NewNode(machine()->RoundFloat64ToInt32(), value); | |
| 727 Node* check_same = graph()->NewNode( | |
| 728 machine()->Float64Equal(), value, | |
| 729 graph()->NewNode(machine()->ChangeInt32ToFloat64(), value32)); | |
| 730 control = effect = graph()->NewNode(common()->DeoptimizeUnless(), check_same, | |
| 731 frame_state, effect, control); | |
| 732 | |
| 733 // Check if {value} is -0. | |
| 734 Node* check_zero = graph()->NewNode(machine()->Word32Equal(), value32, | |
| 735 jsgraph()->Int32Constant(0)); | |
| 736 Node* branch_zero = graph()->NewNode(common()->Branch(BranchHint::kFalse), | |
| 737 check_zero, control); | |
| 738 | |
| 739 Node* if_zero = graph()->NewNode(common()->IfTrue(), branch_zero); | |
| 740 Node* if_notzero = graph()->NewNode(common()->IfFalse(), branch_zero); | |
| 741 | |
| 742 // In case of 0, we need to check the high bits for the IEEE -0 pattern. | |
| 743 Node* check_negative = graph()->NewNode( | |
| 744 machine()->Int32LessThan(), | |
| 745 graph()->NewNode(machine()->Float64ExtractHighWord32(), value), | |
| 746 jsgraph()->Int32Constant(0)); | |
| 747 | |
| 748 Node* deopt_minus_zero = graph()->NewNode( | |
| 749 common()->DeoptimizeIf(), check_negative, frame_state, effect, if_zero); | |
| 750 | |
| 751 Node* merge = | |
| 752 graph()->NewNode(common()->Merge(2), deopt_minus_zero, if_notzero); | |
| 753 | |
| 754 effect = | |
| 755 graph()->NewNode(common()->EffectPhi(2), deopt_minus_zero, effect, merge); | |
| 756 | |
| 757 return ValueEffectControl(value32, effect, merge); | |
| 758 } | |
| 759 | |
| 760 EffectControlLinearizer::ValueEffectControl | |
| 761 EffectControlLinearizer::LowerCheckedFloat64ToInt32(Node* node, Node* effect, | |
| 762 Node* control) { | |
| 763 Node* value = node->InputAt(0); | |
| 764 Node* frame_state = NodeProperties::GetFrameStateInput(node, 0); | |
| 765 | |
| 766 return BuildCheckedFloat64ToInt32(value, frame_state, effect, control); | |
| 767 } | |
| 768 | |
| 769 EffectControlLinearizer::ValueEffectControl | |
| 770 EffectControlLinearizer::LowerCheckedTaggedToInt32(Node* node, Node* effect, | |
| 771 Node* control) { | |
| 772 Node* value = node->InputAt(0); | |
| 773 Node* frame_state = NodeProperties::GetFrameStateInput(node, 0); | |
| 774 | |
| 775 Node* check = ObjectIsSmi(value); | |
| 776 Node* branch = | |
| 777 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); | |
| 778 | |
| 779 // In the Smi case, just convert to int32. | |
| 780 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); | |
| 781 Node* etrue = effect; | |
| 782 Node* vtrue = ChangeSmiToInt32(value); | |
| 783 | |
| 784 // In the non-Smi case, check the heap numberness, load the number and convert | |
| 785 // to int32. | |
| 786 // TODO(jarin) Propagate/handle possible truncations here. | |
| 787 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); | |
| 788 ValueEffectControl number_state = BuildCheckedHeapNumberOrOddballToFloat64( | |
| 789 value, frame_state, effect, if_false); | |
| 790 number_state = | |
| 791 BuildCheckedFloat64ToInt32(number_state.value, frame_state, | |
| 792 number_state.effect, number_state.control); | |
| 793 | |
| 794 Node* merge = | |
| 795 graph()->NewNode(common()->Merge(2), if_true, number_state.control); | |
| 796 Node* effect_phi = graph()->NewNode(common()->EffectPhi(2), etrue, | |
| 797 number_state.effect, merge); | |
| 798 Node* result = | |
| 799 graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2), vtrue, | |
| 800 number_state.value, merge); | |
| 801 return ValueEffectControl(result, effect_phi, merge); | |
| 802 } | |
| 803 | |
| 804 EffectControlLinearizer::ValueEffectControl | |
| 805 EffectControlLinearizer::BuildCheckedHeapNumberOrOddballToFloat64( | |
| 806 Node* value, Node* frame_state, Node* effect, Node* control) { | |
| 807 Node* value_map = effect = graph()->NewNode( | |
| 808 simplified()->LoadField(AccessBuilder::ForMap()), value, effect, control); | |
| 809 Node* check_number = graph()->NewNode(machine()->WordEqual(), value_map, | |
| 810 jsgraph()->HeapNumberMapConstant()); | |
| 811 | |
| 812 Node* branch = graph()->NewNode(common()->Branch(BranchHint::kTrue), | |
| 813 check_number, control); | |
| 814 | |
| 815 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); | |
| 816 Node* etrue = effect; | |
| 817 | |
| 818 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); | |
| 819 // For oddballs also contain the numeric value, let us just check that | |
| 820 // we have an oddball here. | |
| 821 Node* efalse = effect; | |
| 822 Node* instance_type = efalse = graph()->NewNode( | |
| 823 simplified()->LoadField(AccessBuilder::ForMapInstanceType()), value_map, | |
| 824 efalse, if_false); | |
| 825 Node* check_oddball = | |
| 826 graph()->NewNode(machine()->Word32Equal(), instance_type, | |
| 827 jsgraph()->Int32Constant(ODDBALL_TYPE)); | |
| 828 if_false = efalse = | |
| 829 graph()->NewNode(common()->DeoptimizeUnless(), check_oddball, frame_state, | |
| 830 efalse, if_false); | |
| 831 STATIC_ASSERT(HeapNumber::kValueOffset == Oddball::kToNumberRawOffset); | |
| 832 | |
| 833 control = graph()->NewNode(common()->Merge(2), if_true, if_false); | |
| 834 effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control); | |
| 835 | |
| 836 Node* result = effect = graph()->NewNode( | |
| 837 simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), value, | |
| 838 effect, control); | |
| 839 return ValueEffectControl(result, effect, control); | |
| 840 } | |
| 841 | |
| 842 EffectControlLinearizer::ValueEffectControl | |
| 843 EffectControlLinearizer::LowerCheckedTaggedToFloat64(Node* node, Node* effect, | |
| 844 Node* control) { | |
| 845 Node* value = node->InputAt(0); | |
| 846 Node* frame_state = NodeProperties::GetFrameStateInput(node, 0); | |
| 847 | |
| 848 Node* check = ObjectIsSmi(value); | |
| 849 Node* branch = | |
| 850 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); | |
| 851 | |
| 852 // In the Smi case, just convert to int32 and then float64. | |
| 853 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); | |
| 854 Node* etrue = effect; | |
| 855 Node* vtrue = ChangeSmiToInt32(value); | |
| 856 vtrue = graph()->NewNode(machine()->ChangeInt32ToFloat64(), vtrue); | |
| 857 | |
| 858 // Otherwise, check heap numberness and load the number. | |
| 859 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); | |
| 860 // TODO(jarin) Truncate undefined (and null?) here. | |
|
Benedikt Meurer
2016/05/30 18:39:50
This TODO doesn't seem relevant anymore?
Jarin
2016/05/31 20:28:52
Done.
| |
| 861 ValueEffectControl number_state = BuildCheckedHeapNumberOrOddballToFloat64( | |
| 862 value, frame_state, effect, if_false); | |
| 863 | |
| 864 Node* merge = | |
| 865 graph()->NewNode(common()->Merge(2), if_true, number_state.control); | |
| 866 Node* effect_phi = graph()->NewNode(common()->EffectPhi(2), etrue, | |
| 867 number_state.effect, merge); | |
| 868 Node* result = | |
| 869 graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), vtrue, | |
| 870 number_state.value, merge); | |
| 871 return ValueEffectControl(result, effect_phi, merge); | |
| 872 } | |
| 873 | |
| 874 EffectControlLinearizer::ValueEffectControl | |
| 697 EffectControlLinearizer::LowerTruncateTaggedToWord32(Node* node, Node* effect, | 875 EffectControlLinearizer::LowerTruncateTaggedToWord32(Node* node, Node* effect, |
| 698 Node* control) { | 876 Node* control) { |
| 699 Node* value = node->InputAt(0); | 877 Node* value = node->InputAt(0); |
| 700 | 878 |
| 701 Node* check = ObjectIsSmi(value); | 879 Node* check = ObjectIsSmi(value); |
| 702 Node* branch = | 880 Node* branch = |
| 703 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); | 881 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); |
| 704 | 882 |
| 705 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); | 883 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); |
| 706 Node* etrue = effect; | 884 Node* etrue = effect; |
| (...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 974 return jsgraph()->Int32Constant(Smi::kMaxValue); | 1152 return jsgraph()->Int32Constant(Smi::kMaxValue); |
| 975 } | 1153 } |
| 976 | 1154 |
| 977 Node* EffectControlLinearizer::SmiShiftBitsConstant() { | 1155 Node* EffectControlLinearizer::SmiShiftBitsConstant() { |
| 978 return jsgraph()->IntPtrConstant(kSmiShiftSize + kSmiTagSize); | 1156 return jsgraph()->IntPtrConstant(kSmiShiftSize + kSmiTagSize); |
| 979 } | 1157 } |
| 980 | 1158 |
| 981 } // namespace compiler | 1159 } // namespace compiler |
| 982 } // namespace internal | 1160 } // namespace internal |
| 983 } // namespace v8 | 1161 } // namespace v8 |
| OLD | NEW |