Commit 2fdf33bb authored by bmeurer's avatar bmeurer Committed by Commit bot

[turbofan] Introduce dedicated NumberConvertHoleNaN simplified operator.

This is part of the fixes required to make type feedback viable for
TurboFan on Octane.

R=jarin@chromium.org

Review-Url: https://codereview.chromium.org/2065953002
Cr-Commit-Position: refs/heads/master@{#36966}
parent d9e8764f
......@@ -790,9 +790,6 @@ Reduction JSNativeContextSpecialization::ReduceElementAccess(
this_value = graph()->NewNode(simplified()->TypeGuard(element_type),
this_value, this_control);
} else if (elements_kind == FAST_HOLEY_DOUBLE_ELEMENTS) {
// Perform the hole check on the result.
Node* check =
graph()->NewNode(simplified()->NumberIsHoleNaN(), this_value);
// Check if we are allowed to return the hole directly.
Type* initial_holey_array_type = Type::Class(
handle(isolate()->get_initial_js_array_map(elements_kind)),
......@@ -804,11 +801,12 @@ Reduction JSNativeContextSpecialization::ReduceElementAccess(
isolate()->initial_object_prototype());
dependencies()->AssumePropertyCell(factory()->array_protector());
// Turn the hole into undefined.
this_value = graph()->NewNode(
common()->Select(MachineRepresentation::kTagged,
BranchHint::kFalse),
check, jsgraph()->UndefinedConstant(), this_value);
this_value = graph()->NewNode(simplified()->NumberConvertHoleNaN(),
this_value);
} else {
// Perform the hole check on the result.
Node* check =
graph()->NewNode(simplified()->NumberIsHoleNaN(), this_value);
// Deoptimize in case of the hole.
this_control = this_effect =
graph()->NewNode(common()->DeoptimizeIf(), check, frame_state,
......
......@@ -805,21 +805,6 @@ Reduction JSTypedLowering::ReduceJSToLength(Node* node) {
}
Reduction JSTypedLowering::ReduceJSToNumberInput(Node* input) {
// Check for ToNumber truncation of signaling NaN to undefined mapping.
if (input->opcode() == IrOpcode::kSelect) {
Node* check = NodeProperties::GetValueInput(input, 0);
Node* vtrue = NodeProperties::GetValueInput(input, 1);
Type* vtrue_type = NodeProperties::GetType(vtrue);
Node* vfalse = NodeProperties::GetValueInput(input, 2);
Type* vfalse_type = NodeProperties::GetType(vfalse);
if (vtrue_type->Is(Type::Undefined()) && vfalse_type->Is(Type::Number())) {
if (check->opcode() == IrOpcode::kNumberIsHoleNaN &&
check->InputAt(0) == vfalse) {
// JSToNumber(Select(NumberIsHoleNaN(x), y:undefined, x:number)) => x
return Replace(vfalse);
}
}
}
// Try constant-folding of JSToNumber with constant inputs.
Type* input_type = NodeProperties::GetType(input);
if (input_type->IsConstant()) {
......
......@@ -207,6 +207,7 @@
V(NumberToUint32) \
V(NumberIsHoleNaN) \
V(NumberSilenceNaN) \
V(NumberConvertHoleNaN) \
V(StringFromCharCode) \
V(StringToNumber) \
V(ChangeTaggedSignedToInt32) \
......
......@@ -1449,6 +1449,41 @@ class RepresentationSelector {
}
return;
}
case IrOpcode::kNumberConvertHoleNaN: {
if (truncation.TruncatesToFloat64()) {
// NumberConvertHoleNaN(x) => x
VisitUnop(node, UseInfo::TruncatingFloat64(),
MachineRepresentation::kFloat64);
if (lower()) DeferReplacement(node, node->InputAt(0));
} else {
VisitUnop(node, UseInfo::TruncatingFloat64(),
MachineRepresentation::kTagged);
if (lower()) {
// NumberConvertHoleNaN(x) =>
// Select(Word32Equal(Float64ExtractHighWord32(x),
// #HoleNanUpper32),
// #Undefined,
// ChangeFloat64ToTagged(x))
Node* value = node->InputAt(0);
node->ReplaceInput(
0,
jsgraph_->graph()->NewNode(
jsgraph_->machine()->Word32Equal(),
jsgraph_->graph()->NewNode(
jsgraph_->machine()->Float64ExtractHighWord32(), value),
jsgraph_->Int32Constant(kHoleNanUpper32)));
node->AppendInput(jsgraph_->zone(), jsgraph_->UndefinedConstant());
node->AppendInput(
jsgraph_->zone(),
jsgraph_->graph()->NewNode(
jsgraph_->simplified()->ChangeFloat64ToTagged(), value));
NodeProperties::ChangeOp(
node, jsgraph_->common()->Select(MachineRepresentation::kTagged,
BranchHint::kFalse));
}
}
return;
}
case IrOpcode::kReferenceEqual: {
VisitBinop(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
if (lower()) {
......
......@@ -214,6 +214,7 @@ BinaryOperationHints::Hint BinaryOperationHintOf(const Operator* op) {
V(NumberToUint32, Operator::kNoProperties, 1) \
V(NumberIsHoleNaN, Operator::kNoProperties, 1) \
V(NumberSilenceNaN, Operator::kNoProperties, 1) \
V(NumberConvertHoleNaN, Operator::kNoProperties, 1) \
V(StringFromCharCode, Operator::kNoProperties, 1) \
V(StringToNumber, Operator::kNoProperties, 1) \
V(PlainPrimitiveToNumber, Operator::kNoWrite, 1) \
......
......@@ -163,6 +163,7 @@ class SimplifiedOperatorBuilder final : public ZoneObject {
const Operator* NumberToInt32();
const Operator* NumberToUint32();
const Operator* NumberIsHoleNaN();
const Operator* NumberConvertHoleNaN();
const Operator* NumberSilenceNaN();
......
......@@ -248,6 +248,7 @@ class Typer::Visitor : public Reducer {
static Type* NumberTrunc(Type*, Typer*);
static Type* NumberToInt32(Type*, Typer*);
static Type* NumberToUint32(Type*, Typer*);
static Type* NumberConvertHoleNaN(Type*, Typer*);
static Type* ObjectIsCallable(Type*, Typer*);
static Type* ObjectIsNumber(Type*, Typer*);
......@@ -556,6 +557,10 @@ Type* Typer::Visitor::NumberToUint32(Type* type, Typer* t) {
return Type::Unsigned32();
}
Type* Typer::Visitor::NumberConvertHoleNaN(Type* type, Typer* t) {
return Type::Union(type, Type::Undefined(), t->zone());
}
// Type checks.
Type* Typer::Visitor::ObjectIsCallable(Type* type, Typer* t) {
......@@ -1813,6 +1818,10 @@ Type* Typer::Visitor::TypeNumberIsHoleNaN(Node* node) {
return Type::Boolean();
}
Type* Typer::Visitor::TypeNumberConvertHoleNaN(Node* node) {
return TypeUnaryOp(node, NumberConvertHoleNaN);
}
// static
Type* Typer::Visitor::ReferenceEqualTyper(Type* lhs, Type* rhs, Typer* t) {
if (lhs->IsConstant() && rhs->Is(lhs)) {
......
......@@ -770,6 +770,11 @@ void Verifier::Visitor::Check(Node* node) {
CheckValueInputIs(node, 0, Type::Number());
CheckUpperIs(node, Type::Boolean());
break;
case IrOpcode::kNumberConvertHoleNaN:
// Number -> Number \/ Undefined
CheckValueInputIs(node, 0, Type::Number());
CheckUpperIs(node, Type::NumberOrUndefined());
break;
case IrOpcode::kPlainPrimitiveToNumber:
// Type is Number.
CheckUpperIs(node, Type::Number());
......
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