Commit 76949ba4 authored by bmeurer's avatar bmeurer Committed by Commit bot

[turbofan] Consume number type hints for strict equality.

This allows us to consume the type hints gathered by the CompareIC
for the strict equality and inequality operators. Similar to abstract
equality We need to distinguish Number and NumberOrOddball feedback,
as strict equality doesn't truncate Oddball to Number.

R=epertoso@chromium.org
BUG=v8:4583

Review-Url: https://codereview.chromium.org/2222993003
Cr-Commit-Position: refs/heads/master@{#38438}
parent f8938e50
......@@ -120,14 +120,14 @@ void JSGenericLowering::ReplaceWithRuntimeCall(Node* node,
void JSGenericLowering::LowerJSStrictEqual(Node* node) {
Callable callable = CodeFactory::StrictEqual(isolate());
node->AppendInput(zone(), graph()->start());
node->RemoveInput(4); // control
ReplaceWithStubCall(node, callable, CallDescriptor::kNoFlags,
Operator::kEliminatable);
}
void JSGenericLowering::LowerJSStrictNotEqual(Node* node) {
Callable callable = CodeFactory::StrictNotEqual(isolate());
node->AppendInput(zone(), graph()->start());
node->RemoveInput(4); // control
ReplaceWithStubCall(node, callable, CallDescriptor::kNoFlags,
Operator::kEliminatable);
}
......
......@@ -579,7 +579,7 @@ const Operator* JSOperatorBuilder::StrictEqual(CompareOperationHints hints) {
return new (zone()) Operator1<CompareOperationHints>( //--
IrOpcode::kJSStrictEqual, Operator::kPure, // opcode
"JSStrictEqual", // name
2, 0, 0, 1, 0, 0, // inputs/outputs
2, 1, 1, 1, 1, 0, // inputs/outputs
hints); // parameter
}
......@@ -588,7 +588,7 @@ const Operator* JSOperatorBuilder::StrictNotEqual(CompareOperationHints hints) {
return new (zone()) Operator1<CompareOperationHints>( //--
IrOpcode::kJSStrictNotEqual, Operator::kPure, // opcode
"JSStrictNotEqual", // name
2, 0, 0, 1, 0, 0, // inputs/outputs
2, 1, 1, 1, 1, 0, // inputs/outputs
hints); // parameter
}
......
......@@ -55,9 +55,7 @@ class JSBinopReduction final {
bool GetCompareNumberOperationHint(NumberOperationHint* hint) {
if (lowering_->flags() & JSTypedLowering::kDeoptimizationEnabled) {
DCHECK_NE(0, node_->op()->ControlOutputCount());
DCHECK_EQ(1, node_->op()->EffectOutputCount());
DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node_->op()));
CompareOperationHints hints = CompareOperationHintsOf(node_->op());
switch (hints.combined()) {
case CompareOperationHints::kSignedSmall:
......@@ -175,8 +173,6 @@ class JSBinopReduction final {
DCHECK_EQ(1, node_->op()->EffectInputCount());
DCHECK_EQ(1, node_->op()->EffectOutputCount());
DCHECK_EQ(1, node_->op()->ControlInputCount());
DCHECK_LT(1, node_->op()->ControlOutputCount());
DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node_->op()));
DCHECK_EQ(2, node_->op()->ValueInputCount());
// Reconnect the control output to bypass the IfSuccess node and
......@@ -196,7 +192,9 @@ class JSBinopReduction final {
}
// Remove the frame state and the context.
node_->RemoveInput(NodeProperties::FirstFrameStateIndex(node_));
if (OperatorProperties::HasFrameStateInput(node_->op())) {
node_->RemoveInput(NodeProperties::FirstFrameStateIndex(node_));
}
node_->RemoveInput(NodeProperties::FirstContextIndex(node_));
NodeProperties::ChangeOp(node_, op);
......@@ -694,6 +692,7 @@ Reduction JSTypedLowering::ReduceJSEqualTypeOf(Node* node, bool invert) {
if (invert) {
replacement = graph()->NewNode(simplified()->BooleanNot(), replacement);
}
ReplaceWithValue(node, replacement);
return Replace(replacement);
}
return NoChange();
......@@ -701,10 +700,7 @@ Reduction JSTypedLowering::ReduceJSEqualTypeOf(Node* node, bool invert) {
Reduction JSTypedLowering::ReduceJSEqual(Node* node, bool invert) {
Reduction const reduction = ReduceJSEqualTypeOf(node, invert);
if (reduction.Changed()) {
ReplaceWithValue(node, reduction.replacement());
return reduction;
}
if (reduction.Changed()) return reduction;
JSBinopReduction r(this, node);
......@@ -769,10 +765,10 @@ Reduction JSTypedLowering::ReduceJSStrictEqual(Node* node, bool invert) {
return Replace(replacement);
}
}
Reduction const reduction = ReduceJSEqualTypeOf(node, invert);
if (reduction.Changed()) {
return reduction;
}
if (reduction.Changed()) return reduction;
if (r.OneInputIs(the_hole_type_)) {
return r.ChangeToPureOperator(simplified()->ReferenceEqual(the_hole_type_),
invert);
......@@ -804,10 +800,17 @@ Reduction JSTypedLowering::ReduceJSStrictEqual(Node* node, bool invert) {
if (r.BothInputsAre(Type::String())) {
return r.ChangeToPureOperator(simplified()->StringEqual(), invert);
}
if (r.BothInputsAre(Type::Number())) {
NumberOperationHint hint;
if (r.BothInputsAre(Type::Signed32()) ||
r.BothInputsAre(Type::Unsigned32())) {
return r.ChangeToPureOperator(simplified()->NumberEqual(), invert);
} else if (r.GetCompareNumberOperationHint(&hint)) {
return r.ChangeToSpeculativeOperator(
simplified()->SpeculativeNumberEqual(hint), invert, Type::Boolean());
} else if (r.BothInputsAre(Type::Number())) {
return r.ChangeToPureOperator(simplified()->NumberEqual(), invert);
}
// TODO(turbofan): js-typed-lowering of StrictEqual(mixed types)
return NoChange();
}
......
......@@ -390,11 +390,13 @@ TEST_F(JSTypedLoweringTest, JSToStringWithBoolean) {
TEST_F(JSTypedLoweringTest, JSStrictEqualWithTheHole) {
Node* const the_hole = HeapConstant(factory()->the_hole_value());
Node* const context = UndefinedConstant();
Node* const effect = graph()->start();
Node* const control = graph()->start();
TRACED_FOREACH(Type*, type, kJSTypes) {
Node* const lhs = Parameter(type);
Reduction r = Reduce(graph()->NewNode(
javascript()->StrictEqual(CompareOperationHints::Any()), lhs, the_hole,
context));
context, effect, control));
ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(), IsFalseConstant());
}
......@@ -405,9 +407,11 @@ TEST_F(JSTypedLoweringTest, JSStrictEqualWithUnique) {
Node* const lhs = Parameter(Type::Unique(), 0);
Node* const rhs = Parameter(Type::Unique(), 1);
Node* const context = Parameter(Type::Any(), 2);
Node* const effect = graph()->start();
Node* const control = graph()->start();
Reduction r = Reduce(
graph()->NewNode(javascript()->StrictEqual(CompareOperationHints::Any()),
lhs, rhs, context));
lhs, rhs, context, effect, control));
ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(), IsReferenceEqual(Type::Unique(), lhs, rhs));
}
......
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