[turbofan] Make Node::set_op safer via wrapper.
authormstarzinger <mstarzinger@chromium.org>
Thu, 24 Sep 2015 14:46:29 +0000 (07:46 -0700)
committerCommit bot <commit-bot@chromium.org>
Thu, 24 Sep 2015 14:46:37 +0000 (14:46 +0000)
This introduces the NodeProperties::ChangeOp helper which guards node
operator changes so that additional checking can be done without any
additional dependencies being pulled into the Node class. For now only
the input count is checked, but additional checking might follow.

R=jarin@chromium.org

Review URL: https://codereview.chromium.org/1366753003

Cr-Commit-Position: refs/heads/master@{#30916}

21 files changed:
src/compiler/ast-graph-builder.cc
src/compiler/bytecode-graph-builder.cc
src/compiler/common-operator-reducer.cc
src/compiler/control-flow-optimizer.cc
src/compiler/dead-code-elimination.cc
src/compiler/diamond.h
src/compiler/js-context-specialization.cc
src/compiler/js-generic-lowering.cc
src/compiler/js-inlining.cc
src/compiler/js-intrinsic-lowering.cc
src/compiler/js-typed-lowering.cc
src/compiler/machine-operator-reducer.cc
src/compiler/node-properties.cc
src/compiler/node-properties.h
src/compiler/node.h
src/compiler/osr.cc
src/compiler/select-lowering.cc
src/compiler/simplified-lowering.cc
src/compiler/simplified-operator-reducer.cc
src/compiler/tail-call-optimization.cc
test/unittests/compiler/graph-reducer-unittest.cc

index 963802e..8e5137e 100644 (file)
@@ -4219,12 +4219,12 @@ Node* AstGraphBuilder::MergeControl(Node* control, Node* other) {
     // Control node for loop exists, add input.
     const Operator* op = common()->Loop(inputs);
     control->AppendInput(graph_zone(), other);
-    control->set_op(op);
+    NodeProperties::ChangeOp(control, op);
   } else if (control->opcode() == IrOpcode::kMerge) {
     // Control node for merge exists, add input.
     const Operator* op = common()->Merge(inputs);
     control->AppendInput(graph_zone(), other);
-    control->set_op(op);
+    NodeProperties::ChangeOp(control, op);
   } else {
     // Control node is a singleton, introduce a merge.
     const Operator* op = common()->Merge(inputs);
@@ -4240,8 +4240,8 @@ Node* AstGraphBuilder::MergeEffect(Node* value, Node* other, Node* control) {
   if (value->opcode() == IrOpcode::kEffectPhi &&
       NodeProperties::GetControlInput(value) == control) {
     // Phi already exists, add input.
-    value->set_op(common()->EffectPhi(inputs));
     value->InsertInput(graph_zone(), inputs - 1, other);
+    NodeProperties::ChangeOp(value, common()->EffectPhi(inputs));
   } else if (value != other) {
     // Phi does not exist yet, introduce one.
     value = NewEffectPhi(inputs, value, control);
@@ -4256,8 +4256,8 @@ Node* AstGraphBuilder::MergeValue(Node* value, Node* other, Node* control) {
   if (value->opcode() == IrOpcode::kPhi &&
       NodeProperties::GetControlInput(value) == control) {
     // Phi already exists, add input.
-    value->set_op(common()->Phi(kMachAnyTagged, inputs));
     value->InsertInput(graph_zone(), inputs - 1, other);
+    NodeProperties::ChangeOp(value, common()->Phi(kMachAnyTagged, inputs));
   } else if (value != other) {
     // Phi does not exist yet, introduce one.
     value = NewPhi(inputs, value, control);
index 2d0ffa1..b63abe6 100644 (file)
@@ -418,12 +418,12 @@ Node* BytecodeGraphBuilder::MergeControl(Node* control, Node* other) {
     // Control node for loop exists, add input.
     const Operator* op = common()->Loop(inputs);
     control->AppendInput(graph_zone(), other);
-    control->set_op(op);
+    NodeProperties::ChangeOp(control, op);
   } else if (control->opcode() == IrOpcode::kMerge) {
     // Control node for merge exists, add input.
     const Operator* op = common()->Merge(inputs);
     control->AppendInput(graph_zone(), other);
-    control->set_op(op);
+    NodeProperties::ChangeOp(control, op);
   } else {
     // Control node is a singleton, introduce a merge.
     const Operator* op = common()->Merge(inputs);
index 02f99ce..e4af2ad 100644 (file)
@@ -85,10 +85,10 @@ Reduction CommonOperatorReducer::ReduceBranch(Node* node) {
     for (Node* const use : node->uses()) {
       switch (use->opcode()) {
         case IrOpcode::kIfTrue:
-          use->set_op(common()->IfFalse());
+          NodeProperties::ChangeOp(use, common()->IfFalse());
           break;
         case IrOpcode::kIfFalse:
-          use->set_op(common()->IfTrue());
+          NodeProperties::ChangeOp(use, common()->IfTrue());
           break;
         default:
           UNREACHABLE();
@@ -99,7 +99,8 @@ Reduction CommonOperatorReducer::ReduceBranch(Node* node) {
     // graph reduction logic will ensure that the uses are revisited properly.
     node->ReplaceInput(0, cond->InputAt(0));
     // Negate the hint for {branch}.
-    node->set_op(common()->Branch(NegateBranchHint(BranchHintOf(node->op()))));
+    NodeProperties::ChangeOp(
+        node, common()->Branch(NegateBranchHint(BranchHintOf(node->op()))));
     return Changed(node);
   }
   Decision const decision = DecideCondition(cond);
@@ -148,8 +149,8 @@ Reduction CommonOperatorReducer::ReduceMerge(Node* node) {
       DCHECK(branch->OwnedBy(if_true, if_false));
       Node* const control = branch->InputAt(1);
       // Mark the {branch} as {Dead}.
-      branch->set_op(common()->Dead());
       branch->TrimInputCount(0);
+      NodeProperties::ChangeOp(branch, common()->Dead());
       return Replace(control);
     }
   }
@@ -280,9 +281,8 @@ Reduction CommonOperatorReducer::ReduceReturn(Node* node) {
     DCHECK_NE(0, control_input_count);
     DCHECK_EQ(control_input_count, value->InputCount() - 1);
     DCHECK_EQ(control_input_count, effect->InputCount() - 1);
-    Node* const end = graph()->end();
-    DCHECK_EQ(IrOpcode::kEnd, end->opcode());
-    DCHECK_NE(0, end->InputCount());
+    DCHECK_EQ(IrOpcode::kEnd, graph()->end()->opcode());
+    DCHECK_NE(0, graph()->end()->InputCount());
     for (int i = 0; i < control_input_count; ++i) {
       // Create a new {Return} and connect it to {end}. We don't need to mark
       // {end} as revisit, because we mark {node} as {Dead} below, which was
@@ -290,8 +290,7 @@ Reduction CommonOperatorReducer::ReduceReturn(Node* node) {
       // the reducer logic will visit {end} again.
       Node* ret = graph()->NewNode(common()->Return(), value->InputAt(i),
                                    effect->InputAt(i), control->InputAt(i));
-      end->set_op(common()->End(end->InputCount() + 1));
-      end->AppendInput(graph()->zone(), ret);
+      NodeProperties::MergeControlToEnd(graph(), common(), ret);
     }
     // Mark the merge {control} and return {node} as {dead}.
     Replace(control, dead());
@@ -361,19 +360,19 @@ Reduction CommonOperatorReducer::ReduceSelect(Node* node) {
 
 Reduction CommonOperatorReducer::Change(Node* node, Operator const* op,
                                         Node* a) {
-  node->set_op(op);
   node->ReplaceInput(0, a);
   node->TrimInputCount(1);
+  NodeProperties::ChangeOp(node, op);
   return Changed(node);
 }
 
 
 Reduction CommonOperatorReducer::Change(Node* node, Operator const* op, Node* a,
                                         Node* b) {
-  node->set_op(op);
   node->ReplaceInput(0, a);
   node->ReplaceInput(1, b);
   node->TrimInputCount(2);
+  NodeProperties::ChangeOp(node, op);
   return Changed(node);
 }
 
index 25e183e..3fc3bce 100644 (file)
@@ -245,7 +245,7 @@ bool ControlFlowOptimizer::TryBuildSwitch(Node* node) {
       branch->NullAllInputs();
       if_true->ReplaceInput(0, node);
     }
-    if_true->set_op(common()->IfValue(value));
+    NodeProperties::ChangeOp(if_true, common()->IfValue(value));
     if_false->NullAllInputs();
     Enqueue(if_true);
 
@@ -261,13 +261,13 @@ bool ControlFlowOptimizer::TryBuildSwitch(Node* node) {
     return false;
   }
   DCHECK_LT(1u, values.size());
-  node->set_op(common()->Switch(values.size() + 1));
   node->ReplaceInput(0, index);
-  if_true->set_op(common()->IfValue(value));
+  NodeProperties::ChangeOp(node, common()->Switch(values.size() + 1));
   if_true->ReplaceInput(0, node);
+  NodeProperties::ChangeOp(if_true, common()->IfValue(value));
   Enqueue(if_true);
-  if_false->set_op(common()->IfDefault());
   if_false->ReplaceInput(0, node);
+  NodeProperties::ChangeOp(if_false, common()->IfDefault());
   Enqueue(if_false);
   branch->NullAllInputs();
   return true;
index 755620a..697d7f8 100644 (file)
@@ -52,8 +52,8 @@ Reduction DeadCodeElimination::ReduceEnd(Node* node) {
   if (live_input_count == 0) {
     return Replace(dead());
   } else if (live_input_count < input_count) {
-    node->set_op(common()->End(live_input_count));
     node->TrimInputCount(live_input_count);
+    NodeProperties::ChangeOp(node, common()->End(live_input_count));
     return Changed(node);
   }
   DCHECK_EQ(input_count, live_input_count);
@@ -137,7 +137,7 @@ Reduction DeadCodeElimination::ReduceNode(Node* node) {
 void DeadCodeElimination::TrimMergeOrPhi(Node* node, int size) {
   const Operator* const op = common()->ResizeMergeOrPhi(node->op(), size);
   node->TrimInputCount(OperatorProperties::GetTotalInputCount(op));
-  node->set_op(op);
+  NodeProperties::ChangeOp(node, op);
 }
 
 }  // namespace compiler
index cf83638..e6208e4 100644 (file)
@@ -8,6 +8,7 @@
 #include "src/compiler/common-operator.h"
 #include "src/compiler/graph.h"
 #include "src/compiler/node.h"
+#include "src/compiler/node-properties.h"
 
 namespace v8 {
 namespace internal {
@@ -60,20 +61,20 @@ struct Diamond {
   void OverwriteWithPhi(Node* node, MachineType machine_type, Node* tv,
                         Node* fv) {
     DCHECK(node->InputCount() >= 3);
-    node->set_op(common->Phi(machine_type, 2));
     node->ReplaceInput(0, tv);
     node->ReplaceInput(1, fv);
     node->ReplaceInput(2, merge);
     node->TrimInputCount(3);
+    NodeProperties::ChangeOp(node, common->Phi(machine_type, 2));
   }
 
   void OverwriteWithEffectPhi(Node* node, Node* te, Node* fe) {
     DCHECK(node->InputCount() >= 3);
-    node->set_op(common->EffectPhi(2));
     node->ReplaceInput(0, te);
     node->ReplaceInput(1, fe);
     node->ReplaceInput(2, merge);
     node->TrimInputCount(3);
+    NodeProperties::ChangeOp(node, common->EffectPhi(2));
   }
 };
 }
index 496d014..0ad25e1 100644 (file)
@@ -77,8 +77,8 @@ Reduction JSContextSpecialization::ReduceJSLoadContext(Node* node) {
     }
     const Operator* op = jsgraph_->javascript()->LoadContext(
         0, access.index(), access.immutable());
-    node->set_op(op);
     node->ReplaceInput(0, jsgraph_->Constant(context));
+    NodeProperties::ChangeOp(node, op);
     return Changed(node);
   }
   Handle<Object> value =
@@ -119,8 +119,8 @@ Reduction JSContextSpecialization::ReduceJSStoreContext(Node* node) {
     context = handle(context->previous(), isolate());
   }
 
-  node->set_op(javascript()->StoreContext(0, access.index()));
   node->ReplaceInput(0, jsgraph_->Constant(context));
+  NodeProperties::ChangeOp(node, javascript()->StoreContext(0, access.index()));
   return Changed(node);
 }
 
index ece5a72..4937b1d 100644 (file)
@@ -208,7 +208,7 @@ void JSGenericLowering::ReplaceWithCompareIC(Node* node, Token::Value token,
   node->ReplaceInput(0, booleanize);
   node->ReplaceInput(1, true_value);
   node->ReplaceInput(2, false_value);
-  node->set_op(common()->Select(kMachAnyTagged));
+  NodeProperties::ChangeOp(node, common()->Select(kMachAnyTagged));
 }
 
 
@@ -219,7 +219,7 @@ void JSGenericLowering::ReplaceWithStubCall(Node* node, Callable callable,
       isolate(), zone(), callable.descriptor(), 0, flags, properties);
   Node* stub_code = jsgraph()->HeapConstant(callable.code());
   node->InsertInput(zone(), 0, stub_code);
-  node->set_op(common()->Call(desc));
+  NodeProperties::ChangeOp(node, common()->Call(desc));
 }
 
 
@@ -236,7 +236,7 @@ void JSGenericLowering::ReplaceWithRuntimeCall(Node* node,
   node->InsertInput(zone(), 0, jsgraph()->CEntryStubConstant(fun->result_size));
   node->InsertInput(zone(), nargs + 1, ref);
   node->InsertInput(zone(), nargs + 2, arity);
-  node->set_op(common()->Call(desc));
+  NodeProperties::ChangeOp(node, common()->Call(desc));
 }
 
 
@@ -440,7 +440,7 @@ void JSGenericLowering::LowerJSLoadContext(Node* node) {
   node->ReplaceInput(1, jsgraph()->Int32Constant(Context::SlotOffset(
                             static_cast<int>(access.index()))));
   node->AppendInput(zone(), graph()->start());
-  node->set_op(machine()->Load(kMachAnyTagged));
+  NodeProperties::ChangeOp(node, machine()->Load(kMachAnyTagged));
 }
 
 
@@ -458,8 +458,8 @@ void JSGenericLowering::LowerJSStoreContext(Node* node) {
   node->ReplaceInput(2, NodeProperties::GetValueInput(node, 1));
   node->ReplaceInput(1, jsgraph()->Int32Constant(Context::SlotOffset(
                             static_cast<int>(access.index()))));
-  node->set_op(
-      machine()->Store(StoreRepresentation(kMachAnyTagged, kFullWriteBarrier)));
+  NodeProperties::ChangeOp(node, machine()->Store(StoreRepresentation(
+                                     kMachAnyTagged, kFullWriteBarrier)));
 }
 
 
@@ -551,7 +551,7 @@ void JSGenericLowering::LowerJSCallConstruct(Node* node) {
   node->InsertInput(zone(), 2, actual_construct);
   node->InsertInput(zone(), 3, original_construct);
   node->InsertInput(zone(), 4, jsgraph()->UndefinedConstant());
-  node->set_op(common()->Call(desc));
+  NodeProperties::ChangeOp(node, common()->Call(desc));
 }
 
 
@@ -568,7 +568,7 @@ void JSGenericLowering::LowerJSCallFunction(Node* node) {
       isolate(), zone(), d, static_cast<int>(p.arity() - 1), flags);
   Node* stub_code = jsgraph()->HeapConstant(stub.GetCode());
   node->InsertInput(zone(), 0, stub_code);
-  node->set_op(common()->Call(desc));
+  NodeProperties::ChangeOp(node, common()->Call(desc));
 }
 
 
index 5f97835..0b7c789 100644 (file)
@@ -179,9 +179,8 @@ Reduction JSInliner::InlineCall(Node* call, Node* context, Node* frame_state,
       case IrOpcode::kDeoptimize:
       case IrOpcode::kTerminate:
       case IrOpcode::kThrow:
-        jsgraph_->graph()->end()->AppendInput(jsgraph_->zone(), input);
-        jsgraph_->graph()->end()->set_op(
-            jsgraph_->common()->End(jsgraph_->graph()->end()->InputCount()));
+        NodeProperties::MergeControlToEnd(jsgraph_->graph(), jsgraph_->common(),
+                                          input);
         break;
       default:
         UNREACHABLE();
index 1f94716..324c42e 100644 (file)
@@ -149,8 +149,8 @@ Reduction JSIntrinsicLowering::ReduceDeoptimizeNow(Node* node) {
       graph()->NewNode(common()->Deoptimize(), frame_state, effect, control);
   NodeProperties::MergeControlToEnd(graph(), common(), deoptimize);
 
-  node->set_op(common()->Dead());
   node->TrimInputCount(0);
+  NodeProperties::ChangeOp(node, common()->Dead());
   return Changed(node);
 }
 
@@ -283,11 +283,12 @@ Reduction JSIntrinsicLowering::ReduceSeqStringGetChar(
     Node* node, String::Encoding encoding) {
   Node* effect = NodeProperties::GetEffectInput(node);
   Node* control = NodeProperties::GetControlInput(node);
-  node->set_op(
-      simplified()->LoadElement(AccessBuilder::ForSeqStringChar(encoding)));
   node->ReplaceInput(2, effect);
   node->ReplaceInput(3, control);
   node->TrimInputCount(4);
+  NodeProperties::ChangeOp(
+      node,
+      simplified()->LoadElement(AccessBuilder::ForSeqStringChar(encoding)));
   RelaxControls(node);
   return Changed(node);
 }
@@ -301,14 +302,15 @@ Reduction JSIntrinsicLowering::ReduceSeqStringSetChar(
   Node* string = NodeProperties::GetValueInput(node, 2);
   Node* effect = NodeProperties::GetEffectInput(node);
   Node* control = NodeProperties::GetControlInput(node);
-  node->set_op(
-      simplified()->StoreElement(AccessBuilder::ForSeqStringChar(encoding)));
   node->ReplaceInput(0, string);
   node->ReplaceInput(1, index);
   node->ReplaceInput(2, chr);
   node->ReplaceInput(3, effect);
   node->ReplaceInput(4, control);
   node->TrimInputCount(5);
+  NodeProperties::ChangeOp(
+      node,
+      simplified()->StoreElement(AccessBuilder::ForSeqStringChar(encoding)));
   NodeProperties::RemoveType(node);
   ReplaceWithValue(node, string, node);
   return Changed(node);
@@ -337,7 +339,7 @@ Reduction JSIntrinsicLowering::ReduceUnLikely(Node* node, BranchHint hint) {
         nodes_to_visit.push(use);
       } else if (use->opcode() == IrOpcode::kBranch) {
         // Actually set the hint on any branch using the intrinsic node.
-        use->set_op(common()->Branch(hint));
+        NodeProperties::ChangeOp(use, common()->Branch(hint));
       }
     }
   }
@@ -417,7 +419,7 @@ Reduction JSIntrinsicLowering::Change(Node* node, const Operator* op) {
   // Remove the inputs corresponding to context, effect and control.
   NodeProperties::RemoveNonValueInputs(node);
   // Finally update the operator to the new one.
-  node->set_op(op);
+  NodeProperties::ChangeOp(node, op);
   return Changed(node);
 }
 
@@ -519,14 +521,14 @@ Reduction JSIntrinsicLowering::ReduceThrowNotDateError(Node* node) {
       graph()->NewNode(common()->Deoptimize(), frame_state, effect, control);
   NodeProperties::MergeControlToEnd(graph(), common(), deoptimize);
 
-  node->set_op(common()->Dead());
   node->TrimInputCount(0);
+  NodeProperties::ChangeOp(node, common()->Dead());
   return Changed(node);
 }
 
 
 Reduction JSIntrinsicLowering::ReduceToObject(Node* node) {
-  node->set_op(javascript()->ToObject());
+  NodeProperties::ChangeOp(node, javascript()->ToObject());
   return Changed(node);
 }
 
@@ -534,24 +536,26 @@ Reduction JSIntrinsicLowering::ReduceToObject(Node* node) {
 Reduction JSIntrinsicLowering::ReduceCallFunction(Node* node) {
   CallRuntimeParameters params = OpParameter<CallRuntimeParameters>(node->op());
   size_t arity = params.arity();
-  node->set_op(javascript()->CallFunction(arity, NO_CALL_FUNCTION_FLAGS, STRICT,
-                                          VectorSlotPair(), ALLOW_TAIL_CALLS));
   Node* function = node->InputAt(static_cast<int>(arity - 1));
   while (--arity != 0) {
     node->ReplaceInput(static_cast<int>(arity),
                        node->InputAt(static_cast<int>(arity - 1)));
   }
   node->ReplaceInput(0, function);
+  NodeProperties::ChangeOp(
+      node,
+      javascript()->CallFunction(params.arity(), NO_CALL_FUNCTION_FLAGS, STRICT,
+                                 VectorSlotPair(), ALLOW_TAIL_CALLS));
   return Changed(node);
 }
 
 
 Reduction JSIntrinsicLowering::Change(Node* node, const Operator* op, Node* a,
                                       Node* b) {
-  node->set_op(op);
   node->ReplaceInput(0, a);
   node->ReplaceInput(1, b);
   node->TrimInputCount(2);
+  NodeProperties::ChangeOp(node, op);
   RelaxControls(node);
   return Changed(node);
 }
@@ -559,11 +563,11 @@ Reduction JSIntrinsicLowering::Change(Node* node, const Operator* op, Node* a,
 
 Reduction JSIntrinsicLowering::Change(Node* node, const Operator* op, Node* a,
                                       Node* b, Node* c) {
-  node->set_op(op);
   node->ReplaceInput(0, a);
   node->ReplaceInput(1, b);
   node->ReplaceInput(2, c);
   node->TrimInputCount(3);
+  NodeProperties::ChangeOp(node, op);
   RelaxControls(node);
   return Changed(node);
 }
@@ -571,12 +575,12 @@ Reduction JSIntrinsicLowering::Change(Node* node, const Operator* op, Node* a,
 
 Reduction JSIntrinsicLowering::Change(Node* node, const Operator* op, Node* a,
                                       Node* b, Node* c, Node* d) {
-  node->set_op(op);
   node->ReplaceInput(0, a);
   node->ReplaceInput(1, b);
   node->ReplaceInput(2, c);
   node->ReplaceInput(3, d);
   node->TrimInputCount(4);
+  NodeProperties::ChangeOp(node, op);
   RelaxControls(node);
   return Changed(node);
 }
index c5d03d1..db8f618 100644 (file)
@@ -163,7 +163,7 @@ class JSBinopReduction final {
     // Remove the inputs corresponding to context, effect, and control.
     NodeProperties::RemoveNonValueInputs(node_);
     // Finally, update the operator to the new one.
-    node_->set_op(op);
+    NodeProperties::ChangeOp(node_, op);
 
     // TODO(jarin): Replace the explicit typing hack with a call to some method
     // that encapsulates changing the operator and re-typing.
@@ -362,7 +362,7 @@ class JSBinopReduction final {
     NodeProperties::RemoveType(exception_merge);
     exception_merge->ReplaceInput(0, left_exception);
     exception_merge->ReplaceInput(1, right_exception);
-    exception_merge->set_op(common()->Merge(2));
+    NodeProperties::ChangeOp(exception_merge, common()->Merge(2));
 
     *left_result = left_conv;
     *right_result = right_conv;
@@ -413,7 +413,7 @@ Reduction JSTypedLowering::ReduceJSAdd(Node* node) {
     node->RemoveInput(NodeProperties::FirstFrameStateIndex(node) + 1);
     node->InsertInput(graph()->zone(), 0,
                       jsgraph()->HeapConstant(callable.code()));
-    node->set_op(common()->Call(desc));
+    NodeProperties::ChangeOp(node, common()->Call(desc));
     return Changed(node);
   }
   return NoChange();
@@ -629,14 +629,13 @@ Reduction JSTypedLowering::ReduceJSUnaryNot(Node* node) {
   Type* const input_type = NodeProperties::GetType(input);
   if (input_type->Is(Type::Boolean())) {
     // JSUnaryNot(x:boolean) => BooleanNot(x)
-    node->set_op(simplified()->BooleanNot());
     node->TrimInputCount(1);
+    NodeProperties::ChangeOp(node, simplified()->BooleanNot());
     return Changed(node);
   } else if (input_type->Is(Type::OrderedNumber())) {
     // JSUnaryNot(x:number) => NumberEqual(x,#0)
-    node->set_op(simplified()->NumberEqual());
     node->ReplaceInput(1, jsgraph()->ZeroConstant());
-    DCHECK_EQ(2, node->InputCount());
+    NodeProperties::ChangeOp(node, simplified()->NumberEqual());
     return Changed(node);
   } else if (input_type->Is(Type::String())) {
     // JSUnaryNot(x:string) => NumberEqual(x.length,#0)
@@ -645,11 +644,10 @@ Reduction JSTypedLowering::ReduceJSUnaryNot(Node* node) {
     // chain) because we assume String::length to be immutable.
     Node* length = graph()->NewNode(simplified()->LoadField(access), input,
                                     graph()->start(), graph()->start());
-    node->set_op(simplified()->NumberEqual());
     node->ReplaceInput(0, length);
     node->ReplaceInput(1, jsgraph()->ZeroConstant());
+    NodeProperties::ChangeOp(node, simplified()->NumberEqual());
     ReplaceWithValue(node, node, length);
-    DCHECK_EQ(2, node->InputCount());
     return Changed(node);
   }
   return NoChange();
@@ -664,10 +662,10 @@ Reduction JSTypedLowering::ReduceJSToBoolean(Node* node) {
     return Replace(input);
   } else if (input_type->Is(Type::OrderedNumber())) {
     // JSToBoolean(x:ordered-number) => BooleanNot(NumberEqual(x,#0))
-    node->set_op(simplified()->BooleanNot());
     node->ReplaceInput(0, graph()->NewNode(simplified()->NumberEqual(), input,
                                            jsgraph()->ZeroConstant()));
     node->TrimInputCount(1);
+    NodeProperties::ChangeOp(node, simplified()->BooleanNot());
     return Changed(node);
   } else if (input_type->Is(Type::String())) {
     // JSToBoolean(x:string) => NumberLessThan(#0,x.length)
@@ -676,10 +674,9 @@ Reduction JSTypedLowering::ReduceJSToBoolean(Node* node) {
     // chain) because we assume String::length to be immutable.
     Node* length = graph()->NewNode(simplified()->LoadField(access), input,
                                     graph()->start(), graph()->start());
-    node->set_op(simplified()->NumberLessThan());
     node->ReplaceInput(0, jsgraph()->ZeroConstant());
     node->ReplaceInput(1, length);
-    DCHECK_EQ(2, node->InputCount());
+    NodeProperties::ChangeOp(node, simplified()->NumberLessThan());
     return Changed(node);
   }
   return NoChange();
@@ -908,21 +905,22 @@ Reduction JSTypedLowering::ReduceJSStoreProperty(Node* node) {
         }
         // Check if we can avoid the bounds check.
         if (key_type->Min() >= 0 && key_type->Max() < array->length_value()) {
-          node->set_op(simplified()->StoreElement(
-              AccessBuilder::ForTypedArrayElement(array->type(), true)));
           node->ReplaceInput(0, buffer);
           DCHECK_EQ(key, node->InputAt(1));
           node->ReplaceInput(2, value);
           node->ReplaceInput(3, effect);
           node->ReplaceInput(4, control);
           node->TrimInputCount(5);
+          NodeProperties::ChangeOp(
+              node,
+              simplified()->StoreElement(
+                  AccessBuilder::ForTypedArrayElement(array->type(), true)));
           RelaxControls(node);
           return Changed(node);
         }
         // Compute byte offset.
         Node* offset = Word32Shl(key, static_cast<int>(k));
         // Turn into a StoreBuffer operation.
-        node->set_op(simplified()->StoreBuffer(access));
         node->ReplaceInput(0, buffer);
         node->ReplaceInput(1, offset);
         node->ReplaceInput(2, length);
@@ -930,6 +928,7 @@ Reduction JSTypedLowering::ReduceJSStoreProperty(Node* node) {
         node->ReplaceInput(4, effect);
         node->ReplaceInput(5, control);
         node->TrimInputCount(6);
+        NodeProperties::ChangeOp(node, simplified()->StoreBuffer(access));
         RelaxControls(node);
         return Changed(node);
       }
@@ -951,11 +950,11 @@ Reduction JSTypedLowering::ReduceJSLoadContext(Node* node) {
                    AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX)),
                NodeProperties::GetValueInput(node, 0), effect, control));
   }
-  node->set_op(
-      simplified()->LoadField(AccessBuilder::ForContextSlot(access.index())));
   node->ReplaceInput(1, effect);
   node->ReplaceInput(2, control);
-  DCHECK_EQ(3, node->InputCount());
+  NodeProperties::ChangeOp(
+      node,
+      simplified()->LoadField(AccessBuilder::ForContextSlot(access.index())));
   return Changed(node);
 }
 
@@ -972,10 +971,10 @@ Reduction JSTypedLowering::ReduceJSStoreContext(Node* node) {
                    AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX)),
                NodeProperties::GetValueInput(node, 0), effect, control));
   }
-  node->set_op(
-      simplified()->StoreField(AccessBuilder::ForContextSlot(access.index())));
   node->RemoveInput(2);
-  DCHECK_EQ(4, node->InputCount());
+  NodeProperties::ChangeOp(
+      node,
+      simplified()->StoreField(AccessBuilder::ForContextSlot(access.index())));
   return Changed(node);
 }
 
@@ -1007,8 +1006,9 @@ Reduction JSTypedLowering::ReduceJSLoadDynamicGlobal(Node* node) {
                                     check_true);
     Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
     Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
-    check_false->set_op(common()->Merge(check_false->InputCount() + 1));
     check_false->AppendInput(graph()->zone(), if_false);
+    NodeProperties::ChangeOp(check_false,
+                             common()->Merge(check_false->InputCount()));
     check_true = if_true;
   }
 
@@ -1066,8 +1066,9 @@ Reduction JSTypedLowering::ReduceJSLoadDynamicContext(Node* node) {
                                     check_true);
     Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
     Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
-    check_false->set_op(common()->Merge(check_false->InputCount() + 1));
     check_false->AppendInput(graph()->zone(), if_false);
+    NodeProperties::ChangeOp(check_false,
+                             common()->Merge(check_false->InputCount()));
     check_true = if_true;
   }
 
@@ -1115,7 +1116,7 @@ Reduction JSTypedLowering::ReduceJSCreateClosure(Node* node) {
     Node* stub_code = jsgraph()->HeapConstant(callable.code());
     node->InsertInput(graph()->zone(), 0, stub_code);
     node->InsertInput(graph()->zone(), 1, jsgraph()->HeapConstant(shared));
-    node->set_op(new_op);
+    NodeProperties::ChangeOp(node, new_op);
     return Changed(node);
   }
 
@@ -1145,7 +1146,7 @@ Reduction JSTypedLowering::ReduceJSCreateLiteralArray(Node* node) {
     const Operator* new_op = common()->Call(desc);
     Node* stub_code = jsgraph()->HeapConstant(callable.code());
     node->InsertInput(graph()->zone(), 0, stub_code);
-    node->set_op(new_op);
+    NodeProperties::ChangeOp(node, new_op);
     return Changed(node);
   }
 
@@ -1175,7 +1176,7 @@ Reduction JSTypedLowering::ReduceJSCreateLiteralObject(Node* node) {
     Node* stub_code = jsgraph()->HeapConstant(callable.code());
     node->InsertInput(graph()->zone(), 3, jsgraph()->Constant(flags));
     node->InsertInput(graph()->zone(), 0, stub_code);
-    node->set_op(new_op);
+    NodeProperties::ChangeOp(node, new_op);
     return Changed(node);
   }
 
@@ -1209,8 +1210,8 @@ Reduction JSTypedLowering::ReduceJSCreateWithContext(Node* node) {
     ReplaceWithValue(node, node, a.effect());
     node->ReplaceInput(0, a.allocation());
     node->ReplaceInput(1, a.effect());
-    node->set_op(common()->Finish(1));
     node->TrimInputCount(2);
+    NodeProperties::ChangeOp(node, common()->Finish(1));
     return Changed(node);
   }
   return NoChange();
@@ -1248,8 +1249,8 @@ Reduction JSTypedLowering::ReduceJSCreateBlockContext(Node* node) {
     ReplaceWithValue(node, node, a.effect());
     node->ReplaceInput(0, a.allocation());
     node->ReplaceInput(1, a.effect());
-    node->set_op(common()->Finish(1));
     node->TrimInputCount(2);
+    NodeProperties::ChangeOp(node, common()->Finish(1));
     return Changed(node);
   }
   return NoChange();
@@ -1280,8 +1281,9 @@ Reduction JSTypedLowering::ReduceJSCallFunction(Node* node) {
       if (is_strict(p.language_mode())) {
         flags |= CallDescriptor::kSupportsTailCalls;
       }
-      node->set_op(common()->Call(Linkage::GetJSCallDescriptor(
-          graph()->zone(), false, 1 + arity, flags)));
+      NodeProperties::ChangeOp(node,
+                               common()->Call(Linkage::GetJSCallDescriptor(
+                                   graph()->zone(), false, 1 + arity, flags)));
       return Changed(node);
     }
   }
@@ -1291,8 +1293,8 @@ Reduction JSTypedLowering::ReduceJSCallFunction(Node* node) {
 
 Reduction JSTypedLowering::ReduceJSForInDone(Node* node) {
   DCHECK_EQ(IrOpcode::kJSForInDone, node->opcode());
-  node->set_op(machine()->Word32Equal());
   node->TrimInputCount(2);
+  NodeProperties::ChangeOp(node, machine()->Word32Equal());
   return Changed(node);
 }
 
@@ -1540,20 +1542,19 @@ Reduction JSTypedLowering::ReduceJSForInNext(Node* node) {
   control = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
   effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control);
   ReplaceWithValue(node, node, effect, control);
-  node->set_op(common()->Phi(kMachAnyTagged, 2));
   node->ReplaceInput(0, vtrue0);
   node->ReplaceInput(1, vfalse0);
   node->ReplaceInput(2, control);
   node->TrimInputCount(3);
+  NodeProperties::ChangeOp(node, common()->Phi(kMachAnyTagged, 2));
   return Changed(node);
 }
 
 
 Reduction JSTypedLowering::ReduceJSForInStep(Node* node) {
   DCHECK_EQ(IrOpcode::kJSForInStep, node->opcode());
-  node->set_op(machine()->Int32Add());
   node->ReplaceInput(1, jsgraph()->Int32Constant(1));
-  DCHECK_EQ(2, node->InputCount());
+  NodeProperties::ChangeOp(node, machine()->Int32Add());
   return Changed(node);
 }
 
index b70eef5..c174da2 100644 (file)
@@ -213,14 +213,14 @@ Reduction MachineOperatorReducer::Reduce(Node* node) {
         return ReplaceInt32(m.left().Value() * m.right().Value());
       }
       if (m.right().Is(-1)) {  // x * -1 => 0 - x
-        node->set_op(machine()->Int32Sub());
         node->ReplaceInput(0, Int32Constant(0));
         node->ReplaceInput(1, m.left().node());
+        NodeProperties::ChangeOp(node, machine()->Int32Sub());
         return Changed(node);
       }
       if (m.right().IsPowerOf2()) {  // x * 2^n => x << n
-        node->set_op(machine()->Word32Shl());
         node->ReplaceInput(1, Int32Constant(WhichPowerOf2(m.right().Value())));
+        NodeProperties::ChangeOp(node, machine()->Word32Shl());
         Reduction reduction = ReduceWord32Shl(node);
         return reduction.Changed() ? reduction : Changed(node);
       }
@@ -338,9 +338,9 @@ Reduction MachineOperatorReducer::Reduce(Node* node) {
     case IrOpcode::kFloat64Mul: {
       Float64BinopMatcher m(node);
       if (m.right().Is(-1)) {  // x * -1.0 => -0.0 - x
-        node->set_op(machine()->Float64Sub());
         node->ReplaceInput(0, Float64Constant(-0.0));
         node->ReplaceInput(1, m.left().node());
+        NodeProperties::ChangeOp(node, machine()->Float64Sub());
         return Changed(node);
       }
       if (m.right().Is(1)) return Replace(m.left().node());  // x * 1.0 => x
@@ -461,9 +461,9 @@ Reduction MachineOperatorReducer::ReduceInt32Add(Node* node) {
   if (m.left().IsInt32Sub()) {
     Int32BinopMatcher mleft(m.left().node());
     if (mleft.left().Is(0)) {  // (0 - x) + y => y - x
-      node->set_op(machine()->Int32Sub());
       node->ReplaceInput(0, m.right().node());
       node->ReplaceInput(1, mleft.right().node());
+      NodeProperties::ChangeOp(node, machine()->Int32Sub());
       Reduction const reduction = ReduceInt32Sub(node);
       return reduction.Changed() ? reduction : Changed(node);
     }
@@ -471,8 +471,8 @@ Reduction MachineOperatorReducer::ReduceInt32Add(Node* node) {
   if (m.right().IsInt32Sub()) {
     Int32BinopMatcher mright(m.right().node());
     if (mright.left().Is(0)) {  // y + (0 - x) => y - x
-      node->set_op(machine()->Int32Sub());
       node->ReplaceInput(1, mright.right().node());
+      NodeProperties::ChangeOp(node, machine()->Int32Sub());
       Reduction const reduction = ReduceInt32Sub(node);
       return reduction.Changed() ? reduction : Changed(node);
     }
@@ -491,8 +491,8 @@ Reduction MachineOperatorReducer::ReduceInt32Sub(Node* node) {
   }
   if (m.LeftEqualsRight()) return ReplaceInt32(0);  // x - x => 0
   if (m.right().HasValue()) {                       // x - K => x + -K
-    node->set_op(machine()->Int32Add());
     node->ReplaceInput(1, Int32Constant(-m.right().Value()));
+    NodeProperties::ChangeOp(node, machine()->Int32Add());
     Reduction const reduction = ReduceInt32Add(node);
     return reduction.Changed() ? reduction : Changed(node);
   }
@@ -514,10 +514,10 @@ Reduction MachineOperatorReducer::ReduceInt32Div(Node* node) {
     return Replace(Word32Equal(Word32Equal(m.left().node(), zero), zero));
   }
   if (m.right().Is(-1)) {  // x / -1 => 0 - x
-    node->set_op(machine()->Int32Sub());
     node->ReplaceInput(0, Int32Constant(0));
     node->ReplaceInput(1, m.left().node());
     node->TrimInputCount(2);
+    NodeProperties::ChangeOp(node, machine()->Int32Sub());
     return Changed(node);
   }
   if (m.right().HasValue()) {
@@ -536,10 +536,10 @@ Reduction MachineOperatorReducer::ReduceInt32Div(Node* node) {
       quotient = Int32Div(quotient, Abs(divisor));
     }
     if (divisor < 0) {
-      node->set_op(machine()->Int32Sub());
       node->ReplaceInput(0, Int32Constant(0));
       node->ReplaceInput(1, quotient);
       node->TrimInputCount(2);
+      NodeProperties::ChangeOp(node, machine()->Int32Sub());
       return Changed(node);
     }
     return Replace(quotient);
@@ -565,9 +565,9 @@ Reduction MachineOperatorReducer::ReduceUint32Div(Node* node) {
     Node* const dividend = m.left().node();
     uint32_t const divisor = m.right().Value();
     if (base::bits::IsPowerOfTwo32(divisor)) {  // x / 2^n => x >> n
-      node->set_op(machine()->Word32Shr());
       node->ReplaceInput(1, Uint32Constant(WhichPowerOf2(m.right().Value())));
       node->TrimInputCount(2);
+      NodeProperties::ChangeOp(node, machine()->Word32Shr());
       return Changed(node);
     } else {
       return Replace(Uint32Div(dividend, divisor));
@@ -594,18 +594,19 @@ Reduction MachineOperatorReducer::ReduceInt32Mod(Node* node) {
     if (base::bits::IsPowerOfTwo32(divisor)) {
       uint32_t const mask = divisor - 1;
       Node* const zero = Int32Constant(0);
-      node->set_op(common()->Select(kMachInt32, BranchHint::kFalse));
       node->ReplaceInput(
           0, graph()->NewNode(machine()->Int32LessThan(), dividend, zero));
       node->ReplaceInput(
           1, Int32Sub(zero, Word32And(Int32Sub(zero, dividend), mask)));
       node->ReplaceInput(2, Word32And(dividend, mask));
+      NodeProperties::ChangeOp(
+          node, common()->Select(kMachInt32, BranchHint::kFalse));
     } else {
       Node* quotient = Int32Div(dividend, divisor);
-      node->set_op(machine()->Int32Sub());
       DCHECK_EQ(dividend, node->InputAt(0));
       node->ReplaceInput(1, Int32Mul(quotient, Int32Constant(divisor)));
       node->TrimInputCount(2);
+      NodeProperties::ChangeOp(node, machine()->Int32Sub());
     }
     return Changed(node);
   }
@@ -627,15 +628,16 @@ Reduction MachineOperatorReducer::ReduceUint32Mod(Node* node) {
     Node* const dividend = m.left().node();
     uint32_t const divisor = m.right().Value();
     if (base::bits::IsPowerOfTwo32(divisor)) {  // x % 2^n => x & 2^n-1
-      node->set_op(machine()->Word32And());
       node->ReplaceInput(1, Uint32Constant(m.right().Value() - 1));
+      node->TrimInputCount(2);
+      NodeProperties::ChangeOp(node, machine()->Word32And());
     } else {
       Node* quotient = Uint32Div(dividend, divisor);
-      node->set_op(machine()->Int32Sub());
       DCHECK_EQ(dividend, node->InputAt(0));
       node->ReplaceInput(1, Int32Mul(quotient, Uint32Constant(divisor)));
+      node->TrimInputCount(2);
+      NodeProperties::ChangeOp(node, machine()->Int32Sub());
     }
-    node->TrimInputCount(2);
     return Changed(node);
   }
   return NoChange();
@@ -663,7 +665,8 @@ Reduction MachineOperatorReducer::ReduceTruncateFloat64ToInt32(Node* node) {
         if (reduction.Changed()) input = reduction.replacement();
         phi->ReplaceInput(i, input);
       }
-      phi->set_op(common()->Phi(kMachInt32, value_input_count));
+      NodeProperties::ChangeOp(phi,
+                               common()->Phi(kMachInt32, value_input_count));
       return Replace(phi);
     }
   }
@@ -776,10 +779,10 @@ Reduction MachineOperatorReducer::ReduceWord32Shl(Node* node) {
     if (m.left().IsWord32Sar() || m.left().IsWord32Shr()) {
       Int32BinopMatcher mleft(m.left().node());
       if (mleft.right().Is(m.right().Value())) {
-        node->set_op(machine()->Word32And());
         node->ReplaceInput(0, mleft.left().node());
         node->ReplaceInput(1,
                            Uint32Constant(~((1U << m.right().Value()) - 1U)));
+        NodeProperties::ChangeOp(node, machine()->Word32And());
         Reduction reduction = ReduceWord32And(node);
         return reduction.Changed() ? reduction : Changed(node);
       }
@@ -800,9 +803,9 @@ Reduction MachineOperatorReducer::ReduceWord32Sar(Node* node) {
     if (mleft.left().IsComparison()) {
       if (m.right().Is(31) && mleft.right().Is(31)) {
         // Comparison << 31 >> 31 => 0 - Comparison
-        node->set_op(machine()->Int32Sub());
         node->ReplaceInput(0, Int32Constant(0));
         node->ReplaceInput(1, mleft.left().node());
+        NodeProperties::ChangeOp(node, machine()->Int32Sub());
         Reduction const reduction = ReduceInt32Sub(node);
         return reduction.Changed() ? reduction : Changed(node);
       }
@@ -859,9 +862,9 @@ Reduction MachineOperatorReducer::ReduceWord32And(Node* node) {
       if (mleft.right().HasValue() &&
           (mleft.right().Value() & mask) == mleft.right().Value()) {
         // (x + (K << L)) & (-1 << L) => (x & (-1 << L)) + (K << L)
-        node->set_op(machine()->Int32Add());
         node->ReplaceInput(0, Word32And(mleft.left().node(), m.right().node()));
         node->ReplaceInput(1, mleft.right().node());
+        NodeProperties::ChangeOp(node, machine()->Int32Add());
         Reduction const reduction = ReduceInt32Add(node);
         return reduction.Changed() ? reduction : Changed(node);
       }
@@ -869,10 +872,10 @@ Reduction MachineOperatorReducer::ReduceWord32And(Node* node) {
         Int32BinopMatcher mleftleft(mleft.left().node());
         if (mleftleft.right().IsMultipleOf(-mask)) {
           // (y * (K << L) + x) & (-1 << L) => (x & (-1 << L)) + y * (K << L)
-          node->set_op(machine()->Int32Add());
           node->ReplaceInput(0,
                              Word32And(mleft.right().node(), m.right().node()));
           node->ReplaceInput(1, mleftleft.node());
+          NodeProperties::ChangeOp(node, machine()->Int32Add());
           Reduction const reduction = ReduceInt32Add(node);
           return reduction.Changed() ? reduction : Changed(node);
         }
@@ -881,10 +884,10 @@ Reduction MachineOperatorReducer::ReduceWord32And(Node* node) {
         Int32BinopMatcher mleftright(mleft.right().node());
         if (mleftright.right().IsMultipleOf(-mask)) {
           // (x + y * (K << L)) & (-1 << L) => (x & (-1 << L)) + y * (K << L)
-          node->set_op(machine()->Int32Add());
           node->ReplaceInput(0,
                              Word32And(mleft.left().node(), m.right().node()));
           node->ReplaceInput(1, mleftright.node());
+          NodeProperties::ChangeOp(node, machine()->Int32Add());
           Reduction const reduction = ReduceInt32Add(node);
           return reduction.Changed() ? reduction : Changed(node);
         }
@@ -893,10 +896,10 @@ Reduction MachineOperatorReducer::ReduceWord32And(Node* node) {
         Int32BinopMatcher mleftleft(mleft.left().node());
         if (mleftleft.right().Is(base::bits::CountTrailingZeros32(mask))) {
           // (y << L + x) & (-1 << L) => (x & (-1 << L)) + y << L
-          node->set_op(machine()->Int32Add());
           node->ReplaceInput(0,
                              Word32And(mleft.right().node(), m.right().node()));
           node->ReplaceInput(1, mleftleft.node());
+          NodeProperties::ChangeOp(node, machine()->Int32Add());
           Reduction const reduction = ReduceInt32Add(node);
           return reduction.Changed() ? reduction : Changed(node);
         }
@@ -905,10 +908,10 @@ Reduction MachineOperatorReducer::ReduceWord32And(Node* node) {
         Int32BinopMatcher mleftright(mleft.right().node());
         if (mleftright.right().Is(base::bits::CountTrailingZeros32(mask))) {
           // (x + y << L) & (-1 << L) => (x & (-1 << L)) + y << L
-          node->set_op(machine()->Int32Add());
           node->ReplaceInput(0,
                              Word32And(mleft.left().node(), m.right().node()));
           node->ReplaceInput(1, mleftright.node());
+          NodeProperties::ChangeOp(node, machine()->Int32Add());
           Reduction const reduction = ReduceInt32Add(node);
           return reduction.Changed() ? reduction : Changed(node);
         }
@@ -975,9 +978,9 @@ Reduction MachineOperatorReducer::ReduceWord32Or(Node* node) {
     if (!msub.left().Is(32) || msub.right().node() != y) return NoChange();
   }
 
-  node->set_op(machine()->Word32Ror());
   node->ReplaceInput(0, mshl.left().node());
   node->ReplaceInput(1, mshr.right().node());
+  NodeProperties::ChangeOp(node, machine()->Word32Ror());
   return Changed(node);
 }
 
@@ -1040,13 +1043,13 @@ Reduction MachineOperatorReducer::ReduceFloat64Compare(Node* node) {
        m.right().IsChangeFloat32ToFloat64())) {
     switch (node->opcode()) {
       case IrOpcode::kFloat64Equal:
-        node->set_op(machine()->Float32Equal());
+        NodeProperties::ChangeOp(node, machine()->Float32Equal());
         break;
       case IrOpcode::kFloat64LessThan:
-        node->set_op(machine()->Float32LessThan());
+        NodeProperties::ChangeOp(node, machine()->Float32LessThan());
         break;
       case IrOpcode::kFloat64LessThanOrEqual:
-        node->set_op(machine()->Float32LessThanOrEqual());
+        NodeProperties::ChangeOp(node, machine()->Float32LessThanOrEqual());
         break;
       default:
         return NoChange();
index 19ca5dd..80031eb 100644 (file)
@@ -196,6 +196,13 @@ void NodeProperties::ReplaceUses(Node* node, Node* value, Node* effect,
 
 
 // static
+void NodeProperties::ChangeOp(Node* node, const Operator* new_op) {
+  DCHECK_EQ(OperatorProperties::GetTotalInputCount(new_op), node->InputCount());
+  node->set_op(new_op);
+}
+
+
+// static
 Node* NodeProperties::FindProjection(Node* node, size_t projection_index) {
   for (auto use : node->uses()) {
     if (use->opcode() == IrOpcode::kProjection &&
index 4fa160d..44f9b79 100644 (file)
@@ -94,6 +94,10 @@ class NodeProperties final {
   static void ReplaceUses(Node* node, Node* value, Node* effect = nullptr,
                           Node* success = nullptr, Node* exception = nullptr);
 
+  // Safe wrapper to mutate the operator of a node. Checks that the node is
+  // currently in a state that satisfies constraints of the new operator.
+  static void ChangeOp(Node* node, const Operator* new_op);
+
   // ---------------------------------------------------------------------------
   // Miscellaneous utilities.
 
index bd12965..d6a9b39 100644 (file)
@@ -49,7 +49,6 @@ class Node final {
   void Kill();
 
   const Operator* op() const { return op_; }
-  void set_op(const Operator* op) { op_ = op; }
 
   IrOpcode::Value opcode() const {
     DCHECK(op_->opcode() <= IrOpcode::kLast);
@@ -284,6 +283,9 @@ class Node final {
 
   void* operator new(size_t, void* location) { return location; }
 
+  // Only NodeProperties should manipulate the op.
+  void set_op(const Operator* op) { op_ = op; }
+
   // Only NodeProperties should manipulate the type.
   Type* type() const { return type_; }
   void set_type(Type* type) { type_ = type; }
index 43e139d..77eea3c 100644 (file)
@@ -237,7 +237,7 @@ static void PeelOuterLoopsForOsr(Graph* graph, CommonOperatorBuilder* common,
     NodeId const id = end->InputAt(i)->id();
     for (NodeVector* const copy : copies) {
       end->AppendInput(graph->zone(), copy->at(id));
-      end->set_op(common->End(end->InputCount()));
+      NodeProperties::ChangeOp(end, common->End(end->InputCount()));
     }
   }
 
@@ -301,12 +301,14 @@ void OsrHelper::Deconstruct(JSGraph* jsgraph, CommonOperatorBuilder* common,
   CHECK_NE(0, live_input_count);
   for (Node* const use : osr_loop->uses()) {
     if (NodeProperties::IsPhi(use)) {
-      use->set_op(common->ResizeMergeOrPhi(use->op(), live_input_count));
       use->RemoveInput(0);
+      NodeProperties::ChangeOp(
+          use, common->ResizeMergeOrPhi(use->op(), live_input_count));
     }
   }
-  osr_loop->set_op(common->ResizeMergeOrPhi(osr_loop->op(), live_input_count));
   osr_loop->RemoveInput(0);
+  NodeProperties::ChangeOp(
+      osr_loop, common->ResizeMergeOrPhi(osr_loop->op(), live_input_count));
 
   // Run control reduction and graph trimming.
   // TODO(bmeurer): The OSR deconstruction could be a regular reducer and play
index 2e0f0d1..ee648c6 100644 (file)
@@ -8,6 +8,7 @@
 #include "src/compiler/diamond.h"
 #include "src/compiler/graph.h"
 #include "src/compiler/node.h"
+#include "src/compiler/node-properties.h"
 
 namespace v8 {
 namespace internal {
@@ -51,7 +52,7 @@ Reduction SelectLowering::Reduce(Node* node) {
   }
 
   // Create a Phi hanging off the previously determined merge.
-  node->set_op(common()->Phi(p.type(), 2));
+  NodeProperties::ChangeOp(node, common()->Phi(p.type(), 2));
   node->ReplaceInput(0, vthen);
   node->ReplaceInput(1, velse);
   node->ReplaceInput(2, merge);
index 4e89d88..ecfba7f 100644 (file)
@@ -368,7 +368,8 @@ class RepresentationSelector {
       SelectParameters p = SelectParametersOf(node->op());
       MachineType type = static_cast<MachineType>(output_type);
       if (type != p.type()) {
-        node->set_op(lowering->common()->Select(type, p.hint()));
+        NodeProperties::ChangeOp(node,
+                                 lowering->common()->Select(type, p.hint()));
       }
 
       // Convert inputs to the output representation of this select.
@@ -399,7 +400,7 @@ class RepresentationSelector {
       // Update the phi operator.
       MachineType type = static_cast<MachineType>(output_type);
       if (type != OpParameter<MachineType>(node)) {
-        node->set_op(lowering->common()->Phi(type, values));
+        NodeProperties::ChangeOp(node, lowering->common()->Phi(type, values));
       }
 
       // Convert inputs to the output representation of this phi.
@@ -453,7 +454,8 @@ class RepresentationSelector {
         MachineTypeUnion input_type = GetInfo(node->InputAt(i))->output;
         (*types)[i] = static_cast<MachineType>(input_type);
       }
-      node->set_op(jsgraph_->common()->TypedStateValues(types));
+      NodeProperties::ChangeOp(node,
+                               jsgraph_->common()->TypedStateValues(types));
     }
     SetOutput(node, kMachAnyTagged);
   }
@@ -583,12 +585,12 @@ class RepresentationSelector {
           MachineTypeUnion input = GetInfo(node->InputAt(0))->output;
           if (input & kRepBit) {
             // BooleanNot(x: kRepBit) => Word32Equal(x, #0)
-            node->set_op(lowering->machine()->Word32Equal());
             node->AppendInput(jsgraph_->zone(), jsgraph_->Int32Constant(0));
+            NodeProperties::ChangeOp(node, lowering->machine()->Word32Equal());
           } else {
             // BooleanNot(x: kRepTagged) => WordEqual(x, #false)
-            node->set_op(lowering->machine()->WordEqual());
             node->AppendInput(jsgraph_->zone(), jsgraph_->FalseConstant());
+            NodeProperties::ChangeOp(node, lowering->machine()->WordEqual());
           }
         } else {
           // No input representation requirement; adapt during lowering.
@@ -605,8 +607,8 @@ class RepresentationSelector {
             DeferReplacement(node, node->InputAt(0));
           } else {
             // BooleanToNumber(x: kRepTagged) => WordEqual(x, #true)
-            node->set_op(lowering->machine()->WordEqual());
             node->AppendInput(jsgraph_->zone(), jsgraph_->TrueConstant());
+            NodeProperties::ChangeOp(node, lowering->machine()->WordEqual());
           }
         } else {
           // No input representation requirement; adapt during lowering.
@@ -622,15 +624,15 @@ class RepresentationSelector {
         if (BothInputsAre(node, Type::Signed32())) {
           // => signed Int32Cmp
           VisitInt32Cmp(node);
-          if (lower()) node->set_op(Int32Op(node));
+          if (lower()) NodeProperties::ChangeOp(node, Int32Op(node));
         } else if (BothInputsAre(node, Type::Unsigned32())) {
           // => unsigned Int32Cmp
           VisitUint32Cmp(node);
-          if (lower()) node->set_op(Uint32Op(node));
+          if (lower()) NodeProperties::ChangeOp(node, Uint32Op(node));
         } else {
           // => Float64Cmp
           VisitFloat64Cmp(node);
-          if (lower()) node->set_op(Float64Op(node));
+          if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
         }
         break;
       }
@@ -641,27 +643,27 @@ class RepresentationSelector {
         if (CanLowerToInt32Binop(node, use)) {
           // => signed Int32Add/Sub
           VisitInt32Binop(node);
-          if (lower()) node->set_op(Int32Op(node));
+          if (lower()) NodeProperties::ChangeOp(node, Int32Op(node));
         } else if (CanLowerToInt32AdditiveBinop(node, use)) {
           // => signed Int32Add/Sub, truncating inputs
           ProcessTruncateWord32Input(node, 0, kTypeInt32);
           ProcessTruncateWord32Input(node, 1, kTypeInt32);
           SetOutput(node, kMachInt32);
-          if (lower()) node->set_op(Int32Op(node));
+          if (lower()) NodeProperties::ChangeOp(node, Int32Op(node));
         } else if (CanLowerToUint32Binop(node, use)) {
           // => unsigned Int32Add/Sub
           VisitUint32Binop(node);
-          if (lower()) node->set_op(Uint32Op(node));
+          if (lower()) NodeProperties::ChangeOp(node, Uint32Op(node));
         } else if (CanLowerToUint32AdditiveBinop(node, use)) {
           // => signed Int32Add/Sub, truncating inputs
           ProcessTruncateWord32Input(node, 0, kTypeUint32);
           ProcessTruncateWord32Input(node, 1, kTypeUint32);
           SetOutput(node, kMachUint32);
-          if (lower()) node->set_op(Uint32Op(node));
+          if (lower()) NodeProperties::ChangeOp(node, Uint32Op(node));
         } else {
           // => Float64Add/Sub
           VisitFloat64Binop(node);
-          if (lower()) node->set_op(Float64Op(node));
+          if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
         }
         break;
       }
@@ -671,13 +673,13 @@ class RepresentationSelector {
           if (CanLowerToInt32Binop(node, use)) {
             // => signed Int32Mul
             VisitInt32Binop(node);
-            if (lower()) node->set_op(Int32Op(node));
+            if (lower()) NodeProperties::ChangeOp(node, Int32Op(node));
             break;
           }
         }
         // => Float64Mul
         VisitFloat64Binop(node);
-        if (lower()) node->set_op(Float64Op(node));
+        if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
         break;
       }
       case IrOpcode::kNumberDivide: {
@@ -695,7 +697,7 @@ class RepresentationSelector {
         }
         // => Float64Div
         VisitFloat64Binop(node);
-        if (lower()) node->set_op(Float64Op(node));
+        if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
         break;
       }
       case IrOpcode::kNumberModulus: {
@@ -713,7 +715,7 @@ class RepresentationSelector {
         }
         // => Float64Mod
         VisitFloat64Binop(node);
-        if (lower()) node->set_op(Float64Op(node));
+        if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
         break;
       }
       case IrOpcode::kNumberShiftLeft: {
@@ -755,8 +757,9 @@ class RepresentationSelector {
           // TODO(turbofan): avoid a truncation with a smi check.
           VisitUnop(node, kTypeInt32 | kRepFloat64, kTypeInt32 | kRepWord32);
           if (lower()) {
-            node->set_op(lowering->machine()->TruncateFloat64ToInt32(
-                TruncationMode::kJavaScript));
+            NodeProperties::ChangeOp(
+                node, lowering->machine()->TruncateFloat64ToInt32(
+                          TruncationMode::kJavaScript));
           }
         }
         break;
@@ -785,8 +788,9 @@ class RepresentationSelector {
           // TODO(turbofan): avoid a truncation with a smi check.
           VisitUnop(node, kTypeUint32 | kRepFloat64, kTypeUint32 | kRepWord32);
           if (lower()) {
-            node->set_op(lowering->machine()->TruncateFloat64ToInt32(
-                TruncationMode::kJavaScript));
+            NodeProperties::ChangeOp(
+                node, lowering->machine()->TruncateFloat64ToInt32(
+                          TruncationMode::kJavaScript));
           }
         }
         break;
@@ -801,16 +805,18 @@ class RepresentationSelector {
           CallDescriptor* desc = Linkage::GetStubCallDescriptor(
               jsgraph_->isolate(), jsgraph_->zone(), callable.descriptor(), 0,
               flags, properties);
-          node->set_op(jsgraph_->common()->Call(desc));
           node->InsertInput(jsgraph_->zone(), 0,
                             jsgraph_->HeapConstant(callable.code()));
           node->AppendInput(jsgraph_->zone(), jsgraph_->NoContextConstant());
+          NodeProperties::ChangeOp(node, jsgraph_->common()->Call(desc));
         }
         break;
       }
       case IrOpcode::kReferenceEqual: {
         VisitBinop(node, kMachAnyTagged, kRepBit);
-        if (lower()) node->set_op(lowering->machine()->WordEqual());
+        if (lower()) {
+          NodeProperties::ChangeOp(node, lowering->machine()->WordEqual());
+        }
         break;
       }
       case IrOpcode::kStringEqual: {
@@ -1210,7 +1216,6 @@ void SimplifiedLowering::DoAllocate(Node* node) {
   Runtime::FunctionId f = Runtime::kAllocateInTargetSpace;
   Operator::Properties props = node->op()->properties();
   CallDescriptor* desc = Linkage::GetRuntimeCallDescriptor(zone(), f, 2, props);
-  node->set_op(common()->Call(desc));
   ExternalReference ref(f, jsgraph()->isolate());
   int32_t flags = AllocateTargetSpace::encode(space);
   node->InsertInput(graph()->zone(), 0, jsgraph()->CEntryStubConstant(1));
@@ -1218,14 +1223,15 @@ void SimplifiedLowering::DoAllocate(Node* node) {
   node->InsertInput(graph()->zone(), 3, jsgraph()->ExternalConstant(ref));
   node->InsertInput(graph()->zone(), 4, jsgraph()->Int32Constant(2));
   node->InsertInput(graph()->zone(), 5, jsgraph()->NoContextConstant());
+  NodeProperties::ChangeOp(node, common()->Call(desc));
 }
 
 
 void SimplifiedLowering::DoLoadField(Node* node) {
   const FieldAccess& access = FieldAccessOf(node->op());
-  node->set_op(machine()->Load(access.machine_type));
   Node* offset = jsgraph()->IntPtrConstant(access.offset - access.tag());
   node->InsertInput(graph()->zone(), 1, offset);
+  NodeProperties::ChangeOp(node, machine()->Load(access.machine_type));
 }
 
 
@@ -1234,10 +1240,10 @@ void SimplifiedLowering::DoStoreField(Node* node) {
   Type* type = NodeProperties::GetType(node->InputAt(1));
   WriteBarrierKind kind =
       ComputeWriteBarrierKind(access.base_is_tagged, access.machine_type, type);
-  node->set_op(
-      machine()->Store(StoreRepresentation(access.machine_type, kind)));
   Node* offset = jsgraph()->IntPtrConstant(access.offset - access.tag());
   node->InsertInput(graph()->zone(), 1, offset);
+  NodeProperties::ChangeOp(
+      node, machine()->Store(StoreRepresentation(access.machine_type, kind)));
 }
 
 
@@ -1311,13 +1317,13 @@ void SimplifiedLowering::DoLoadBuffer(Node* node, MachineType output_type,
     NodeProperties::ReplaceUses(node, node, ephi);
 
     // Turn the {node} into a Phi.
-    node->set_op(common()->Phi(output_type, 2));
     node->ReplaceInput(0, vtrue);
     node->ReplaceInput(1, vfalse);
     node->ReplaceInput(2, merge);
     node->TrimInputCount(3);
+    NodeProperties::ChangeOp(node, common()->Phi(output_type, 2));
   } else {
-    node->set_op(machine()->CheckedLoad(type));
+    NodeProperties::ChangeOp(node, machine()->CheckedLoad(type));
   }
 }
 
@@ -1325,25 +1331,26 @@ void SimplifiedLowering::DoLoadBuffer(Node* node, MachineType output_type,
 void SimplifiedLowering::DoStoreBuffer(Node* node) {
   DCHECK_EQ(IrOpcode::kStoreBuffer, node->opcode());
   MachineType const type = BufferAccessOf(node->op()).machine_type();
-  node->set_op(machine()->CheckedStore(type));
+  NodeProperties::ChangeOp(node, machine()->CheckedStore(type));
 }
 
 
 void SimplifiedLowering::DoLoadElement(Node* node) {
   const ElementAccess& access = ElementAccessOf(node->op());
-  node->set_op(machine()->Load(access.machine_type));
   node->ReplaceInput(1, ComputeIndex(access, node->InputAt(1)));
+  NodeProperties::ChangeOp(node, machine()->Load(access.machine_type));
 }
 
 
 void SimplifiedLowering::DoStoreElement(Node* node) {
   const ElementAccess& access = ElementAccessOf(node->op());
   Type* type = NodeProperties::GetType(node->InputAt(2));
-  node->set_op(machine()->Store(
-      StoreRepresentation(access.machine_type,
-                          ComputeWriteBarrierKind(access.base_is_tagged,
-                                                  access.machine_type, type))));
   node->ReplaceInput(1, ComputeIndex(access, node->InputAt(1)));
+  NodeProperties::ChangeOp(
+      node, machine()->Store(StoreRepresentation(
+                access.machine_type,
+                ComputeWriteBarrierKind(access.base_is_tagged,
+                                        access.machine_type, type))));
 }
 
 
@@ -1610,34 +1617,34 @@ Node* SimplifiedLowering::Uint32Mod(Node* const node) {
 
 
 void SimplifiedLowering::DoShift(Node* node, Operator const* op) {
-  node->set_op(op);
   Node* const rhs = NodeProperties::GetValueInput(node, 1);
   Type* const rhs_type = NodeProperties::GetType(rhs);
   if (!rhs_type->Is(zero_thirtyone_range_)) {
     node->ReplaceInput(1, graph()->NewNode(machine()->Word32And(), rhs,
                                            jsgraph()->Int32Constant(0x1f)));
   }
+  NodeProperties::ChangeOp(node, op);
 }
 
 
 void SimplifiedLowering::DoStringEqual(Node* node) {
-  node->set_op(machine()->WordEqual());
   node->ReplaceInput(0, StringComparison(node));
   node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL));
+  NodeProperties::ChangeOp(node, machine()->WordEqual());
 }
 
 
 void SimplifiedLowering::DoStringLessThan(Node* node) {
-  node->set_op(machine()->IntLessThan());
   node->ReplaceInput(0, StringComparison(node));
   node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL));
+  NodeProperties::ChangeOp(node, machine()->IntLessThan());
 }
 
 
 void SimplifiedLowering::DoStringLessThanOrEqual(Node* node) {
-  node->set_op(machine()->IntLessThanOrEqual());
   node->ReplaceInput(0, StringComparison(node));
   node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL));
+  NodeProperties::ChangeOp(node, machine()->IntLessThanOrEqual());
 }
 
 }  // namespace compiler
index 30bf47e..a7f7905 100644 (file)
@@ -100,8 +100,8 @@ Reduction SimplifiedOperatorReducer::Change(Node* node, const Operator* op,
                                             Node* a) {
   DCHECK_EQ(node->InputCount(), OperatorProperties::GetTotalInputCount(op));
   DCHECK_LE(1, node->InputCount());
-  node->set_op(op);
   node->ReplaceInput(0, a);
+  NodeProperties::ChangeOp(node, op);
   return Changed(node);
 }
 
index a88ebe3..6635fb9 100644 (file)
@@ -63,8 +63,6 @@ Reduction TailCallOptimization::Reduce(Node* node) {
 
       DCHECK_EQ(call, NodeProperties::GetControlInput(control, 0));
       DCHECK_EQ(3, node->InputCount());
-      node->set_op(
-          common()->TailCall(OpParameter<CallDescriptor const*>(call)));
       node->ReplaceInput(0, NodeProperties::GetEffectInput(call));
       node->ReplaceInput(1, NodeProperties::GetControlInput(call));
       node->RemoveInput(2);
@@ -72,6 +70,8 @@ Reduction TailCallOptimization::Reduce(Node* node) {
         node->InsertInput(graph()->zone(), index,
                           NodeProperties::GetValueInput(call, index));
       }
+      NodeProperties::ChangeOp(
+          node, common()->TailCall(OpParameter<CallDescriptor const*>(call)));
       return Changed(node);
     }
   }
index 599af72..8d05c52 100644 (file)
@@ -5,6 +5,7 @@
 #include "src/compiler/common-operator.h"
 #include "src/compiler/graph.h"
 #include "src/compiler/node.h"
+#include "src/compiler/node-properties.h"
 #include "src/compiler/operator.h"
 #include "test/unittests/compiler/graph-reducer-unittest.h"
 #include "test/unittests/test-utils.h"
@@ -63,15 +64,15 @@ class InPlaceABReducer final : public Reducer {
     switch (node->op()->opcode()) {
       case kOpcodeA0:
         EXPECT_EQ(0, node->InputCount());
-        node->set_op(&kOpB0);
+        NodeProperties::ChangeOp(node, &kOpB0);
         return Replace(node);
       case kOpcodeA1:
         EXPECT_EQ(1, node->InputCount());
-        node->set_op(&kOpB1);
+        NodeProperties::ChangeOp(node, &kOpB1);
         return Replace(node);
       case kOpcodeA2:
         EXPECT_EQ(2, node->InputCount());
-        node->set_op(&kOpB2);
+        NodeProperties::ChangeOp(node, &kOpB2);
         return Replace(node);
     }
     return NoChange();
@@ -178,15 +179,15 @@ class InPlaceBCReducer final : public Reducer {
     switch (node->op()->opcode()) {
       case kOpcodeB0:
         EXPECT_EQ(0, node->InputCount());
-        node->set_op(&kOpC0);
+        NodeProperties::ChangeOp(node, &kOpC0);
         return Replace(node);
       case kOpcodeB1:
         EXPECT_EQ(1, node->InputCount());
-        node->set_op(&kOpC1);
+        NodeProperties::ChangeOp(node, &kOpC1);
         return Replace(node);
       case kOpcodeB2:
         EXPECT_EQ(2, node->InputCount());
-        node->set_op(&kOpC2);
+        NodeProperties::ChangeOp(node, &kOpC2);
         return Replace(node);
     }
     return NoChange();