1 // Copyright 2018 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "src/compiler/type-narrowing-reducer.h"
6
7 #include "src/compiler/js-graph.h"
8 #include "src/compiler/js-heap-broker.h"
9
10 namespace v8 {
11 namespace internal {
12 namespace compiler {
13
TypeNarrowingReducer(Editor * editor,JSGraph * jsgraph,JSHeapBroker * broker)14 TypeNarrowingReducer::TypeNarrowingReducer(Editor* editor, JSGraph* jsgraph,
15 JSHeapBroker* broker)
16 : AdvancedReducer(editor),
17 jsgraph_(jsgraph),
18 op_typer_(broker, zone()) {}
19
20 TypeNarrowingReducer::~TypeNarrowingReducer() = default;
21
Reduce(Node * node)22 Reduction TypeNarrowingReducer::Reduce(Node* node) {
23 Type new_type = Type::Any();
24
25 switch (node->opcode()) {
26 case IrOpcode::kNumberLessThan: {
27 // TODO(turbofan) Reuse the logic from typer.cc (by integrating relational
28 // comparisons with the operation typer).
29 Type left_type = NodeProperties::GetType(node->InputAt(0));
30 Type right_type = NodeProperties::GetType(node->InputAt(1));
31 if (left_type.Is(Type::PlainNumber()) &&
32 right_type.Is(Type::PlainNumber())) {
33 if (left_type.Max() < right_type.Min()) {
34 new_type = op_typer_.singleton_true();
35 } else if (left_type.Min() >= right_type.Max()) {
36 new_type = op_typer_.singleton_false();
37 }
38 }
39 break;
40 }
41
42 case IrOpcode::kTypeGuard: {
43 new_type = op_typer_.TypeTypeGuard(
44 node->op(), NodeProperties::GetType(node->InputAt(0)));
45 break;
46 }
47
48 #define DECLARE_CASE(Name) \
49 case IrOpcode::k##Name: { \
50 new_type = op_typer_.Name(NodeProperties::GetType(node->InputAt(0)), \
51 NodeProperties::GetType(node->InputAt(1))); \
52 break; \
53 }
54 SIMPLIFIED_NUMBER_BINOP_LIST(DECLARE_CASE)
55 DECLARE_CASE(SameValue)
56 #undef DECLARE_CASE
57
58 #define DECLARE_CASE(Name) \
59 case IrOpcode::k##Name: { \
60 new_type = op_typer_.Name(NodeProperties::GetType(node->InputAt(0))); \
61 break; \
62 }
63 SIMPLIFIED_NUMBER_UNOP_LIST(DECLARE_CASE)
64 DECLARE_CASE(ToBoolean)
65 #undef DECLARE_CASE
66
67 default:
68 return NoChange();
69 }
70
71 Type original_type = NodeProperties::GetType(node);
72 Type restricted = Type::Intersect(new_type, original_type, zone());
73 if (!original_type.Is(restricted)) {
74 NodeProperties::SetType(node, restricted);
75 return Changed(node);
76 }
77 return NoChange();
78 }
79
graph() const80 Graph* TypeNarrowingReducer::graph() const { return jsgraph()->graph(); }
81
zone() const82 Zone* TypeNarrowingReducer::zone() const { return graph()->zone(); }
83
84 } // namespace compiler
85 } // namespace internal
86 } // namespace v8
87