Commit d3797add authored by Mike Stanton's avatar Mike Stanton Committed by Commit Bot

[Turbofan] Introduce StringToNumber opcode

If we have good lower bound type information in simplified lowering
that the input to PlainPrimitiveToNumber is a string, then we'd like
to introduce a call to the StringToNumber builtin. However, this
requires more careful management of the effect chain than we had
previously. To fix this, introduce a StringToNumber opcode which
defers the graph alteration until effect-control-linearization,
when the effect chain is available for careful wiring.

Bug: v8:6929
Change-Id: I4f0e43fe474a44d0dfa095a3a01caece649d82db
Reviewed-on: https://chromium-review.googlesource.com/727934Reviewed-by: 's avatarJaroslav Sevcik <jarin@chromium.org>
Commit-Queue: Michael Stanton <mvstanton@chromium.org>
Cr-Commit-Position: refs/heads/master@{#48741}
parent efe438c5
......@@ -855,6 +855,9 @@ bool EffectControlLinearizer::TryWireInStateEffect(Node* node,
case IrOpcode::kStringIndexOf:
result = LowerStringIndexOf(node);
break;
case IrOpcode::kStringToNumber:
result = LowerStringToNumber(node);
break;
case IrOpcode::kStringCharAt:
result = LowerStringCharAt(node);
break;
......@@ -2479,6 +2482,19 @@ Node* EffectControlLinearizer::LowerArrayBufferWasNeutered(Node* node) {
__ Int32Constant(0));
}
Node* EffectControlLinearizer::LowerStringToNumber(Node* node) {
Node* string = node->InputAt(0);
Callable const callable =
Builtins::CallableFor(isolate(), Builtins::kStringToNumber);
Operator::Properties properties = Operator::kEliminatable;
CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
CallDescriptor* desc = Linkage::GetStubCallDescriptor(
isolate(), graph()->zone(), callable.descriptor(), 0, flags, properties);
return __ Call(desc, __ HeapConstant(callable.code()), string,
__ NoContextConstant());
}
Node* EffectControlLinearizer::LowerStringCharAt(Node* node) {
Node* receiver = node->InputAt(0);
Node* position = node->InputAt(1);
......
......@@ -103,6 +103,7 @@ class V8_EXPORT_PRIVATE EffectControlLinearizer {
Node* LowerNewSmiOrObjectElements(Node* node);
Node* LowerNewArgumentsElements(Node* node);
Node* LowerArrayBufferWasNeutered(Node* node);
Node* LowerStringToNumber(Node* node);
Node* LowerStringCharAt(Node* node);
Node* LowerStringCharCodeAt(Node* node);
Node* LowerSeqStringCharCodeAt(Node* node);
......
......@@ -320,6 +320,7 @@
V(PlainPrimitiveToWord32) \
V(PlainPrimitiveToFloat64) \
V(BooleanNot) \
V(StringToNumber) \
V(StringCharAt) \
V(StringCharCodeAt) \
V(SeqStringCharCodeAt) \
......
......@@ -2645,7 +2645,9 @@ class RepresentationSelector {
if (lower()) DeferReplacement(node, node->InputAt(0));
} else if (InputIs(node, Type::String())) {
VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kTagged);
if (lower()) lowering->DoStringToNumber(node);
if (lower()) {
NodeProperties::ChangeOp(node, simplified()->StringToNumber());
}
} else if (truncation.IsUsedAsWord32()) {
if (InputIs(node, Type::NumberOrOddball())) {
VisitUnop(node, UseInfo::TruncatingWord32(),
......@@ -3645,20 +3647,6 @@ void SimplifiedLowering::DoShift(Node* node, Operator const* op,
ChangeToPureOp(node, op);
}
void SimplifiedLowering::DoStringToNumber(Node* node) {
Operator::Properties properties = Operator::kEliminatable;
Callable callable =
Builtins::CallableFor(isolate(), Builtins::kStringToNumber);
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));
}
void SimplifiedLowering::DoIntegral32ToBit(Node* node) {
Node* const input = node->InputAt(0);
Node* const zero = jsgraph()->Int32Constant(0);
......
......@@ -35,7 +35,6 @@ class SimplifiedLowering final {
void DoJSToNumberTruncatesToWord32(Node* node,
RepresentationSelector* selector);
void DoShift(Node* node, Operator const* op, Type* rhs_type);
void DoStringToNumber(Node* node);
void DoIntegral32ToBit(Node* node);
void DoOrderedNumberToBit(Node* node);
void DoNumberToBit(Node* node);
......
......@@ -549,6 +549,7 @@ DeoptimizeReason DeoptimizeReasonOf(const Operator* op) {
V(NumberToUint32, Operator::kNoProperties, 1, 0) \
V(NumberToUint8Clamped, Operator::kNoProperties, 1, 0) \
V(NumberSilenceNaN, Operator::kNoProperties, 1, 0) \
V(StringToNumber, Operator::kNoProperties, 1, 0) \
V(StringCharAt, Operator::kNoProperties, 2, 1) \
V(StringCharCodeAt, Operator::kNoProperties, 2, 1) \
V(SeqStringCharCodeAt, Operator::kNoProperties, 2, 1) \
......
......@@ -389,6 +389,7 @@ class V8_EXPORT_PRIVATE SimplifiedOperatorBuilder final
const Operator* SpeculativeToNumber(NumberOperationHint hint);
const Operator* StringToNumber();
const Operator* PlainPrimitiveToNumber();
const Operator* PlainPrimitiveToWord32();
const Operator* PlainPrimitiveToFloat64();
......
......@@ -1801,6 +1801,10 @@ Type* Typer::Visitor::TypeSpeculativeNumberLessThanOrEqual(Node* node) {
return TypeBinaryOp(node, NumberLessThanOrEqualTyper);
}
Type* Typer::Visitor::TypeStringToNumber(Node* node) {
return TypeUnaryOp(node, ToNumber);
}
Type* Typer::Visitor::TypePlainPrimitiveToNumber(Node* node) {
return TypeUnaryOp(node, ToNumber);
}
......
......@@ -967,6 +967,11 @@ void Verifier::Visitor::Check(Node* node) {
CheckValueInputIs(node, 1, Type::String());
CheckTypeIs(node, Type::Boolean());
break;
case IrOpcode::kStringToNumber:
// String -> Number
CheckValueInputIs(node, 0, Type::String());
CheckTypeIs(node, Type::Number());
break;
case IrOpcode::kStringCharAt:
// (String, Unsigned32) -> String
CheckValueInputIs(node, 0, Type::String());
......
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