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