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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/compiler/effect-control-linearizer.h ('k') | src/compiler/opcodes.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler/effect-control-linearizer.cc
diff --git a/src/compiler/effect-control-linearizer.cc b/src/compiler/effect-control-linearizer.cc
index c69eec09b1e51661693fbdd261d798e5250a849e..362df3ae31758a4180f00a4ac13c4f09e240148d 100644
--- a/src/compiler/effect-control-linearizer.cc
+++ b/src/compiler/effect-control-linearizer.cc
@@ -265,7 +265,6 @@ void TryCloneBranch(Node* node, BasicBlock* block, Graph* graph,
Node* phi_false = graph->NewNode(phi->op(), input_count + 1, inputs);
if (phi->UseCount() == 0) {
DCHECK_EQ(phi->opcode(), IrOpcode::kEffectPhi);
- DCHECK_EQ(input_count, block->SuccessorCount());
} else {
for (Edge edge : phi->use_edges()) {
Node* control = NodeProperties::GetControlInput(edge.from());
@@ -616,6 +615,9 @@ bool EffectControlLinearizer::TryWireInStateEffect(Node* node,
case IrOpcode::kChangeTaggedToFloat64:
state = LowerChangeTaggedToFloat64(node, *effect, *control);
break;
+ case IrOpcode::kTruncateTaggedToBit:
+ state = LowerTruncateTaggedToBit(node, *effect, *control);
+ break;
case IrOpcode::kTruncateTaggedToFloat64:
state = LowerTruncateTaggedToFloat64(node, *effect, *control);
break;
@@ -942,6 +944,157 @@ EffectControlLinearizer::LowerChangeTaggedToBit(Node* node, Node* effect,
}
EffectControlLinearizer::ValueEffectControl
+EffectControlLinearizer::LowerTruncateTaggedToBit(Node* node, Node* effect,
+ Node* control) {
+ Node* value = node->InputAt(0);
+ Node* one = jsgraph()->Int32Constant(1);
+ Node* zero = jsgraph()->Int32Constant(0);
+ Node* fzero = jsgraph()->Float64Constant(0.0);
+
+ // Collect effect/control/value triples.
+ int count = 0;
+ Node* values[7];
+ Node* effects[7];
+ Node* controls[6];
+
+ // Check if {value} is a Smi.
+ Node* check_smi = ObjectIsSmi(value);
+ Node* branch_smi = graph()->NewNode(common()->Branch(BranchHint::kFalse),
+ check_smi, control);
+
+ // If {value} is a Smi, then we only need to check that it's not zero.
+ Node* if_smi = graph()->NewNode(common()->IfTrue(), branch_smi);
+ Node* esmi = effect;
+ {
+ controls[count] = if_smi;
+ effects[count] = esmi;
+ values[count] =
+ graph()->NewNode(machine()->Word32Equal(),
+ graph()->NewNode(machine()->WordEqual(), value,
+ jsgraph()->ZeroConstant()),
+ zero);
+ count++;
+ }
+ control = graph()->NewNode(common()->IfFalse(), branch_smi);
+
+ // Load the map instance type of {value}.
+ Node* value_map = effect = graph()->NewNode(
+ simplified()->LoadField(AccessBuilder::ForMap()), value, effect, control);
+ Node* value_instance_type = effect = graph()->NewNode(
+ simplified()->LoadField(AccessBuilder::ForMapInstanceType()), value_map,
+ effect, control);
+
+ // Check if {value} is an Oddball.
+ Node* check_oddball =
+ graph()->NewNode(machine()->Word32Equal(), value_instance_type,
+ jsgraph()->Int32Constant(ODDBALL_TYPE));
+ Node* branch_oddball = graph()->NewNode(common()->Branch(BranchHint::kTrue),
+ check_oddball, control);
+
+ // The only Oddball {value} that is trueish is true itself.
+ Node* if_oddball = graph()->NewNode(common()->IfTrue(), branch_oddball);
+ Node* eoddball = effect;
+ {
+ controls[count] = if_oddball;
+ effects[count] = eoddball;
+ values[count] = graph()->NewNode(machine()->WordEqual(), value,
+ jsgraph()->TrueConstant());
+ count++;
+ }
+ control = graph()->NewNode(common()->IfFalse(), branch_oddball);
+
+ // Check if {value} is a String.
+ Node* check_string =
+ graph()->NewNode(machine()->Int32LessThan(), value_instance_type,
+ jsgraph()->Int32Constant(FIRST_NONSTRING_TYPE));
+ Node* branch_string =
+ graph()->NewNode(common()->Branch(), check_string, control);
+
+ // For String {value}, we need to check that the length is not zero.
+ Node* if_string = graph()->NewNode(common()->IfTrue(), branch_string);
+ Node* estring = effect;
+ {
+ // Load the {value} length.
+ Node* value_length = estring = graph()->NewNode(
+ simplified()->LoadField(AccessBuilder::ForStringLength()), value,
+ estring, if_string);
+
+ controls[count] = if_string;
+ effects[count] = estring;
+ values[count] =
+ graph()->NewNode(machine()->Word32Equal(),
+ graph()->NewNode(machine()->WordEqual(), value_length,
+ jsgraph()->ZeroConstant()),
+ zero);
+ count++;
+ }
+ control = graph()->NewNode(common()->IfFalse(), branch_string);
+
+ // Check if {value} is a HeapNumber.
+ Node* check_heapnumber =
+ graph()->NewNode(machine()->Word32Equal(), value_instance_type,
+ jsgraph()->Int32Constant(HEAP_NUMBER_TYPE));
+ Node* branch_heapnumber =
+ graph()->NewNode(common()->Branch(), check_heapnumber, control);
+
+ // For HeapNumber {value}, just check that its value is not 0.0, -0.0 or NaN.
+ Node* if_heapnumber = graph()->NewNode(common()->IfTrue(), branch_heapnumber);
+ Node* eheapnumber = effect;
+ {
+ // Load the raw value of {value}.
+ Node* value_value = eheapnumber = graph()->NewNode(
+ simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), value,
+ eheapnumber, if_heapnumber);
+
+ // Check if {value} is either less than 0.0 or greater than 0.0.
+ Node* check =
+ graph()->NewNode(machine()->Float64LessThan(), fzero, value_value);
+ Node* branch = graph()->NewNode(common()->Branch(), check, if_heapnumber);
+
+ controls[count] = graph()->NewNode(common()->IfTrue(), branch);
+ effects[count] = eheapnumber;
+ values[count] = one;
+ count++;
+
+ controls[count] = graph()->NewNode(common()->IfFalse(), branch);
+ effects[count] = eheapnumber;
+ values[count] =
+ graph()->NewNode(machine()->Float64LessThan(), value_value, fzero);
+ count++;
+ }
+ control = graph()->NewNode(common()->IfFalse(), branch_heapnumber);
+
+ // The {value} is either a JSReceiver, a Symbol or some Simd128Value. In
+ // those cases we can just the undetectable bit on the map, which will only
+ // be set for certain JSReceivers, i.e. document.all.
+ {
+ // Load the {value} map bit field.
+ Node* value_map_bitfield = effect = graph()->NewNode(
+ simplified()->LoadField(AccessBuilder::ForMapBitField()), value_map,
+ effect, control);
+
+ controls[count] = control;
+ effects[count] = effect;
+ values[count] = graph()->NewNode(
+ machine()->Word32Equal(),
+ graph()->NewNode(machine()->Word32And(), value_map_bitfield,
+ jsgraph()->Int32Constant(1 << Map::kIsUndetectable)),
+ zero);
+ count++;
+ }
+
+ // Merge the different controls.
+ control = graph()->NewNode(common()->Merge(count), count, controls);
+ effects[count] = control;
+ effect = graph()->NewNode(common()->EffectPhi(count), count + 1, effects);
+ values[count] = control;
+ value = graph()->NewNode(common()->Phi(MachineRepresentation::kBit, count),
+ count + 1, values);
+
+ return ValueEffectControl(value, effect, control);
+}
+
+EffectControlLinearizer::ValueEffectControl
EffectControlLinearizer::LowerChangeTaggedToInt32(Node* node, Node* effect,
Node* control) {
Node* value = node->InputAt(0);
« 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