Commit 85969ede authored by bmeurer's avatar bmeurer Committed by Commit bot

[turbofan] Unify BooleanToNumber, StringToNumber and PlainPrimitiveToNumber.

The PlainPrimitiveToNumber operator performs a superset of the operations
previously performed by the BooleanToNumber and StringToNumber operators,
so we can just use the special lowering rules for PlainPrimitiveToNumber
based on the input type and get rid of the specialized operators.

R=jarin@chromium.org

Review-Url: https://codereview.chromium.org/2139183002
Cr-Commit-Position: refs/heads/master@{#37669}
parent e92e9118
......@@ -928,14 +928,6 @@ Reduction JSTypedLowering::ReduceJSToNumberInput(Node* input) {
// JSToNumber(null) => #0
return Replace(jsgraph()->ZeroConstant());
}
if (input_type->Is(Type::Boolean())) {
// JSToNumber(x:boolean) => BooleanToNumber(x)
return Replace(graph()->NewNode(simplified()->BooleanToNumber(), input));
}
if (input_type->Is(Type::String())) {
// JSToNumber(x:string) => StringToNumber(x)
return Replace(graph()->NewNode(simplified()->StringToNumber(), input));
}
return NoChange();
}
......
......@@ -201,7 +201,6 @@
V(PlainPrimitiveToWord32) \
V(PlainPrimitiveToFloat64) \
V(BooleanNot) \
V(BooleanToNumber) \
V(SpeculativeNumberAdd) \
V(SpeculativeNumberSubtract) \
V(SpeculativeNumberMultiply) \
......@@ -256,7 +255,6 @@
V(NumberToUint32) \
V(NumberSilenceNaN) \
V(StringFromCharCode) \
V(StringToNumber) \
V(CheckBounds) \
V(CheckIf) \
V(CheckNumber) \
......
......@@ -1245,24 +1245,6 @@ class RepresentationSelector {
}
return;
}
case IrOpcode::kBooleanToNumber: {
if (lower()) {
NodeInfo* input_info = GetInfo(node->InputAt(0));
if (input_info->representation() == MachineRepresentation::kBit) {
// BooleanToNumber(x: kRepBit) => x
DeferReplacement(node, node->InputAt(0));
} else {
// BooleanToNumber(x: kRepTagged) => WordEqual(x, #true)
node->AppendInput(jsgraph_->zone(), jsgraph_->TrueConstant());
NodeProperties::ChangeOp(node, lowering->machine()->WordEqual());
}
} else {
// No input representation requirement; adapt during lowering.
ProcessInput(node, 0, UseInfo::AnyTruncatingToBool());
SetOutput(node, MachineRepresentation::kWord32);
}
return;
}
case IrOpcode::kNumberEqual:
case IrOpcode::kNumberLessThan:
case IrOpcode::kNumberLessThanOrEqual: {
......@@ -1790,24 +1772,6 @@ class RepresentationSelector {
MachineRepresentation::kTagged);
return;
}
case IrOpcode::kStringToNumber: {
VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kTagged);
if (lower()) {
// StringToNumber(x) => Call(StringToNumber, x, no-context)
Operator::Properties properties = Operator::kEliminatable;
Callable callable = CodeFactory::StringToNumber(jsgraph_->isolate());
CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
CallDescriptor* desc = Linkage::GetStubCallDescriptor(
jsgraph_->isolate(), jsgraph_->zone(), callable.descriptor(), 0,
flags, properties);
node->InsertInput(jsgraph_->zone(), 0,
jsgraph_->HeapConstant(callable.code()));
node->AppendInput(jsgraph_->zone(), jsgraph_->NoContextConstant());
node->AppendInput(jsgraph_->zone(), jsgraph_->graph()->start());
NodeProperties::ChangeOp(node, jsgraph_->common()->Call(desc));
}
return;
}
case IrOpcode::kCheckBounds: {
if (TypeOf(node->InputAt(0))->Is(Type::Unsigned32())) {
......@@ -1995,8 +1959,14 @@ class RepresentationSelector {
}
return;
}
case IrOpcode::kPlainPrimitiveToNumber:
if (truncation.TruncatesToWord32()) {
case IrOpcode::kPlainPrimitiveToNumber: {
if (InputIs(node, Type::Boolean())) {
VisitUnop(node, UseInfo::Bool(), MachineRepresentation::kWord32);
if (lower()) DeferReplacement(node, node->InputAt(0));
} else if (InputIs(node, Type::String())) {
VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kTagged);
if (lower()) lowering->DoStringToNumber(node);
} else if (truncation.TruncatesToWord32()) {
// TODO(jarin): Extend this to Number \/ Oddball
if (InputIs(node, Type::NumberOrUndefined())) {
VisitUnop(node, UseInfo::TruncatingWord32(),
......@@ -2028,6 +1998,7 @@ class RepresentationSelector {
VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kTagged);
}
return;
}
case IrOpcode::kObjectIsCallable:
case IrOpcode::kObjectIsNumber:
case IrOpcode::kObjectIsReceiver:
......@@ -3270,6 +3241,19 @@ void SimplifiedLowering::DoShift(Node* node, Operator const* op,
NodeProperties::ChangeOp(node, op);
}
void SimplifiedLowering::DoStringToNumber(Node* node) {
Operator::Properties properties = Operator::kEliminatable;
Callable callable = CodeFactory::StringToNumber(isolate());
CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
CallDescriptor* desc = Linkage::GetStubCallDescriptor(
isolate(), graph()->zone(), callable.descriptor(), 0, flags, properties);
node->InsertInput(graph()->zone(), 0,
jsgraph()->HeapConstant(callable.code()));
node->AppendInput(graph()->zone(), jsgraph()->NoContextConstant());
node->AppendInput(graph()->zone(), graph()->start());
NodeProperties::ChangeOp(node, common()->Call(desc));
}
Node* SimplifiedLowering::ToNumberCode() {
if (!to_number_code_.is_set()) {
Callable callable = CodeFactory::ToNumber(isolate());
......
......@@ -42,6 +42,7 @@ class SimplifiedLowering final {
RepresentationChanger* changer);
void DoStoreBuffer(Node* node);
void DoShift(Node* node, Operator const* op, Type* rhs_type);
void DoStringToNumber(Node* node);
private:
JSGraph* const jsgraph_;
......
......@@ -230,7 +230,6 @@ CompareOperationHints::Hint CompareOperationHintOf(const Operator* op) {
#define PURE_OP_LIST(V) \
V(BooleanNot, Operator::kNoProperties, 1) \
V(BooleanToNumber, Operator::kNoProperties, 1) \
V(NumberEqual, Operator::kCommutative, 2) \
V(NumberLessThan, Operator::kNoProperties, 2) \
V(NumberLessThanOrEqual, Operator::kNoProperties, 2) \
......@@ -280,7 +279,6 @@ CompareOperationHints::Hint CompareOperationHintOf(const Operator* op) {
V(NumberToUint32, Operator::kNoProperties, 1) \
V(NumberSilenceNaN, Operator::kNoProperties, 1) \
V(StringFromCharCode, Operator::kNoProperties, 1) \
V(StringToNumber, Operator::kNoProperties, 1) \
V(PlainPrimitiveToNumber, Operator::kNoProperties, 1) \
V(PlainPrimitiveToWord32, Operator::kNoProperties, 1) \
V(PlainPrimitiveToFloat64, Operator::kNoProperties, 1) \
......
......@@ -158,7 +158,6 @@ class SimplifiedOperatorBuilder final : public ZoneObject {
explicit SimplifiedOperatorBuilder(Zone* zone);
const Operator* BooleanNot();
const Operator* BooleanToNumber();
const Operator* NumberEqual();
const Operator* NumberLessThan();
......@@ -227,7 +226,6 @@ class SimplifiedOperatorBuilder final : public ZoneObject {
const Operator* StringLessThan();
const Operator* StringLessThanOrEqual();
const Operator* StringFromCharCode();
const Operator* StringToNumber();
const Operator* PlainPrimitiveToNumber();
const Operator* PlainPrimitiveToWord32();
......
......@@ -1551,10 +1551,6 @@ Type* Typer::Visitor::TypeJSStackCheck(Node* node) { return Type::Any(); }
Type* Typer::Visitor::TypeBooleanNot(Node* node) { return Type::Boolean(); }
Type* Typer::Visitor::TypeBooleanToNumber(Node* node) {
return TypeUnaryOp(node, ToNumber);
}
Type* Typer::Visitor::TypeNumberEqual(Node* node) { return Type::Boolean(); }
Type* Typer::Visitor::TypeNumberLessThan(Node* node) { return Type::Boolean(); }
......@@ -1773,10 +1769,6 @@ Type* Typer::Visitor::TypeStringFromCharCode(Node* node) {
return TypeUnaryOp(node, StringFromCharCodeTyper);
}
Type* Typer::Visitor::TypeStringToNumber(Node* node) {
return TypeUnaryOp(node, ToNumber);
}
Type* Typer::Visitor::TypeCheckBounds(Node* node) {
// TODO(bmeurer): We could do better here based on the limit.
return Type::Unsigned31();
......
......@@ -664,11 +664,6 @@ void Verifier::Visitor::Check(Node* node) {
CheckValueInputIs(node, 0, Type::Boolean());
CheckUpperIs(node, Type::Boolean());
break;
case IrOpcode::kBooleanToNumber:
// Boolean -> Number
CheckValueInputIs(node, 0, Type::Boolean());
CheckUpperIs(node, Type::Number());
break;
case IrOpcode::kNumberEqual:
// (Number, Number) -> Boolean
CheckValueInputIs(node, 0, Type::Number());
......@@ -790,13 +785,18 @@ void Verifier::Visitor::Check(Node* node) {
CheckUpperIs(node, Type::Unsigned32());
break;
case IrOpcode::kPlainPrimitiveToNumber:
// Type is Number.
// PlainPrimitive -> Number
CheckValueInputIs(node, 0, Type::PlainPrimitive());
CheckUpperIs(node, Type::Number());
break;
case IrOpcode::kPlainPrimitiveToWord32:
CheckUpperIs(node, Type::Number());
// PlainPrimitive -> Integral32
CheckValueInputIs(node, 0, Type::PlainPrimitive());
CheckUpperIs(node, Type::Integral32());
break;
case IrOpcode::kPlainPrimitiveToFloat64:
// PlainPrimitive -> Number
CheckValueInputIs(node, 0, Type::PlainPrimitive());
CheckUpperIs(node, Type::Number());
break;
case IrOpcode::kStringEqual:
......@@ -812,11 +812,6 @@ void Verifier::Visitor::Check(Node* node) {
CheckValueInputIs(node, 0, Type::Number());
CheckUpperIs(node, Type::String());
break;
case IrOpcode::kStringToNumber:
// String -> Number
CheckValueInputIs(node, 0, Type::String());
CheckUpperIs(node, Type::Number());
break;
case IrOpcode::kReferenceEqual: {
// (Unique, Any) -> Boolean and
// (Any, Unique) -> Boolean
......
......@@ -612,9 +612,6 @@ TEST(StringComparison) {
static void CheckIsConvertedToNumber(Node* val, Node* converted) {
if (NodeProperties::GetType(val)->Is(Type::Number())) {
CHECK_EQ(val, converted);
} else if (NodeProperties::GetType(val)->Is(Type::Boolean())) {
CHECK_EQ(IrOpcode::kBooleanToNumber, converted->opcode());
CHECK_EQ(val, converted->InputAt(0));
} else {
if (converted->opcode() == IrOpcode::kNumberConstant) return;
CHECK_EQ(IrOpcode::kJSToNumber, converted->opcode());
......@@ -1001,7 +998,8 @@ TEST(OrderCompareEffects) {
JSTypedLowering::kNoFlags);
CHECK_EQ(ops[j + 1]->opcode(), B.result->op()->opcode());
Node* i0 = B.CheckConvertedInput(IrOpcode::kStringToNumber, 0, false);
Node* i0 =
B.CheckConvertedInput(IrOpcode::kPlainPrimitiveToNumber, 0, false);
Node* i1 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 1, true);
// Inputs should be commuted.
......
......@@ -899,63 +899,6 @@ TEST(LowerBooleanNot_tagged_tagged) {
CHECK(f == cmp->InputAt(0) || f == cmp->InputAt(1));
}
TEST(LowerBooleanToNumber_bit_int32) {
// BooleanToNumber(x: kRepBit) used as MachineType::Int32()
TestingGraph t(Type::Boolean());
Node* b = t.ExampleWithOutput(MachineType::Bool());
Node* cnv = t.graph()->NewNode(t.simplified()->BooleanToNumber(), b);
Node* use = t.Use(cnv, MachineType::Int32());
t.Return(use);
t.Lower();
CHECK_EQ(b, use->InputAt(0));
}
TEST(LowerBooleanToNumber_tagged_int32) {
// BooleanToNumber(x: kRepTagged) used as MachineType::Int32()
TestingGraph t(Type::Boolean());
Node* b = t.p0;
Node* cnv = t.graph()->NewNode(t.simplified()->BooleanToNumber(), b);
Node* use = t.Use(cnv, MachineType::Int32());
t.Return(use);
t.Lower();
CHECK_EQ(t.machine()->WordEqual()->opcode(), cnv->opcode());
CHECK(b == cnv->InputAt(0) || b == cnv->InputAt(1));
Node* c = t.jsgraph.TrueConstant();
CHECK(c == cnv->InputAt(0) || c == cnv->InputAt(1));
}
TEST(LowerBooleanToNumber_bit_tagged) {
// BooleanToNumber(x: kRepBit) used as MachineType::AnyTagged()
TestingGraph t(Type::Boolean());
Node* b = t.ExampleWithOutput(MachineType::Bool());
Node* cnv = t.graph()->NewNode(t.simplified()->BooleanToNumber(), b);
Node* use = t.Use(cnv, MachineType::AnyTagged());
t.Return(use);
t.Lower();
CHECK_EQ(b, use->InputAt(0)->InputAt(0));
CHECK_EQ(IrOpcode::kChangeInt31ToTaggedSigned, use->InputAt(0)->opcode());
}
TEST(LowerBooleanToNumber_tagged_tagged) {
// BooleanToNumber(x: kRepTagged) used as MachineType::AnyTagged()
TestingGraph t(Type::Boolean());
Node* b = t.p0;
Node* cnv = t.graph()->NewNode(t.simplified()->BooleanToNumber(), b);
Node* use = t.Use(cnv, MachineType::AnyTagged());
t.Return(use);
t.Lower();
CHECK_EQ(cnv, use->InputAt(0)->InputAt(0));
CHECK_EQ(IrOpcode::kChangeInt31ToTaggedSigned, use->InputAt(0)->opcode());
CHECK_EQ(t.machine()->WordEqual()->opcode(), cnv->opcode());
CHECK(b == cnv->InputAt(0) || b == cnv->InputAt(1));
Node* c = t.jsgraph.TrueConstant();
CHECK(c == cnv->InputAt(0) || c == cnv->InputAt(1));
}
static Type* test_types[] = {Type::Signed32(), Type::Unsigned32(),
Type::Number()};
......
......@@ -38,7 +38,6 @@ const PureOperator kPureOperators[] = {
Operator::kPure | properties, input_count \
}
PURE(BooleanNot, Operator::kNoProperties, 1),
PURE(BooleanToNumber, Operator::kNoProperties, 1),
PURE(NumberEqual, Operator::kCommutative, 2),
PURE(NumberLessThan, Operator::kNoProperties, 2),
PURE(NumberLessThanOrEqual, Operator::kNoProperties, 2),
......
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