• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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