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

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

Issue 1921563002: [turbofan] Initial version of number type feedback. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Add tests for the checks and fix check insertion Created 4 years, 6 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/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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698