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 18namespace v8 { 19namespace internal { 20namespace compiler { 21 22// ----------------------------------------------------------------------------- 23// Input layout. 24// Inputs are always arranged in order as follows: 25// 0 [ values, context, effects, control ] node->InputCount() 26 27inline int NodeProperties::FirstValueIndex(Node* node) { return 0; } 28 29inline int NodeProperties::FirstContextIndex(Node* node) { 30 return PastValueIndex(node); 31} 32 33inline int NodeProperties::FirstFrameStateIndex(Node* node) { 34 return PastContextIndex(node); 35} 36 37inline int NodeProperties::FirstEffectIndex(Node* node) { 38 return PastFrameStateIndex(node); 39} 40 41inline int NodeProperties::FirstControlIndex(Node* node) { 42 return PastEffectIndex(node); 43} 44 45 46inline int NodeProperties::PastValueIndex(Node* node) { 47 return FirstValueIndex(node) + 48 OperatorProperties::GetValueInputCount(node->op()); 49} 50 51inline int NodeProperties::PastContextIndex(Node* node) { 52 return FirstContextIndex(node) + 53 OperatorProperties::GetContextInputCount(node->op()); 54} 55 56inline int NodeProperties::PastFrameStateIndex(Node* node) { 57 return FirstFrameStateIndex(node) + 58 OperatorProperties::GetFrameStateInputCount(node->op()); 59} 60 61inline int NodeProperties::PastEffectIndex(Node* node) { 62 return FirstEffectIndex(node) + 63 OperatorProperties::GetEffectInputCount(node->op()); 64} 65 66inline int NodeProperties::PastControlIndex(Node* node) { 67 return FirstControlIndex(node) + 68 OperatorProperties::GetControlInputCount(node->op()); 69} 70 71 72// ----------------------------------------------------------------------------- 73// Input accessors. 74 75inline 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 81inline Node* NodeProperties::GetContextInput(Node* node) { 82 DCHECK(OperatorProperties::HasContextInput(node->op())); 83 return node->InputAt(FirstContextIndex(node)); 84} 85 86inline Node* NodeProperties::GetFrameStateInput(Node* node) { 87 DCHECK(OperatorProperties::HasFrameStateInput(node->op())); 88 return node->InputAt(FirstFrameStateIndex(node)); 89} 90 91inline 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 97inline 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 103inline int NodeProperties::GetFrameStateIndex(Node* node) { 104 DCHECK(OperatorProperties::HasFrameStateInput(node->op())); 105 return FirstFrameStateIndex(node); 106} 107 108// ----------------------------------------------------------------------------- 109// Edge kinds. 110 111inline 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 119inline bool NodeProperties::IsValueEdge(Node::Edge edge) { 120 Node* node = edge.from(); 121 return IsInputRange(edge, FirstValueIndex(node), 122 OperatorProperties::GetValueInputCount(node->op())); 123} 124 125inline bool NodeProperties::IsContextEdge(Node::Edge edge) { 126 Node* node = edge.from(); 127 return IsInputRange(edge, FirstContextIndex(node), 128 OperatorProperties::GetContextInputCount(node->op())); 129} 130 131inline bool NodeProperties::IsEffectEdge(Node::Edge edge) { 132 Node* node = edge.from(); 133 return IsInputRange(edge, FirstEffectIndex(node), 134 OperatorProperties::GetEffectInputCount(node->op())); 135} 136 137inline 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 147inline bool NodeProperties::IsControl(Node* node) { 148 return IrOpcode::IsControlOpcode(node->opcode()); 149} 150 151 152// ----------------------------------------------------------------------------- 153// Miscellaneous mutators. 154 155inline void NodeProperties::ReplaceControlInput(Node* node, Node* control) { 156 node->ReplaceInput(FirstControlIndex(node), control); 157} 158 159inline 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 165inline void NodeProperties::ReplaceFrameStateInput(Node* node, 166 Node* frame_state) { 167 DCHECK(OperatorProperties::HasFrameStateInput(node->op())); 168 node->ReplaceInput(FirstFrameStateIndex(node), frame_state); 169} 170 171inline 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}. 178inline 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 201inline Bounds NodeProperties::GetBounds(Node* node) { return node->bounds(); } 202 203inline 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