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

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

Issue 2167593002: [turbofan] Introduce TruncateTaggedToBit operator for ToBoolean truncation. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix remaining bugs. Created 4 years, 3 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
« no previous file with comments | « src/compiler/effect-control-linearizer.h ('k') | src/compiler/opcodes.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
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());
269 } else { 268 } else {
270 for (Edge edge : phi->use_edges()) { 269 for (Edge edge : phi->use_edges()) {
271 Node* control = NodeProperties::GetControlInput(edge.from()); 270 Node* control = NodeProperties::GetControlInput(edge.from());
272 if (NodeProperties::IsPhi(edge.from())) { 271 if (NodeProperties::IsPhi(edge.from())) {
273 control = NodeProperties::GetControlInput(control, edge.index()); 272 control = NodeProperties::GetControlInput(control, edge.index());
274 } 273 }
275 DCHECK(control == matcher.IfTrue() || control == matcher.IfFalse()); 274 DCHECK(control == matcher.IfTrue() || control == matcher.IfFalse());
276 edge.UpdateTo((control == matcher.IfTrue()) ? phi_true : phi_false); 275 edge.UpdateTo((control == matcher.IfTrue()) ? phi_true : phi_false);
277 } 276 }
278 } 277 }
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after
609 break; 608 break;
610 case IrOpcode::kChangeTaggedToInt32: 609 case IrOpcode::kChangeTaggedToInt32:
611 state = LowerChangeTaggedToInt32(node, *effect, *control); 610 state = LowerChangeTaggedToInt32(node, *effect, *control);
612 break; 611 break;
613 case IrOpcode::kChangeTaggedToUint32: 612 case IrOpcode::kChangeTaggedToUint32:
614 state = LowerChangeTaggedToUint32(node, *effect, *control); 613 state = LowerChangeTaggedToUint32(node, *effect, *control);
615 break; 614 break;
616 case IrOpcode::kChangeTaggedToFloat64: 615 case IrOpcode::kChangeTaggedToFloat64:
617 state = LowerChangeTaggedToFloat64(node, *effect, *control); 616 state = LowerChangeTaggedToFloat64(node, *effect, *control);
618 break; 617 break;
618 case IrOpcode::kTruncateTaggedToBit:
619 state = LowerTruncateTaggedToBit(node, *effect, *control);
620 break;
619 case IrOpcode::kTruncateTaggedToFloat64: 621 case IrOpcode::kTruncateTaggedToFloat64:
620 state = LowerTruncateTaggedToFloat64(node, *effect, *control); 622 state = LowerTruncateTaggedToFloat64(node, *effect, *control);
621 break; 623 break;
622 case IrOpcode::kCheckBounds: 624 case IrOpcode::kCheckBounds:
623 state = LowerCheckBounds(node, frame_state, *effect, *control); 625 state = LowerCheckBounds(node, frame_state, *effect, *control);
624 break; 626 break;
625 case IrOpcode::kCheckMaps: 627 case IrOpcode::kCheckMaps:
626 state = LowerCheckMaps(node, frame_state, *effect, *control); 628 state = LowerCheckMaps(node, frame_state, *effect, *control);
627 break; 629 break;
628 case IrOpcode::kCheckNumber: 630 case IrOpcode::kCheckNumber:
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after
935 EffectControlLinearizer::ValueEffectControl 937 EffectControlLinearizer::ValueEffectControl
936 EffectControlLinearizer::LowerChangeTaggedToBit(Node* node, Node* effect, 938 EffectControlLinearizer::LowerChangeTaggedToBit(Node* node, Node* effect,
937 Node* control) { 939 Node* control) {
938 Node* value = node->InputAt(0); 940 Node* value = node->InputAt(0);
939 value = graph()->NewNode(machine()->WordEqual(), value, 941 value = graph()->NewNode(machine()->WordEqual(), value,
940 jsgraph()->TrueConstant()); 942 jsgraph()->TrueConstant());
941 return ValueEffectControl(value, effect, control); 943 return ValueEffectControl(value, effect, control);
942 } 944 }
943 945
944 EffectControlLinearizer::ValueEffectControl 946 EffectControlLinearizer::ValueEffectControl
947 EffectControlLinearizer::LowerTruncateTaggedToBit(Node* node, Node* effect,
948 Node* control) {
949 Node* value = node->InputAt(0);
950 Node* one = jsgraph()->Int32Constant(1);
951 Node* zero = jsgraph()->Int32Constant(0);
952 Node* fzero = jsgraph()->Float64Constant(0.0);
953
954 // Collect effect/control/value triples.
955 int count = 0;
956 Node* values[7];
957 Node* effects[7];
958 Node* controls[6];
959
960 // Check if {value} is a Smi.
961 Node* check_smi = ObjectIsSmi(value);
962 Node* branch_smi = graph()->NewNode(common()->Branch(BranchHint::kFalse),
963 check_smi, control);
964
965 // If {value} is a Smi, then we only need to check that it's not zero.
966 Node* if_smi = graph()->NewNode(common()->IfTrue(), branch_smi);
967 Node* esmi = effect;
968 {
969 controls[count] = if_smi;
970 effects[count] = esmi;
971 values[count] =
972 graph()->NewNode(machine()->Word32Equal(),
973 graph()->NewNode(machine()->WordEqual(), value,
974 jsgraph()->ZeroConstant()),
975 zero);
976 count++;
977 }
978 control = graph()->NewNode(common()->IfFalse(), branch_smi);
979
980 // Load the map instance type of {value}.
981 Node* value_map = effect = graph()->NewNode(
982 simplified()->LoadField(AccessBuilder::ForMap()), value, effect, control);
983 Node* value_instance_type = effect = graph()->NewNode(
984 simplified()->LoadField(AccessBuilder::ForMapInstanceType()), value_map,
985 effect, control);
986
987 // Check if {value} is an Oddball.
988 Node* check_oddball =
989 graph()->NewNode(machine()->Word32Equal(), value_instance_type,
990 jsgraph()->Int32Constant(ODDBALL_TYPE));
991 Node* branch_oddball = graph()->NewNode(common()->Branch(BranchHint::kTrue),
992 check_oddball, control);
993
994 // The only Oddball {value} that is trueish is true itself.
995 Node* if_oddball = graph()->NewNode(common()->IfTrue(), branch_oddball);
996 Node* eoddball = effect;
997 {
998 controls[count] = if_oddball;
999 effects[count] = eoddball;
1000 values[count] = graph()->NewNode(machine()->WordEqual(), value,
1001 jsgraph()->TrueConstant());
1002 count++;
1003 }
1004 control = graph()->NewNode(common()->IfFalse(), branch_oddball);
1005
1006 // Check if {value} is a String.
1007 Node* check_string =
1008 graph()->NewNode(machine()->Int32LessThan(), value_instance_type,
1009 jsgraph()->Int32Constant(FIRST_NONSTRING_TYPE));
1010 Node* branch_string =
1011 graph()->NewNode(common()->Branch(), check_string, control);
1012
1013 // For String {value}, we need to check that the length is not zero.
1014 Node* if_string = graph()->NewNode(common()->IfTrue(), branch_string);
1015 Node* estring = effect;
1016 {
1017 // Load the {value} length.
1018 Node* value_length = estring = graph()->NewNode(
1019 simplified()->LoadField(AccessBuilder::ForStringLength()), value,
1020 estring, if_string);
1021
1022 controls[count] = if_string;
1023 effects[count] = estring;
1024 values[count] =
1025 graph()->NewNode(machine()->Word32Equal(),
1026 graph()->NewNode(machine()->WordEqual(), value_length,
1027 jsgraph()->ZeroConstant()),
1028 zero);
1029 count++;
1030 }
1031 control = graph()->NewNode(common()->IfFalse(), branch_string);
1032
1033 // Check if {value} is a HeapNumber.
1034 Node* check_heapnumber =
1035 graph()->NewNode(machine()->Word32Equal(), value_instance_type,
1036 jsgraph()->Int32Constant(HEAP_NUMBER_TYPE));
1037 Node* branch_heapnumber =
1038 graph()->NewNode(common()->Branch(), check_heapnumber, control);
1039
1040 // For HeapNumber {value}, just check that its value is not 0.0, -0.0 or NaN.
1041 Node* if_heapnumber = graph()->NewNode(common()->IfTrue(), branch_heapnumber);
1042 Node* eheapnumber = effect;
1043 {
1044 // Load the raw value of {value}.
1045 Node* value_value = eheapnumber = graph()->NewNode(
1046 simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), value,
1047 eheapnumber, if_heapnumber);
1048
1049 // Check if {value} is either less than 0.0 or greater than 0.0.
1050 Node* check =
1051 graph()->NewNode(machine()->Float64LessThan(), fzero, value_value);
1052 Node* branch = graph()->NewNode(common()->Branch(), check, if_heapnumber);
1053
1054 controls[count] = graph()->NewNode(common()->IfTrue(), branch);
1055 effects[count] = eheapnumber;
1056 values[count] = one;
1057 count++;
1058
1059 controls[count] = graph()->NewNode(common()->IfFalse(), branch);
1060 effects[count] = eheapnumber;
1061 values[count] =
1062 graph()->NewNode(machine()->Float64LessThan(), value_value, fzero);
1063 count++;
1064 }
1065 control = graph()->NewNode(common()->IfFalse(), branch_heapnumber);
1066
1067 // The {value} is either a JSReceiver, a Symbol or some Simd128Value. In
1068 // those cases we can just the undetectable bit on the map, which will only
1069 // be set for certain JSReceivers, i.e. document.all.
1070 {
1071 // Load the {value} map bit field.
1072 Node* value_map_bitfield = effect = graph()->NewNode(
1073 simplified()->LoadField(AccessBuilder::ForMapBitField()), value_map,
1074 effect, control);
1075
1076 controls[count] = control;
1077 effects[count] = effect;
1078 values[count] = graph()->NewNode(
1079 machine()->Word32Equal(),
1080 graph()->NewNode(machine()->Word32And(), value_map_bitfield,
1081 jsgraph()->Int32Constant(1 << Map::kIsUndetectable)),
1082 zero);
1083 count++;
1084 }
1085
1086 // Merge the different controls.
1087 control = graph()->NewNode(common()->Merge(count), count, controls);
1088 effects[count] = control;
1089 effect = graph()->NewNode(common()->EffectPhi(count), count + 1, effects);
1090 values[count] = control;
1091 value = graph()->NewNode(common()->Phi(MachineRepresentation::kBit, count),
1092 count + 1, values);
1093
1094 return ValueEffectControl(value, effect, control);
1095 }
1096
1097 EffectControlLinearizer::ValueEffectControl
945 EffectControlLinearizer::LowerChangeTaggedToInt32(Node* node, Node* effect, 1098 EffectControlLinearizer::LowerChangeTaggedToInt32(Node* node, Node* effect,
946 Node* control) { 1099 Node* control) {
947 Node* value = node->InputAt(0); 1100 Node* value = node->InputAt(0);
948 1101
949 Node* check = ObjectIsSmi(value); 1102 Node* check = ObjectIsSmi(value);
950 Node* branch = 1103 Node* branch =
951 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); 1104 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
952 1105
953 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); 1106 Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
954 Node* etrue = effect; 1107 Node* etrue = effect;
(...skipping 2353 matching lines...) Expand 10 before | Expand all | Expand 10 after
3308 isolate(), graph()->zone(), callable.descriptor(), 0, flags, 3461 isolate(), graph()->zone(), callable.descriptor(), 0, flags,
3309 Operator::kEliminatable); 3462 Operator::kEliminatable);
3310 to_number_operator_.set(common()->Call(desc)); 3463 to_number_operator_.set(common()->Call(desc));
3311 } 3464 }
3312 return to_number_operator_.get(); 3465 return to_number_operator_.get();
3313 } 3466 }
3314 3467
3315 } // namespace compiler 3468 } // namespace compiler
3316 } // namespace internal 3469 } // namespace internal
3317 } // namespace v8 3470 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/effect-control-linearizer.h ('k') | src/compiler/opcodes.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698