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); 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 RemoveFrameStateInput(Node* node, int index); 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 static Node* FindProjection(Node* node, size_t projection_index); 113 114 // Collect the branch-related projections from a node, such as IfTrue, 115 // IfFalse, IfSuccess, IfException, IfValue and IfDefault. 116 // - Branch: [ IfTrue, IfFalse ] 117 // - Call : [ IfSuccess, IfException ] 118 // - Switch: [ IfValue, ..., IfDefault ] 119 static void CollectControlProjections(Node* node, Node** proj, size_t count); 120 121 // --------------------------------------------------------------------------- 122 // Context. 123 124 // Try to retrieve the specialization context from the given {node}, 125 // optionally utilizing the knowledge about the (outermost) function 126 // {context}. 127 static MaybeHandle<Context> GetSpecializationContext( 128 Node* node, MaybeHandle<Context> context = MaybeHandle<Context>()); 129 130 // Try to retrieve the specialization native context from the given 131 // {node}, optionally utilizing the knowledge about the (outermost) 132 // {native_context}. 133 static MaybeHandle<Context> GetSpecializationNativeContext( 134 Node* node, MaybeHandle<Context> native_context = MaybeHandle<Context>()); 135 136 // Try to retrieve the specialization global object from the given 137 // {node}, optionally utilizing the knowledge about the (outermost) 138 // {native_context}. 139 static MaybeHandle<JSGlobalObject> GetSpecializationGlobalObject( 140 Node* node, MaybeHandle<Context> native_context = MaybeHandle<Context>()); 141 142 // --------------------------------------------------------------------------- 143 // Type. 144 IsTyped(Node * node)145 static bool IsTyped(Node* node) { return node->type() != nullptr; } GetType(Node * node)146 static Type* GetType(Node* node) { 147 DCHECK(IsTyped(node)); 148 return node->type(); 149 } 150 static Type* GetTypeOrAny(Node* node); SetType(Node * node,Type * type)151 static void SetType(Node* node, Type* type) { 152 DCHECK_NOT_NULL(type); 153 node->set_type(type); 154 } RemoveType(Node * node)155 static void RemoveType(Node* node) { node->set_type(nullptr); } 156 static bool AllValueInputsAreTyped(Node* node); 157 158 private: 159 static inline bool IsInputRange(Edge edge, int first, int count); 160 }; 161 162 } // namespace compiler 163 } // namespace internal 164 } // namespace v8 165 166 #endif // V8_COMPILER_NODE_PROPERTIES_H_ 167