blob: 723293dfb86f56ef51e86819397d628976ea304f [file] [log] [blame]
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/compiler/type-narrowing-reducer.h"
#include "src/compiler/js-graph.h"
namespace v8 {
namespace internal {
namespace compiler {
TypeNarrowingReducer::TypeNarrowingReducer(Editor* editor, JSGraph* jsgraph,
JSHeapBroker* broker)
: AdvancedReducer(editor), jsgraph_(jsgraph), op_typer_(broker, zone()) {}
TypeNarrowingReducer::~TypeNarrowingReducer() = default;
Reduction TypeNarrowingReducer::Reduce(Node* node) {
DisallowHeapAccess no_heap_access;
Type new_type = Type::Any();
switch (node->opcode()) {
case IrOpcode::kNumberLessThan: {
// TODO(turbofan) Reuse the logic from typer.cc (by integrating relational
// comparisons with the operation typer).
Type left_type = NodeProperties::GetType(node->InputAt(0));
Type right_type = NodeProperties::GetType(node->InputAt(1));
if (left_type.Is(Type::PlainNumber()) &&
right_type.Is(Type::PlainNumber())) {
if (left_type.Max() < right_type.Min()) {
new_type = op_typer_.singleton_true();
} else if (left_type.Min() >= right_type.Max()) {
new_type = op_typer_.singleton_false();
}
}
break;
}
case IrOpcode::kTypeGuard: {
new_type = op_typer_.TypeTypeGuard(
node->op(), NodeProperties::GetType(node->InputAt(0)));
break;
}
#define DECLARE_CASE(Name) \
case IrOpcode::k##Name: { \
new_type = op_typer_.Name(NodeProperties::GetType(node->InputAt(0)), \
NodeProperties::GetType(node->InputAt(1))); \
break; \
}
SIMPLIFIED_NUMBER_BINOP_LIST(DECLARE_CASE)
DECLARE_CASE(SameValue)
#undef DECLARE_CASE
#define DECLARE_CASE(Name) \
case IrOpcode::k##Name: { \
new_type = op_typer_.Name(NodeProperties::GetType(node->InputAt(0))); \
break; \
}
SIMPLIFIED_NUMBER_UNOP_LIST(DECLARE_CASE)
DECLARE_CASE(ToBoolean)
#undef DECLARE_CASE
default:
return NoChange();
}
Type original_type = NodeProperties::GetType(node);
Type restricted = Type::Intersect(new_type, original_type, zone());
if (!original_type.Is(restricted)) {
NodeProperties::SetType(node, restricted);
return Changed(node);
}
return NoChange();
}
Graph* TypeNarrowingReducer::graph() const { return jsgraph()->graph(); }
Zone* TypeNarrowingReducer::zone() const { return graph()->zone(); }
} // namespace compiler
} // namespace internal
} // namespace v8