if (has_effect) {
environment_->UpdateEffectDependency(result);
}
- if (NodeProperties::HasControlOutput(result) &&
+ if (OperatorProperties::HasControlOutput(result->op()) &&
!environment_internal()->IsMarkedAsUnreachable()) {
UpdateControlDependency(result);
}
Node* StructuredGraphBuilder::MergeControl(Node* control, Node* other) {
- int inputs = NodeProperties::GetControlInputCount(control) + 1;
+ int inputs = OperatorProperties::GetControlInputCount(control->op()) + 1;
if (control->opcode() == IrOpcode::kLoop) {
// Control node for loop exists, add input.
Operator* op = common()->Loop(inputs);
Node* StructuredGraphBuilder::MergeEffect(Node* value, Node* other,
Node* control) {
- int inputs = NodeProperties::GetControlInputCount(control);
+ int inputs = OperatorProperties::GetControlInputCount(control->op());
if (value->opcode() == IrOpcode::kEffectPhi &&
NodeProperties::GetControlInput(value) == control) {
// Phi already exists, add input.
Node* StructuredGraphBuilder::MergeValue(Node* value, Node* other,
Node* control) {
- int inputs = NodeProperties::GetControlInputCount(control);
+ int inputs = OperatorProperties::GetControlInputCount(control->op());
if (value->opcode() == IrOpcode::kPhi &&
NodeProperties::GetControlInput(value) == control) {
// Phi already exists, add input.
static Node* GetControlCluster(Node* node) {
- if (NodeProperties::IsBasicBlockBegin(node)) {
+ if (OperatorProperties::IsBasicBlockBegin(node->op())) {
return node;
- } else if (NodeProperties::GetControlInputCount(node) == 1) {
+ } else if (OperatorProperties::GetControlInputCount(node->op()) == 1) {
Node* control = NodeProperties::GetControlInput(node, 0);
- return NodeProperties::IsBasicBlockBegin(control) ? control : NULL;
+ return OperatorProperties::IsBasicBlockBegin(control->op()) ? control
+ : NULL;
} else {
return NULL;
}
os_ << " label=\"{{#" << node->id() << ":" << Escaped(label);
InputIter i = node->inputs().begin();
- for (int j = NodeProperties::GetValueInputCount(node); j > 0; ++i, j--) {
+ for (int j = OperatorProperties::GetValueInputCount(node->op()); j > 0;
+ ++i, j--) {
os_ << "|<I" << i.index() << ">#" << (*i)->id();
}
- for (int j = NodeProperties::GetContextInputCount(node); j > 0; ++i, j--) {
+ for (int j = OperatorProperties::GetContextInputCount(node->op()); j > 0;
+ ++i, j--) {
os_ << "|<I" << i.index() << ">X #" << (*i)->id();
}
- for (int j = NodeProperties::GetEffectInputCount(node); j > 0; ++i, j--) {
+ for (int j = OperatorProperties::GetEffectInputCount(node->op()); j > 0;
+ ++i, j--) {
os_ << "|<I" << i.index() << ">E #" << (*i)->id();
}
- if (!use_to_def_ || NodeProperties::IsBasicBlockBegin(node) ||
+ if (!use_to_def_ || OperatorProperties::IsBasicBlockBegin(node->op()) ||
GetControlCluster(node) == NULL) {
- for (int j = NodeProperties::GetControlInputCount(node); j > 0; ++i, j--) {
+ for (int j = OperatorProperties::GetControlInputCount(node->op()); j > 0;
+ ++i, j--) {
os_ << "|<I" << i.index() << ">C #" << (*i)->id();
}
}
os_ << " ID" << from->id();
if (all_nodes_.count(to) == 0) {
os_ << ":I" << index << ":n -> DEAD_INPUT";
- } else if (NodeProperties::IsBasicBlockBegin(from) ||
+ } else if (OperatorProperties::IsBasicBlockBegin(from->op()) ||
GetControlCluster(from) == NULL ||
- (NodeProperties::GetControlInputCount(from) > 0 &&
+ (OperatorProperties::GetControlInputCount(from->op()) > 0 &&
NodeProperties::GetControlInput(from) != to)) {
os_ << ":I" << index << ":n -> ID" << to->id() << ":s";
if (unconstrained) os_ << " [constraint=false,style=dotted]";
BasicBlock* deopt_node) {
OperandGenerator g(this);
DCHECK_EQ(call->op()->OutputCount(), buffer->descriptor->ReturnCount());
- DCHECK_EQ(NodeProperties::GetValueInputCount(call), buffer->input_count());
+ DCHECK_EQ(OperatorProperties::GetValueInputCount(call->op()),
+ buffer->input_count());
if (buffer->descriptor->ReturnCount() > 0) {
// Collect the projections that represent multiple outputs from this call.
const Runtime::Function* fun = Runtime::FunctionForId(f);
int nargs = (nargs_override < 0) ? fun->nargs : nargs_override;
CallDescriptor::DeoptimizationSupport deopt =
- NodeProperties::CanLazilyDeoptimize(node)
+ OperatorProperties::CanLazilyDeoptimize(node->op())
? CallDescriptor::kCanDeoptimize
: CallDescriptor::kCannotDeoptimize;
CallDescriptor* desc =
Node* JSGenericLowering::LowerJSCallRuntime(Node* node) {
Runtime::FunctionId function = OpParameter<Runtime::FunctionId>(node);
- int arity = NodeProperties::GetValueInputCount(node);
+ int arity = OperatorProperties::GetValueInputCount(node->op());
ReplaceWithRuntimeCall(node, function, arity);
return node;
}
namespace compiler {
// -----------------------------------------------------------------------------
-// Input counts & layout.
+// Input layout.
// Inputs are always arranged in order as follows:
// 0 [ values, context, effects, control ] node->InputCount()
-inline bool NodeProperties::HasValueInput(Node* node) {
- return OperatorProperties::HasValueInput(node->op());
-}
-
-inline bool NodeProperties::HasContextInput(Node* node) {
- return OperatorProperties::HasContextInput(node->op());
-}
-
-inline bool NodeProperties::HasEffectInput(Node* node) {
- return OperatorProperties::HasEffectInput(node->op());
-}
-
-inline bool NodeProperties::HasControlInput(Node* node) {
- return OperatorProperties::HasControlInput(node->op());
-}
-
-
-inline int NodeProperties::GetValueInputCount(Node* node) {
- return OperatorProperties::GetValueInputCount(node->op());
-}
-
-inline int NodeProperties::GetContextInputCount(Node* node) {
- return OperatorProperties::GetContextInputCount(node->op());
-}
-
-inline int NodeProperties::GetEffectInputCount(Node* node) {
- return OperatorProperties::GetEffectInputCount(node->op());
-}
-
-inline int NodeProperties::GetControlInputCount(Node* node) {
- return OperatorProperties::GetControlInputCount(node->op());
-}
-
inline int NodeProperties::GetContextIndex(Node* node) {
return PastValueIndex(node);
}
-
inline int NodeProperties::FirstValueIndex(Node* node) { return 0; }
inline int NodeProperties::FirstEffectIndex(Node* node) {
inline int NodeProperties::PastValueIndex(Node* node) {
- return FirstValueIndex(node) + GetValueInputCount(node);
+ return FirstValueIndex(node) +
+ OperatorProperties::GetValueInputCount(node->op());
}
inline int NodeProperties::PastContextIndex(Node* node) {
- return GetContextIndex(node) + GetContextInputCount(node);
+ return GetContextIndex(node) +
+ OperatorProperties::GetContextInputCount(node->op());
}
inline int NodeProperties::PastEffectIndex(Node* node) {
- return FirstEffectIndex(node) + GetEffectInputCount(node);
+ return FirstEffectIndex(node) +
+ OperatorProperties::GetEffectInputCount(node->op());
}
inline int NodeProperties::PastControlIndex(Node* node) {
- return FirstControlIndex(node) + GetControlInputCount(node);
+ return FirstControlIndex(node) +
+ OperatorProperties::GetControlInputCount(node->op());
}
// Input accessors.
inline Node* NodeProperties::GetValueInput(Node* node, int index) {
- DCHECK(0 <= index && index < GetValueInputCount(node));
+ DCHECK(0 <= index &&
+ index < OperatorProperties::GetValueInputCount(node->op()));
return node->InputAt(FirstValueIndex(node) + index);
}
inline Node* NodeProperties::GetContextInput(Node* node) {
- DCHECK(HasContextInput(node));
+ DCHECK(OperatorProperties::HasContextInput(node->op()));
return node->InputAt(GetContextIndex(node));
}
inline Node* NodeProperties::GetEffectInput(Node* node, int index) {
- DCHECK(0 <= index && index < GetEffectInputCount(node));
+ DCHECK(0 <= index &&
+ index < OperatorProperties::GetEffectInputCount(node->op()));
return node->InputAt(FirstEffectIndex(node) + index);
}
inline Node* NodeProperties::GetControlInput(Node* node, int index) {
- DCHECK(0 <= index && index < GetControlInputCount(node));
+ DCHECK(0 <= index &&
+ index < OperatorProperties::GetControlInputCount(node->op()));
return node->InputAt(FirstControlIndex(node) + index);
}
// -----------------------------------------------------------------------------
-// Output counts.
-
-inline bool NodeProperties::HasValueOutput(Node* node) {
- return OperatorProperties::HasValueOutput(node->op());
-}
-
-inline bool NodeProperties::HasEffectOutput(Node* node) {
- return OperatorProperties::HasEffectOutput(node->op());
-}
-
-inline bool NodeProperties::HasControlOutput(Node* node) {
- return OperatorProperties::HasControlOutput(node->op());
-}
-
-
-inline int NodeProperties::GetValueOutputCount(Node* node) {
- return OperatorProperties::GetValueOutputCount(node->op());
-}
-
-inline int NodeProperties::GetEffectOutputCount(Node* node) {
- return OperatorProperties::GetEffectOutputCount(node->op());
-}
-
-inline int NodeProperties::GetControlOutputCount(Node* node) {
- return OperatorProperties::GetControlOutputCount(node->op());
-}
-
-
-// -----------------------------------------------------------------------------
// Edge kinds.
inline bool NodeProperties::IsInputRange(Node::Edge edge, int first, int num) {
inline bool NodeProperties::IsValueEdge(Node::Edge edge) {
Node* node = edge.from();
- return IsInputRange(edge, FirstValueIndex(node), GetValueInputCount(node));
+ return IsInputRange(edge, FirstValueIndex(node),
+ OperatorProperties::GetValueInputCount(node->op()));
}
inline bool NodeProperties::IsContextEdge(Node::Edge edge) {
Node* node = edge.from();
- return IsInputRange(edge, GetContextIndex(node), GetContextInputCount(node));
+ return IsInputRange(edge, GetContextIndex(node),
+ OperatorProperties::GetContextInputCount(node->op()));
}
inline bool NodeProperties::IsEffectEdge(Node::Edge edge) {
Node* node = edge.from();
- return IsInputRange(edge, FirstEffectIndex(node), GetEffectInputCount(node));
+ return IsInputRange(edge, FirstEffectIndex(node),
+ OperatorProperties::GetEffectInputCount(node->op()));
}
inline bool NodeProperties::IsControlEdge(Node::Edge edge) {
Node* node = edge.from();
return IsInputRange(edge, FirstControlIndex(node),
- GetControlInputCount(node));
+ OperatorProperties::GetControlInputCount(node->op()));
}
return IrOpcode::IsControlOpcode(node->opcode());
}
-inline bool NodeProperties::IsBasicBlockBegin(Node* node) {
- return OperatorProperties::IsBasicBlockBegin(node->op());
-}
-
-inline bool NodeProperties::CanBeScheduled(Node* node) {
- return OperatorProperties::CanBeScheduled(node->op());
-}
-
-inline bool NodeProperties::HasFixedSchedulePosition(Node* node) {
- return OperatorProperties::HasFixedSchedulePosition(node->op());
-}
-
-inline bool NodeProperties::IsScheduleRoot(Node* node) {
- return OperatorProperties::IsScheduleRoot(node->op());
-}
-
// -----------------------------------------------------------------------------
// Miscellaneous mutators.
inline void NodeProperties::ReplaceEffectInput(Node* node, Node* effect,
int index) {
- DCHECK(index < GetEffectInputCount(node));
+ DCHECK(index < OperatorProperties::GetEffectInputCount(node->op()));
return node->ReplaceInput(
- GetValueInputCount(node) + GetContextInputCount(node) + index, effect);
+ OperatorProperties::GetValueInputCount(node->op()) +
+ OperatorProperties::GetContextInputCount(node->op()) + index,
+ effect);
}
inline void NodeProperties::RemoveNonValueInputs(Node* node) {
- node->TrimInputCount(GetValueInputCount(node));
+ node->TrimInputCount(OperatorProperties::GetValueInputCount(node->op()));
}
}
-inline bool NodeProperties::CanLazilyDeoptimize(Node* node) {
- return OperatorProperties::CanLazilyDeoptimize(node->op());
-}
}
}
} // namespace v8::internal::compiler
// A facade that simplifies access to the different kinds of inputs to a node.
class NodeProperties {
public:
- static inline bool HasValueInput(Node* node);
- static inline bool HasContextInput(Node* node);
- static inline bool HasEffectInput(Node* node);
- static inline bool HasControlInput(Node* node);
-
- static inline int GetValueInputCount(Node* node);
- static inline int GetContextInputCount(Node* node);
- static inline int GetEffectInputCount(Node* node);
- static inline int GetControlInputCount(Node* node);
- static inline int GetTotalInputCount(Node* node);
-
static inline Node* GetValueInput(Node* node, int index);
static inline Node* GetContextInput(Node* node);
static inline Node* GetEffectInput(Node* node, int index = 0);
static inline Node* GetControlInput(Node* node, int index = 0);
- static inline bool HasValueOutput(Node* node);
- static inline bool HasEffectOutput(Node* node);
- static inline bool HasControlOutput(Node* node);
-
- static inline int GetValueOutputCount(Node* node);
- static inline int GetEffectOutputCount(Node* node);
- static inline int GetControlOutputCount(Node* node);
-
static inline bool IsValueEdge(Node::Edge edge);
static inline bool IsContextEdge(Node::Edge edge);
static inline bool IsEffectEdge(Node::Edge edge);
static inline bool IsControlEdge(Node::Edge edge);
static inline bool IsControl(Node* node);
- static inline bool IsBasicBlockBegin(Node* node);
-
- static inline bool CanBeScheduled(Node* node);
- static inline bool HasFixedSchedulePosition(Node* node);
- static inline bool IsScheduleRoot(Node* node);
static inline void ReplaceEffectInput(Node* node, Node* effect,
int index = 0);
static inline Bounds GetBounds(Node* node);
static inline void SetBounds(Node* node, Bounds bounds);
- static inline bool CanLazilyDeoptimize(Node* node);
-
static inline int GetContextIndex(Node* node);
private:
break;
}
case IrOpcode::kCall: {
- if (NodeProperties::CanLazilyDeoptimize(node)) {
+ if (OperatorProperties::CanLazilyDeoptimize(node->op())) {
scheduler_->calls_.push_back(node);
}
break;
// For all of the merge's control inputs, add a goto at the end to the
// merge's basic block.
for (InputIter j = (*i)->inputs().begin(); j != (*i)->inputs().end(); ++j) {
- if (NodeProperties::IsBasicBlockBegin(*i)) {
+ if (OperatorProperties::IsBasicBlockBegin((*i)->op())) {
BasicBlock* predecessor_block = schedule_->block(*j);
if ((*j)->opcode() != IrOpcode::kReturn &&
(*j)->opcode() != IrOpcode::kDeoptimize) {
for (NodeVectorIter i = calls_.begin(); i != calls_.end(); ++i) {
Node* call = *i;
DCHECK(call->opcode() == IrOpcode::kCall);
- DCHECK(NodeProperties::CanLazilyDeoptimize(call));
+ DCHECK(OperatorProperties::CanLazilyDeoptimize(call->op()));
Node* lazy_deopt_node = NULL;
Node* cont_node = NULL;
int max_rpo = 0;
// Otherwise, the minimum rpo for the node is the max of all of the inputs.
if (!IsFixedNode(node)) {
- DCHECK(!NodeProperties::IsBasicBlockBegin(node));
+ DCHECK(!OperatorProperties::IsBasicBlockBegin(node->op()));
for (InputIter i = node->inputs().begin(); i != node->inputs().end();
++i) {
int control_rpo = scheduler_->schedule_early_rpo_index_[(*i)->id()];
}
static bool IsFixedNode(Node* node) {
- return NodeProperties::HasFixedSchedulePosition(node) ||
- !NodeProperties::CanBeScheduled(node);
+ return OperatorProperties::HasFixedSchedulePosition(node->op()) ||
+ !OperatorProperties::CanBeScheduled(node->op());
}
// TODO(mstarzinger): Dirty hack to unblock others, schedule early should be
// right place; it's a convenient place during the preparation of use counts
// to schedule them.
if (!schedule_->IsScheduled(node) &&
- NodeProperties::HasFixedSchedulePosition(node)) {
+ OperatorProperties::HasFixedSchedulePosition(node->op())) {
if (FLAG_trace_turbo_scheduler) {
PrintF("Fixed position node %d is unscheduled, scheduling now\n",
node->id());
schedule_->AddNode(block, node);
}
- if (NodeProperties::IsScheduleRoot(node)) {
+ if (OperatorProperties::IsScheduleRoot(node->op())) {
scheduler_->schedule_root_nodes_.push_back(node);
}
// If the edge is from an unscheduled node, then tally it in the use count
// for all of its inputs. The same criterion will be used in ScheduleLate
// for decrementing use counts.
- if (!schedule_->IsScheduled(from) && NodeProperties::CanBeScheduled(from)) {
- DCHECK(!NodeProperties::HasFixedSchedulePosition(from));
+ if (!schedule_->IsScheduled(from) &&
+ OperatorProperties::CanBeScheduled(from->op())) {
+ DCHECK(!OperatorProperties::HasFixedSchedulePosition(from->op()));
++scheduler_->unscheduled_uses_[to->id()];
if (FLAG_trace_turbo_scheduler) {
PrintF("Incrementing uses of node %d from %d to %d\n", to->id(),
GenericGraphVisit::Control Pre(Node* node) {
// Don't schedule nodes that cannot be scheduled or are already scheduled.
- if (!NodeProperties::CanBeScheduled(node) || schedule_->IsScheduled(node)) {
+ if (!OperatorProperties::CanBeScheduled(node->op()) ||
+ schedule_->IsScheduled(node)) {
return GenericGraphVisit::CONTINUE;
}
- DCHECK(!NodeProperties::HasFixedSchedulePosition(node));
+ DCHECK(!OperatorProperties::HasFixedSchedulePosition(node->op()));
// If all the uses of a node have been scheduled, then the node itself can
// be scheduled.
Bounds Typer::Visitor::TypePhi(Node* node) {
- int arity = NodeProperties::GetValueInputCount(node);
+ int arity = OperatorProperties::GetValueInputCount(node->op());
Bounds bounds = OperandType(node, 0);
for (int i = 1; i < arity; ++i) {
bounds = Bounds::Either(bounds, OperandType(node, i), zone());
GenericGraphVisit::Control Verifier::Visitor::Pre(Node* node) {
- int value_count = NodeProperties::GetValueInputCount(node);
- int context_count = NodeProperties::GetContextInputCount(node);
- int effect_count = NodeProperties::GetEffectInputCount(node);
- int control_count = NodeProperties::GetControlInputCount(node);
+ int value_count = OperatorProperties::GetValueInputCount(node->op());
+ int context_count = OperatorProperties::GetContextInputCount(node->op());
+ int effect_count = OperatorProperties::GetEffectInputCount(node->op());
+ int control_count = OperatorProperties::GetControlInputCount(node->op());
// Verify number of inputs matches up.
int input_count = value_count + context_count + effect_count + control_count;
// Verify all value inputs actually produce a value.
for (int i = 0; i < value_count; ++i) {
Node* value = NodeProperties::GetValueInput(node, i);
- CHECK(NodeProperties::HasValueOutput(value));
+ CHECK(OperatorProperties::HasValueOutput(value->op()));
CHECK(IsDefUseChainLinkPresent(value, node));
CHECK(IsUseDefChainLinkPresent(value, node));
}
// Verify all context inputs are value nodes.
for (int i = 0; i < context_count; ++i) {
Node* context = NodeProperties::GetContextInput(node);
- CHECK(NodeProperties::HasValueOutput(context));
+ CHECK(OperatorProperties::HasValueOutput(context->op()));
CHECK(IsDefUseChainLinkPresent(context, node));
CHECK(IsUseDefChainLinkPresent(context, node));
}
// Verify all effect inputs actually have an effect.
for (int i = 0; i < effect_count; ++i) {
Node* effect = NodeProperties::GetEffectInput(node);
- CHECK(NodeProperties::HasEffectOutput(effect));
+ CHECK(OperatorProperties::HasEffectOutput(effect->op()));
CHECK(IsDefUseChainLinkPresent(effect, node));
CHECK(IsUseDefChainLinkPresent(effect, node));
}
// Verify all control inputs are control nodes.
for (int i = 0; i < control_count; ++i) {
Node* control = NodeProperties::GetControlInput(node, i);
- CHECK(NodeProperties::HasControlOutput(control));
+ CHECK(OperatorProperties::HasControlOutput(control->op()));
CHECK(IsDefUseChainLinkPresent(control, node));
CHECK(IsUseDefChainLinkPresent(control, node));
}
// Verify all successors are projections if multiple value outputs exist.
- if (NodeProperties::GetValueOutputCount(node) > 1) {
+ if (OperatorProperties::GetValueOutputCount(node->op()) > 1) {
Node::Uses uses = node->uses();
for (Node::Uses::iterator it = uses.begin(); it != uses.end(); ++it) {
CHECK(!NodeProperties::IsValueEdge(it.edge()) ||
break;
case IrOpcode::kEnd:
// End has no outputs.
- CHECK(!NodeProperties::HasValueOutput(node));
- CHECK(!NodeProperties::HasEffectOutput(node));
- CHECK(!NodeProperties::HasControlOutput(node));
+ CHECK(!OperatorProperties::HasValueOutput(node->op()));
+ CHECK(!OperatorProperties::HasEffectOutput(node->op()));
+ CHECK(!OperatorProperties::HasControlOutput(node->op()));
break;
case IrOpcode::kDead:
// Dead is never connected to the graph.
int index = static_cast<Operator1<int>*>(node->op())->parameter();
Node* input = NodeProperties::GetValueInput(node, 0);
// Currently, parameter indices start at -1 instead of 0.
- CHECK_GT(NodeProperties::GetValueOutputCount(input), index + 1);
+ CHECK_GT(OperatorProperties::GetValueOutputCount(input->op()), index + 1);
break;
}
case IrOpcode::kInt32Constant:
// Phi input count matches parent control node.
CHECK_EQ(1, control_count);
Node* control = NodeProperties::GetControlInput(node, 0);
- CHECK_EQ(value_count, NodeProperties::GetControlInputCount(control));
+ CHECK_EQ(value_count,
+ OperatorProperties::GetControlInputCount(control->op()));
break;
}
case IrOpcode::kEffectPhi: {
// EffectPhi input count matches parent control node.
CHECK_EQ(1, control_count);
Node* control = NodeProperties::GetControlInput(node, 0);
- CHECK_EQ(effect_count, NodeProperties::GetControlInputCount(control));
+ CHECK_EQ(effect_count,
+ OperatorProperties::GetControlInputCount(control->op()));
break;
}
case IrOpcode::kLazyDeoptimization:
// Projection has an input that produces enough values.
int index = static_cast<Operator1<int>*>(node->op())->parameter();
Node* input = NodeProperties::GetValueInput(node, 0);
- CHECK_GT(NodeProperties::GetValueOutputCount(input), index);
+ CHECK_GT(OperatorProperties::GetValueOutputCount(input->op()), index);
break;
}
default:
Node* CheckConverted(IrOpcode::Value opcode, Node* node, bool effects) {
CHECK_EQ(opcode, node->opcode());
if (effects) {
- CHECK_LT(0, NodeProperties::GetEffectInputCount(node));
+ CHECK_LT(0, OperatorProperties::GetEffectInputCount(node->op()));
} else {
- CHECK_EQ(0, NodeProperties::GetEffectInputCount(node));
+ CHECK_EQ(0, OperatorProperties::GetEffectInputCount(node->op()));
}
return node;
}