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 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
258 for (Node* const phi : phis) { | 258 for (Node* const phi : phis) { |
259 for (int index = 0; index < input_count; ++index) { | 259 for (int index = 0; index < input_count; ++index) { |
260 inputs[index] = phi->InputAt(index); | 260 inputs[index] = phi->InputAt(index); |
261 } | 261 } |
262 inputs[input_count] = merge_true; | 262 inputs[input_count] = merge_true; |
263 Node* phi_true = graph->NewNode(phi->op(), input_count + 1, inputs); | 263 Node* phi_true = graph->NewNode(phi->op(), input_count + 1, inputs); |
264 inputs[input_count] = merge_false; | 264 inputs[input_count] = merge_false; |
265 Node* phi_false = graph->NewNode(phi->op(), input_count + 1, inputs); | 265 Node* phi_false = graph->NewNode(phi->op(), input_count + 1, inputs); |
266 if (phi->UseCount() == 0) { | 266 if (phi->UseCount() == 0) { |
267 DCHECK_EQ(phi->opcode(), IrOpcode::kEffectPhi); | 267 DCHECK_EQ(phi->opcode(), IrOpcode::kEffectPhi); |
| 268 DCHECK_EQ(input_count, block->SuccessorCount()); |
268 } else { | 269 } else { |
269 for (Edge edge : phi->use_edges()) { | 270 for (Edge edge : phi->use_edges()) { |
270 Node* control = NodeProperties::GetControlInput(edge.from()); | 271 Node* control = NodeProperties::GetControlInput(edge.from()); |
271 if (NodeProperties::IsPhi(edge.from())) { | 272 if (NodeProperties::IsPhi(edge.from())) { |
272 control = NodeProperties::GetControlInput(control, edge.index()); | 273 control = NodeProperties::GetControlInput(control, edge.index()); |
273 } | 274 } |
274 DCHECK(control == matcher.IfTrue() || control == matcher.IfFalse()); | 275 DCHECK(control == matcher.IfTrue() || control == matcher.IfFalse()); |
275 edge.UpdateTo((control == matcher.IfTrue()) ? phi_true : phi_false); | 276 edge.UpdateTo((control == matcher.IfTrue()) ? phi_true : phi_false); |
276 } | 277 } |
277 } | 278 } |
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
608 break; | 609 break; |
609 case IrOpcode::kChangeTaggedToInt32: | 610 case IrOpcode::kChangeTaggedToInt32: |
610 state = LowerChangeTaggedToInt32(node, *effect, *control); | 611 state = LowerChangeTaggedToInt32(node, *effect, *control); |
611 break; | 612 break; |
612 case IrOpcode::kChangeTaggedToUint32: | 613 case IrOpcode::kChangeTaggedToUint32: |
613 state = LowerChangeTaggedToUint32(node, *effect, *control); | 614 state = LowerChangeTaggedToUint32(node, *effect, *control); |
614 break; | 615 break; |
615 case IrOpcode::kChangeTaggedToFloat64: | 616 case IrOpcode::kChangeTaggedToFloat64: |
616 state = LowerChangeTaggedToFloat64(node, *effect, *control); | 617 state = LowerChangeTaggedToFloat64(node, *effect, *control); |
617 break; | 618 break; |
618 case IrOpcode::kTruncateTaggedToBit: | |
619 state = LowerTruncateTaggedToBit(node, *effect, *control); | |
620 break; | |
621 case IrOpcode::kTruncateTaggedToFloat64: | 619 case IrOpcode::kTruncateTaggedToFloat64: |
622 state = LowerTruncateTaggedToFloat64(node, *effect, *control); | 620 state = LowerTruncateTaggedToFloat64(node, *effect, *control); |
623 break; | 621 break; |
624 case IrOpcode::kCheckBounds: | 622 case IrOpcode::kCheckBounds: |
625 state = LowerCheckBounds(node, frame_state, *effect, *control); | 623 state = LowerCheckBounds(node, frame_state, *effect, *control); |
626 break; | 624 break; |
627 case IrOpcode::kCheckNumber: | 625 case IrOpcode::kCheckNumber: |
628 state = LowerCheckNumber(node, frame_state, *effect, *control); | 626 state = LowerCheckNumber(node, frame_state, *effect, *control); |
629 break; | 627 break; |
630 case IrOpcode::kCheckIf: | 628 case IrOpcode::kCheckIf: |
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
888 | 886 |
889 EffectControlLinearizer::ValueEffectControl | 887 EffectControlLinearizer::ValueEffectControl |
890 EffectControlLinearizer::LowerChangeTaggedToBit(Node* node, Node* effect, | 888 EffectControlLinearizer::LowerChangeTaggedToBit(Node* node, Node* effect, |
891 Node* control) { | 889 Node* control) { |
892 Node* value = node->InputAt(0); | 890 Node* value = node->InputAt(0); |
893 value = graph()->NewNode(machine()->WordEqual(), value, | 891 value = graph()->NewNode(machine()->WordEqual(), value, |
894 jsgraph()->TrueConstant()); | 892 jsgraph()->TrueConstant()); |
895 return ValueEffectControl(value, effect, control); | 893 return ValueEffectControl(value, effect, control); |
896 } | 894 } |
897 | 895 |
898 EffectControlLinearizer::ValueEffectControl | |
899 EffectControlLinearizer::LowerTruncateTaggedToBit(Node* node, Node* effect, | |
900 Node* control) { | |
901 Node* value = node->InputAt(0); | |
902 Node* one = jsgraph()->Int32Constant(1); | |
903 Node* zero = jsgraph()->Int32Constant(0); | |
904 Node* fzero = jsgraph()->Float64Constant(0.0); | |
905 | |
906 // Collect effect/control/value triples. | |
907 int count = 0; | |
908 Node* values[7]; | |
909 Node* effects[7]; | |
910 Node* controls[6]; | |
911 | |
912 // Check if {value} is a Smi. | |
913 Node* check_smi = ObjectIsSmi(value); | |
914 Node* branch_smi = graph()->NewNode(common()->Branch(BranchHint::kFalse), | |
915 check_smi, control); | |
916 | |
917 // If {value} is a Smi, then we only need to check that it's not zero. | |
918 Node* if_smi = graph()->NewNode(common()->IfTrue(), branch_smi); | |
919 Node* esmi = effect; | |
920 { | |
921 controls[count] = if_smi; | |
922 effects[count] = esmi; | |
923 values[count] = | |
924 graph()->NewNode(machine()->Word32Equal(), | |
925 graph()->NewNode(machine()->WordEqual(), value, | |
926 jsgraph()->ZeroConstant()), | |
927 zero); | |
928 count++; | |
929 } | |
930 control = graph()->NewNode(common()->IfFalse(), branch_smi); | |
931 | |
932 // Load the map instance type of {value}. | |
933 Node* value_map = effect = graph()->NewNode( | |
934 simplified()->LoadField(AccessBuilder::ForMap()), value, effect, control); | |
935 Node* value_instance_type = effect = graph()->NewNode( | |
936 simplified()->LoadField(AccessBuilder::ForMapInstanceType()), value_map, | |
937 effect, control); | |
938 | |
939 // Check if {value} is an Oddball. | |
940 Node* check_oddball = | |
941 graph()->NewNode(machine()->Word32Equal(), value_instance_type, | |
942 jsgraph()->Int32Constant(ODDBALL_TYPE)); | |
943 Node* branch_oddball = graph()->NewNode(common()->Branch(BranchHint::kTrue), | |
944 check_oddball, control); | |
945 | |
946 // The only Oddball {value} that is trueish is true itself. | |
947 Node* if_oddball = graph()->NewNode(common()->IfTrue(), branch_oddball); | |
948 Node* eoddball = effect; | |
949 { | |
950 controls[count] = if_oddball; | |
951 effects[count] = eoddball; | |
952 values[count] = graph()->NewNode(machine()->WordEqual(), value, | |
953 jsgraph()->TrueConstant()); | |
954 count++; | |
955 } | |
956 control = graph()->NewNode(common()->IfFalse(), branch_oddball); | |
957 | |
958 // Check if {value} is a String. | |
959 Node* check_string = | |
960 graph()->NewNode(machine()->Int32LessThan(), value_instance_type, | |
961 jsgraph()->Int32Constant(FIRST_NONSTRING_TYPE)); | |
962 Node* branch_string = | |
963 graph()->NewNode(common()->Branch(), check_string, control); | |
964 | |
965 // For String {value}, we need to check that the length is not zero. | |
966 Node* if_string = graph()->NewNode(common()->IfTrue(), branch_string); | |
967 Node* estring = effect; | |
968 { | |
969 // Load the {value} length. | |
970 Node* value_length = estring = graph()->NewNode( | |
971 simplified()->LoadField(AccessBuilder::ForStringLength()), value, | |
972 estring, if_string); | |
973 | |
974 controls[count] = if_string; | |
975 effects[count] = estring; | |
976 values[count] = | |
977 graph()->NewNode(machine()->Word32Equal(), | |
978 graph()->NewNode(machine()->WordEqual(), value_length, | |
979 jsgraph()->ZeroConstant()), | |
980 zero); | |
981 count++; | |
982 } | |
983 control = graph()->NewNode(common()->IfFalse(), branch_string); | |
984 | |
985 // Check if {value} is a HeapNumber. | |
986 Node* check_heapnumber = | |
987 graph()->NewNode(machine()->Word32Equal(), value_instance_type, | |
988 jsgraph()->Int32Constant(HEAP_NUMBER_TYPE)); | |
989 Node* branch_heapnumber = | |
990 graph()->NewNode(common()->Branch(), check_heapnumber, control); | |
991 | |
992 // For HeapNumber {value}, just check that its value is not 0.0, -0.0 or NaN. | |
993 Node* if_heapnumber = graph()->NewNode(common()->IfTrue(), branch_heapnumber); | |
994 Node* eheapnumber = effect; | |
995 { | |
996 // Load the raw value of {value}. | |
997 Node* value_value = eheapnumber = graph()->NewNode( | |
998 simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), value, | |
999 eheapnumber, if_heapnumber); | |
1000 | |
1001 // Check if {value} is either less than 0.0 or greater than 0.0. | |
1002 Node* check = | |
1003 graph()->NewNode(machine()->Float64LessThan(), fzero, value_value); | |
1004 Node* branch = graph()->NewNode(common()->Branch(), check, if_heapnumber); | |
1005 | |
1006 controls[count] = graph()->NewNode(common()->IfTrue(), branch); | |
1007 effects[count] = eheapnumber; | |
1008 values[count] = one; | |
1009 count++; | |
1010 | |
1011 controls[count] = graph()->NewNode(common()->IfFalse(), branch); | |
1012 effects[count] = eheapnumber; | |
1013 values[count] = | |
1014 graph()->NewNode(machine()->Float64LessThan(), value_value, fzero); | |
1015 count++; | |
1016 } | |
1017 control = graph()->NewNode(common()->IfFalse(), branch_heapnumber); | |
1018 | |
1019 // The {value} is either a JSReceiver, a Symbol or some Simd128Value. In | |
1020 // those cases we can just the undetectable bit on the map, which will only | |
1021 // be set for certain JSReceivers, i.e. document.all. | |
1022 { | |
1023 // Load the {value} map bit field. | |
1024 Node* value_map_bitfield = effect = graph()->NewNode( | |
1025 simplified()->LoadField(AccessBuilder::ForMapBitField()), value_map, | |
1026 effect, control); | |
1027 | |
1028 controls[count] = control; | |
1029 effects[count] = effect; | |
1030 values[count] = graph()->NewNode( | |
1031 machine()->Word32Equal(), | |
1032 graph()->NewNode(machine()->Word32And(), value_map_bitfield, | |
1033 jsgraph()->Int32Constant(1 << Map::kIsUndetectable)), | |
1034 zero); | |
1035 count++; | |
1036 } | |
1037 | |
1038 // Merge the different controls. | |
1039 control = graph()->NewNode(common()->Merge(count), count, controls); | |
1040 effects[count] = control; | |
1041 effect = graph()->NewNode(common()->EffectPhi(count), count + 1, effects); | |
1042 values[count] = control; | |
1043 value = graph()->NewNode(common()->Phi(MachineRepresentation::kBit, count), | |
1044 count + 1, values); | |
1045 | |
1046 return ValueEffectControl(value, effect, control); | |
1047 } | |
1048 | |
1049 EffectControlLinearizer::ValueEffectControl | 896 EffectControlLinearizer::ValueEffectControl |
1050 EffectControlLinearizer::LowerChangeTaggedToInt32(Node* node, Node* effect, | 897 EffectControlLinearizer::LowerChangeTaggedToInt32(Node* node, Node* effect, |
1051 Node* control) { | 898 Node* control) { |
1052 Node* value = node->InputAt(0); | 899 Node* value = node->InputAt(0); |
1053 | 900 |
1054 Node* check = ObjectIsSmi(value); | 901 Node* check = ObjectIsSmi(value); |
1055 Node* branch = | 902 Node* branch = |
1056 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); | 903 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); |
1057 | 904 |
1058 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); | 905 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); |
(...skipping 1293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2352 isolate(), graph()->zone(), callable.descriptor(), 0, flags, | 2199 isolate(), graph()->zone(), callable.descriptor(), 0, flags, |
2353 Operator::kNoThrow); | 2200 Operator::kNoThrow); |
2354 to_number_operator_.set(common()->Call(desc)); | 2201 to_number_operator_.set(common()->Call(desc)); |
2355 } | 2202 } |
2356 return to_number_operator_.get(); | 2203 return to_number_operator_.get(); |
2357 } | 2204 } |
2358 | 2205 |
2359 } // namespace compiler | 2206 } // namespace compiler |
2360 } // namespace internal | 2207 } // namespace internal |
2361 } // namespace v8 | 2208 } // namespace v8 |
OLD | NEW |