Commit cacb44a9 authored by mvstanton's avatar mvstanton Committed by Commit bot

[turbofan] Optimize typeof operator without storing strings in Type

We'll take expressions like typeof 'hello' and reduce it to 'string'.
Neat! This CL moves the optimization to an explicit reduction
in typed lowering that inserts a constant string, instead of
relying on type matching.

BUG=

Review-Url: https://codereview.chromium.org/2411703002
Cr-Commit-Position: refs/heads/master@{#40175}
parent 33ca1f51
......@@ -756,6 +756,35 @@ Reduction JSTypedLowering::ReduceJSComparison(Node* node) {
}
}
Reduction JSTypedLowering::ReduceJSTypeOf(Node* node) {
Node* const input = node->InputAt(0);
Type* type = NodeProperties::GetType(input);
Factory* const f = factory();
if (type->Is(Type::Boolean())) {
return Replace(jsgraph()->Constant(f->boolean_string()));
} else if (type->Is(Type::Number())) {
return Replace(jsgraph()->Constant(f->number_string()));
} else if (type->Is(Type::String())) {
return Replace(jsgraph()->Constant(f->string_string()));
} else if (type->Is(Type::Symbol())) {
return Replace(jsgraph()->Constant(f->symbol_string()));
} else if (type->Is(Type::Union(Type::Undefined(), Type::OtherUndetectable(),
graph()->zone()))) {
return Replace(jsgraph()->Constant(f->undefined_string()));
} else if (type->Is(Type::Null())) {
return Replace(jsgraph()->Constant(f->object_string()));
} else if (type->Is(Type::Function())) {
return Replace(jsgraph()->Constant(f->function_string()));
} else if (type->IsHeapConstant()) {
return Replace(jsgraph()->Constant(
Object::TypeOf(isolate(), type->AsHeapConstant()->Value())));
} else if (type->IsOtherNumberConstant()) {
return Replace(jsgraph()->Constant(f->number_string()));
}
return NoChange();
}
Reduction JSTypedLowering::ReduceJSEqualTypeOf(Node* node, bool invert) {
HeapObjectBinopMatcher m(node);
if (m.left().IsJSTypeOf() && m.right().HasValue() &&
......@@ -2085,6 +2114,8 @@ Reduction JSTypedLowering::Reduce(Node* node) {
return ReduceJSToString(node);
case IrOpcode::kJSToObject:
return ReduceJSToObject(node);
case IrOpcode::kJSTypeOf:
return ReduceJSTypeOf(node);
case IrOpcode::kJSLoadNamed:
return ReduceJSLoadNamed(node);
case IrOpcode::kJSLoadProperty:
......
......@@ -70,6 +70,7 @@ class JSTypedLowering final : public AdvancedReducer {
Reduction ReduceJSGeneratorStore(Node* node);
Reduction ReduceJSGeneratorRestoreContinuation(Node* node);
Reduction ReduceJSGeneratorRestoreRegister(Node* node);
Reduction ReduceJSTypeOf(Node* node);
Reduction ReduceNumberBinop(Node* node);
Reduction ReduceInt32Binop(Node* node);
Reduction ReduceUI32Shift(Node* node, Signedness signedness);
......
......@@ -290,7 +290,6 @@ class Typer::Visitor : public Reducer {
JS_SIMPLE_BINOP_LIST(DECLARE_METHOD)
#undef DECLARE_METHOD
static Type* JSTypeOfTyper(Type*, Typer*);
static Type* JSCallFunctionTyper(Type*, Typer*);
static Type* ReferenceEqualTyper(Type*, Type*, Typer*);
......@@ -1013,36 +1012,8 @@ Type* Typer::Visitor::JSModulusTyper(Type* lhs, Type* rhs, Typer* t) {
// JS unary operators.
Type* Typer::Visitor::JSTypeOfTyper(Type* type, Typer* t) {
Factory* const f = t->isolate()->factory();
if (type->Is(Type::Boolean())) {
return Type::HeapConstant(f->boolean_string(), t->zone());
} else if (type->Is(Type::Number())) {
return Type::HeapConstant(f->number_string(), t->zone());
} else if (type->Is(Type::String())) {
return Type::HeapConstant(f->string_string(), t->zone());
} else if (type->Is(Type::Symbol())) {
return Type::HeapConstant(f->symbol_string(), t->zone());
} else if (type->Is(Type::Union(Type::Undefined(), Type::OtherUndetectable(),
t->zone()))) {
return Type::HeapConstant(f->undefined_string(), t->zone());
} else if (type->Is(Type::Null())) {
return Type::HeapConstant(f->object_string(), t->zone());
} else if (type->Is(Type::Function())) {
return Type::HeapConstant(f->function_string(), t->zone());
} else if (type->IsHeapConstant()) {
return Type::HeapConstant(
Object::TypeOf(t->isolate(), type->AsHeapConstant()->Value()),
t->zone());
} else if (type->IsOtherNumberConstant()) {
return Type::HeapConstant(f->number_string(), t->zone());
}
return Type::InternalizedString();
}
Type* Typer::Visitor::TypeJSTypeOf(Node* node) {
return TypeUnaryOp(node, JSTypeOfTyper);
return Type::InternalizedString();
}
......
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