[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/727934 Reviewed-by: Jaroslav Sevcik <jarin@chromium.org> Commit-Queue: Michael Stanton <mvstanton@chromium.org> Cr-Commit-Position: refs/heads/master@{#48741}
This commit is contained in:
parent
efe438c5ed
commit
d3797add9e
@ -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());
|
||||
|
Loading…
Reference in New Issue
Block a user