1// Copyright 2013 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#ifndef V8_COMPILER_NODE_PROPERTIES_H_
6#define V8_COMPILER_NODE_PROPERTIES_H_
7
8#include "src/compiler/node.h"
9#include "src/compiler/types.h"
10#include "src/globals.h"
11#include "src/zone/zone-handle-set.h"
12
13namespace v8 {
14namespace internal {
15namespace compiler {
16
17class Graph;
18class Operator;
19class CommonOperatorBuilder;
20
21// A facade that simplifies access to the different kinds of inputs to a node.
22class V8_EXPORT_PRIVATE NodeProperties final {
23 public:
24  // ---------------------------------------------------------------------------
25  // Input layout.
26  // Inputs are always arranged in order as follows:
27  //     0 [ values, context, frame state, effects, control ] node->InputCount()
28
29  static int FirstValueIndex(Node* node) { return 0; }
30  static int FirstContextIndex(Node* node) { return PastValueIndex(node); }
31  static int FirstFrameStateIndex(Node* node) { return PastContextIndex(node); }
32  static int FirstEffectIndex(Node* node) { return PastFrameStateIndex(node); }
33  static int FirstControlIndex(Node* node) { return PastEffectIndex(node); }
34  static int PastValueIndex(Node* node);
35  static int PastContextIndex(Node* node);
36  static int PastFrameStateIndex(Node* node);
37  static int PastEffectIndex(Node* node);
38  static int PastControlIndex(Node* node);
39
40
41  // ---------------------------------------------------------------------------
42  // Input accessors.
43
44  static Node* GetValueInput(Node* node, int index);
45  static Node* GetContextInput(Node* node);
46  static Node* GetFrameStateInput(Node* node);
47  static Node* GetEffectInput(Node* node, int index = 0);
48  static Node* GetControlInput(Node* node, int index = 0);
49
50
51  // ---------------------------------------------------------------------------
52  // Edge kinds.
53
54  static bool IsValueEdge(Edge edge);
55  static bool IsContextEdge(Edge edge);
56  static bool IsFrameStateEdge(Edge edge);
57  static bool IsEffectEdge(Edge edge);
58  static bool IsControlEdge(Edge edge);
59
60
61  // ---------------------------------------------------------------------------
62  // Miscellaneous predicates.
63
64  static bool IsCommon(Node* node) {
65    return IrOpcode::IsCommonOpcode(node->opcode());
66  }
67  static bool IsControl(Node* node) {
68    return IrOpcode::IsControlOpcode(node->opcode());
69  }
70  static bool IsConstant(Node* node) {
71    return IrOpcode::IsConstantOpcode(node->opcode());
72  }
73  static bool IsPhi(Node* node) {
74    return IrOpcode::IsPhiOpcode(node->opcode());
75  }
76
77  // Determines whether exceptions thrown by the given node are handled locally
78  // within the graph (i.e. an IfException projection is present).
79  static bool IsExceptionalCall(Node* node);
80
81  // ---------------------------------------------------------------------------
82  // Miscellaneous mutators.
83
84  static void ReplaceValueInput(Node* node, Node* value, int index);
85  static void ReplaceContextInput(Node* node, Node* context);
86  static void ReplaceControlInput(Node* node, Node* control, int index = 0);
87  static void ReplaceEffectInput(Node* node, Node* effect, int index = 0);
88  static void ReplaceFrameStateInput(Node* node, Node* frame_state);
89  static void RemoveNonValueInputs(Node* node);
90  static void RemoveValueInputs(Node* node);
91
92  // Replaces all value inputs of {node} with the single input {value}.
93  static void ReplaceValueInputs(Node* node, Node* value);
94
95  // Merge the control node {node} into the end of the graph, introducing a
96  // merge node or expanding an existing merge node if necessary.
97  static void MergeControlToEnd(Graph* graph, CommonOperatorBuilder* common,
98                                Node* node);
99
100  // Replace all uses of {node} with the given replacement nodes. All occurring
101  // use kinds need to be replaced, {nullptr} is only valid if a use kind is
102  // guaranteed not to exist.
103  static void ReplaceUses(Node* node, Node* value, Node* effect = nullptr,
104                          Node* success = nullptr, Node* exception = nullptr);
105
106  // Safe wrapper to mutate the operator of a node. Checks that the node is
107  // currently in a state that satisfies constraints of the new operator.
108  static void ChangeOp(Node* node, const Operator* new_op);
109
110  // ---------------------------------------------------------------------------
111  // Miscellaneous utilities.
112
113  // Find the last frame state that is effect-wise before the given node. This
114  // assumes a linear effect-chain up to a {CheckPoint} node in the graph.
115  static Node* FindFrameStateBefore(Node* node);
116
117  // Collect the output-value projection for the given output index.
118  static Node* FindProjection(Node* node, size_t projection_index);
119
120  // Collect the branch-related projections from a node, such as IfTrue,
121  // IfFalse, IfSuccess, IfException, IfValue and IfDefault.
122  //  - Branch: [ IfTrue, IfFalse ]
123  //  - Call  : [ IfSuccess, IfException ]
124  //  - Switch: [ IfValue, ..., IfDefault ]
125  static void CollectControlProjections(Node* node, Node** proj, size_t count);
126
127  // Checks if two nodes are the same, looking past {CheckHeapObject}.
128  static bool IsSame(Node* a, Node* b);
129
130  // Walks up the {effect} chain to find a witness that provides map
131  // information about the {receiver}. Can look through potentially
132  // side effecting nodes.
133  enum InferReceiverMapsResult {
134    kNoReceiverMaps,         // No receiver maps inferred.
135    kReliableReceiverMaps,   // Receiver maps can be trusted.
136    kUnreliableReceiverMaps  // Receiver maps might have changed (side-effect).
137  };
138  static InferReceiverMapsResult InferReceiverMaps(
139      Node* receiver, Node* effect, ZoneHandleSet<Map>* maps_return);
140
141  // ---------------------------------------------------------------------------
142  // Context.
143
144  // Try to retrieve the specialization context from the given {node},
145  // optionally utilizing the knowledge about the (outermost) function
146  // {context}.
147  static MaybeHandle<Context> GetSpecializationContext(
148      Node* node, MaybeHandle<Context> context = MaybeHandle<Context>());
149
150  // Walk up the context chain from the given {node} until we reduce the {depth}
151  // to 0 or hit a node that does not extend the context chain ({depth} will be
152  // updated accordingly).
153  static Node* GetOuterContext(Node* node, size_t* depth);
154
155  // ---------------------------------------------------------------------------
156  // Type.
157
158  static bool IsTyped(Node* node) { return node->type() != nullptr; }
159  static Type* GetType(Node* node) {
160    DCHECK(IsTyped(node));
161    return node->type();
162  }
163  static Type* GetTypeOrAny(Node* node);
164  static void SetType(Node* node, Type* type) {
165    DCHECK_NOT_NULL(type);
166    node->set_type(type);
167  }
168  static void RemoveType(Node* node) { node->set_type(nullptr); }
169  static bool AllValueInputsAreTyped(Node* node);
170
171 private:
172  static inline bool IsInputRange(Edge edge, int first, int count);
173};
174
175}  // namespace compiler
176}  // namespace internal
177}  // namespace v8
178
179#endif  // V8_COMPILER_NODE_PROPERTIES_H_
180