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