Commit 2eaca10e authored by Benedikt Meurer's avatar Benedikt Meurer

[turbofan] Fix pushing of JSToBooleans into Phis.

Now we actually implement it the way it is meant to be, that is:

  JSToBoolean(Phi(x1,...,xn):primitive)
    => Phi(JSToBoolean(x1),...,JSToBoolean(xn)):boolean

This also fixes the endless recursion within JSTypedLowering when
the GraphReducer does all possible reductions instead of using the
generic algorithm.

R=dcarney@chromium.org

Review URL: https://codereview.chromium.org/730043002

Cr-Commit-Position: refs/heads/master@{#25376}
parent ca268fe2
...@@ -527,11 +527,8 @@ Reduction JSTypedLowering::ReduceJSToStringInput(Node* input) { ...@@ -527,11 +527,8 @@ Reduction JSTypedLowering::ReduceJSToStringInput(Node* input) {
Reduction JSTypedLowering::ReduceJSToBooleanInput(Node* input) { Reduction JSTypedLowering::ReduceJSToBooleanInput(Node* input) {
if (input->opcode() == IrOpcode::kJSToBoolean) { if (input->opcode() == IrOpcode::kJSToBoolean) {
// Recursively try to reduce the input first. // Recursively try to reduce the input first.
Reduction result = ReduceJSToBooleanInput(input->InputAt(0)); Reduction result = ReduceJSToBoolean(input);
if (result.Changed()) { if (result.Changed()) return result;
RelaxEffects(input);
return result;
}
return Changed(input); // JSToBoolean(JSToBoolean(x)) => JSToBoolean(x) return Changed(input); // JSToBoolean(JSToBoolean(x)) => JSToBoolean(x)
} }
Type* input_type = NodeProperties::GetBounds(input).upper; Type* input_type = NodeProperties::GetBounds(input).upper;
...@@ -571,37 +568,54 @@ Reduction JSTypedLowering::ReduceJSToBooleanInput(Node* input) { ...@@ -571,37 +568,54 @@ Reduction JSTypedLowering::ReduceJSToBooleanInput(Node* input) {
Node* inv = graph()->NewNode(simplified()->BooleanNot(), cmp); Node* inv = graph()->NewNode(simplified()->BooleanNot(), cmp);
return ReplaceWith(inv); return ReplaceWith(inv);
} }
// TODO(turbofan): We need some kinda of PrimitiveToBoolean simplified return NoChange();
// operator, then we can do the pushing in the SimplifiedOperatorReducer }
// and do not need to protect against stack overflow (because of backedges
// in phis) below.
if (input->opcode() == IrOpcode::kPhi && Reduction JSTypedLowering::ReduceJSToBoolean(Node* node) {
input_type->Is( // Try to reduce the input first.
Type::Union(Type::Boolean(), Type::OrderedNumber(), zone()))) { Node* const input = node->InputAt(0);
// JSToBoolean(phi(x1,...,xn):ordered-number|boolean) Reduction reduction = ReduceJSToBooleanInput(input);
// => phi(JSToBoolean(x1),...,JSToBoolean(xn)) if (reduction.Changed()) {
int input_count = input->InputCount() - 1; NodeProperties::ReplaceWithValue(node, reduction.replacement());
Node** inputs = zone()->NewArray<Node*>(input_count + 1); return reduction;
}
Type* const input_type = NodeProperties::GetBounds(input).upper;
if (input->opcode() == IrOpcode::kPhi && input_type->Is(Type::Primitive())) {
// JSToBoolean(phi(x1,...,xn,control):primitive)
// => phi(JSToBoolean(x1),...,JSToBoolean(xn),control):boolean
RelaxEffects(node);
int const input_count = input->InputCount() - 1;
Node* const control = input->InputAt(input_count);
DCHECK_LE(0, input_count);
DCHECK(NodeProperties::IsControl(control));
DCHECK(NodeProperties::GetBounds(node).upper->Is(Type::Boolean()));
DCHECK(!NodeProperties::GetBounds(input).upper->Is(Type::Boolean()));
node->set_op(common()->Phi(kMachAnyTagged, input_count));
for (int i = 0; i < input_count; ++i) { for (int i = 0; i < input_count; ++i) {
Node* value = input->InputAt(i); Node* value = input->InputAt(i);
Type* value_type = NodeProperties::GetBounds(value).upper;
// Recursively try to reduce the value first. // Recursively try to reduce the value first.
Reduction result = (value_type->Is(Type::Boolean()) || Reduction reduction = ReduceJSToBooleanInput(value);
value_type->Is(Type::OrderedNumber())) if (reduction.Changed()) {
? ReduceJSToBooleanInput(value) value = reduction.replacement();
: NoChange();
if (result.Changed()) {
inputs[i] = result.replacement();
} else { } else {
inputs[i] = graph()->NewNode(javascript()->ToBoolean(), value, value = graph()->NewNode(javascript()->ToBoolean(), value,
jsgraph()->ZeroConstant(), jsgraph()->ZeroConstant(), graph()->start(),
graph()->start(), graph()->start()); graph()->start());
}
if (i < node->InputCount()) {
node->ReplaceInput(i, value);
} else {
node->AppendInput(graph()->zone(), value);
} }
} }
inputs[input_count] = input->InputAt(input_count); if (input_count < node->InputCount()) {
Node* phi = graph()->NewNode(common()->Phi(kMachAnyTagged, input_count), node->ReplaceInput(input_count, control);
input_count + 1, inputs); } else {
return ReplaceWith(phi); node->AppendInput(graph()->zone(), control);
}
node->TrimInputCount(input_count + 1);
return Changed(node);
} }
return NoChange(); return NoChange();
} }
...@@ -753,8 +767,7 @@ Reduction JSTypedLowering::Reduce(Node* node) { ...@@ -753,8 +767,7 @@ Reduction JSTypedLowering::Reduce(Node* node) {
} }
} }
case IrOpcode::kJSToBoolean: case IrOpcode::kJSToBoolean:
return ReplaceWithReduction(node, return ReduceJSToBoolean(node);
ReduceJSToBooleanInput(node->InputAt(0)));
case IrOpcode::kJSToNumber: case IrOpcode::kJSToNumber:
return ReplaceWithReduction(node, return ReplaceWithReduction(node,
ReduceJSToNumberInput(node->InputAt(0))); ReduceJSToNumberInput(node->InputAt(0)));
......
...@@ -43,6 +43,7 @@ class JSTypedLowering FINAL : public Reducer { ...@@ -43,6 +43,7 @@ class JSTypedLowering FINAL : public Reducer {
Reduction ReduceJSToNumberInput(Node* input); Reduction ReduceJSToNumberInput(Node* input);
Reduction ReduceJSToStringInput(Node* input); Reduction ReduceJSToStringInput(Node* input);
Reduction ReduceJSToBooleanInput(Node* input); Reduction ReduceJSToBooleanInput(Node* input);
Reduction ReduceJSToBoolean(Node* node);
Reduction ReduceNumberBinop(Node* node, const Operator* numberOp); Reduction ReduceNumberBinop(Node* node, const Operator* numberOp);
Reduction ReduceI32Binop(Node* node, bool left_signed, bool right_signed, Reduction ReduceI32Binop(Node* node, bool left_signed, bool right_signed,
const Operator* intOp); const Operator* intOp);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment