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 |