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_INL_H_ 6 #define V8_COMPILER_NODE_PROPERTIES_INL_H_ 7 8 #include "src/v8.h" 9 10 #include "src/compiler/common-operator.h" 11 #include "src/compiler/generic-node-inl.h" 12 #include "src/compiler/node-properties.h" 13 #include "src/compiler/opcodes.h" 14 #include "src/compiler/operator.h" 15 #include "src/compiler/operator-properties-inl.h" 16 #include "src/compiler/operator-properties.h" 17 18 namespace v8 { 19 namespace internal { 20 namespace compiler { 21 22 // ----------------------------------------------------------------------------- 23 // Input layout. 24 // Inputs are always arranged in order as follows: 25 // 0 [ values, context, effects, control ] node->InputCount() 26 27 inline int NodeProperties::FirstValueIndex(Node* node) { return 0; } 28 29 inline int NodeProperties::FirstContextIndex(Node* node) { 30 return PastValueIndex(node); 31 } 32 33 inline int NodeProperties::FirstFrameStateIndex(Node* node) { 34 return PastContextIndex(node); 35 } 36 37 inline int NodeProperties::FirstEffectIndex(Node* node) { 38 return PastFrameStateIndex(node); 39 } 40 41 inline int NodeProperties::FirstControlIndex(Node* node) { 42 return PastEffectIndex(node); 43 } 44 45 46 inline int NodeProperties::PastValueIndex(Node* node) { 47 return FirstValueIndex(node) + 48 OperatorProperties::GetValueInputCount(node->op()); 49 } 50 51 inline int NodeProperties::PastContextIndex(Node* node) { 52 return FirstContextIndex(node) + 53 OperatorProperties::GetContextInputCount(node->op()); 54 } 55 56 inline int NodeProperties::PastFrameStateIndex(Node* node) { 57 return FirstFrameStateIndex(node) + 58 OperatorProperties::GetFrameStateInputCount(node->op()); 59 } 60 61 inline int NodeProperties::PastEffectIndex(Node* node) { 62 return FirstEffectIndex(node) + 63 OperatorProperties::GetEffectInputCount(node->op()); 64 } 65 66 inline int NodeProperties::PastControlIndex(Node* node) { 67 return FirstControlIndex(node) + 68 OperatorProperties::GetControlInputCount(node->op()); 69 } 70 71 72 // ----------------------------------------------------------------------------- 73 // Input accessors. 74 75 inline Node* NodeProperties::GetValueInput(Node* node, int index) { 76 DCHECK(0 <= index && 77 index < OperatorProperties::GetValueInputCount(node->op())); 78 return node->InputAt(FirstValueIndex(node) + index); 79 } 80 81 inline Node* NodeProperties::GetContextInput(Node* node) { 82 DCHECK(OperatorProperties::HasContextInput(node->op())); 83 return node->InputAt(FirstContextIndex(node)); 84 } 85 86 inline Node* NodeProperties::GetFrameStateInput(Node* node) { 87 DCHECK(OperatorProperties::HasFrameStateInput(node->op())); 88 return node->InputAt(FirstFrameStateIndex(node)); 89 } 90 91 inline Node* NodeProperties::GetEffectInput(Node* node, int index) { 92 DCHECK(0 <= index && 93 index < OperatorProperties::GetEffectInputCount(node->op())); 94 return node->InputAt(FirstEffectIndex(node) + index); 95 } 96 97 inline Node* NodeProperties::GetControlInput(Node* node, int index) { 98 DCHECK(0 <= index && 99 index < OperatorProperties::GetControlInputCount(node->op())); 100 return node->InputAt(FirstControlIndex(node) + index); 101 } 102 103 inline int NodeProperties::GetFrameStateIndex(Node* node) { 104 DCHECK(OperatorProperties::HasFrameStateInput(node->op())); 105 return FirstFrameStateIndex(node); 106 } 107 108 // ----------------------------------------------------------------------------- 109 // Edge kinds. 110 111 inline bool NodeProperties::IsInputRange(Node::Edge edge, int first, int num) { 112 // TODO(titzer): edge.index() is linear time; 113 // edges maybe need to be marked as value/effect/control. 114 if (num == 0) return false; 115 int index = edge.index(); 116 return first <= index && index < first + num; 117 } 118 119 inline bool NodeProperties::IsValueEdge(Node::Edge edge) { 120 Node* node = edge.from(); 121 return IsInputRange(edge, FirstValueIndex(node), 122 OperatorProperties::GetValueInputCount(node->op())); 123 } 124 125 inline bool NodeProperties::IsContextEdge(Node::Edge edge) { 126 Node* node = edge.from(); 127 return IsInputRange(edge, FirstContextIndex(node), 128 OperatorProperties::GetContextInputCount(node->op())); 129 } 130 131 inline bool NodeProperties::IsEffectEdge(Node::Edge edge) { 132 Node* node = edge.from(); 133 return IsInputRange(edge, FirstEffectIndex(node), 134 OperatorProperties::GetEffectInputCount(node->op())); 135 } 136 137 inline bool NodeProperties::IsControlEdge(Node::Edge edge) { 138 Node* node = edge.from(); 139 return IsInputRange(edge, FirstControlIndex(node), 140 OperatorProperties::GetControlInputCount(node->op())); 141 } 142 143 144 // ----------------------------------------------------------------------------- 145 // Miscellaneous predicates. 146 147 inline bool NodeProperties::IsControl(Node* node) { 148 return IrOpcode::IsControlOpcode(node->opcode()); 149 } 150 151 152 // ----------------------------------------------------------------------------- 153 // Miscellaneous mutators. 154 155 inline void NodeProperties::ReplaceControlInput(Node* node, Node* control) { 156 node->ReplaceInput(FirstControlIndex(node), control); 157 } 158 159 inline void NodeProperties::ReplaceEffectInput(Node* node, Node* effect, 160 int index) { 161 DCHECK(index < OperatorProperties::GetEffectInputCount(node->op())); 162 return node->ReplaceInput(FirstEffectIndex(node) + index, effect); 163 } 164 165 inline void NodeProperties::ReplaceFrameStateInput(Node* node, 166 Node* frame_state) { 167 DCHECK(OperatorProperties::HasFrameStateInput(node->op())); 168 node->ReplaceInput(FirstFrameStateIndex(node), frame_state); 169 } 170 171 inline void NodeProperties::RemoveNonValueInputs(Node* node) { 172 node->TrimInputCount(OperatorProperties::GetValueInputCount(node->op())); 173 } 174 175 176 // Replace value uses of {node} with {value} and effect uses of {node} with 177 // {effect}. If {effect == NULL}, then use the effect input to {node}. 178 inline void NodeProperties::ReplaceWithValue(Node* node, Node* value, 179 Node* effect) { 180 DCHECK(!OperatorProperties::HasControlOutput(node->op())); 181 if (effect == NULL && OperatorProperties::HasEffectInput(node->op())) { 182 effect = NodeProperties::GetEffectInput(node); 183 } 184 185 // Requires distinguishing between value and effect edges. 186 UseIter iter = node->uses().begin(); 187 while (iter != node->uses().end()) { 188 if (NodeProperties::IsEffectEdge(iter.edge())) { 189 DCHECK_NE(NULL, effect); 190 iter = iter.UpdateToAndIncrement(effect); 191 } else { 192 iter = iter.UpdateToAndIncrement(value); 193 } 194 } 195 } 196 197 198 // ----------------------------------------------------------------------------- 199 // Type Bounds. 200 201 inline Bounds NodeProperties::GetBounds(Node* node) { return node->bounds(); } 202 203 inline void NodeProperties::SetBounds(Node* node, Bounds b) { 204 node->set_bounds(b); 205 } 206 207 208 } 209 } 210 } // namespace v8::internal::compiler 211 212 #endif // V8_COMPILER_NODE_PROPERTIES_INL_H_ 213