Commit dac7c953 authored by jarin's avatar jarin Committed by Commit bot

[turbofan] Move node verification methods to the Verifier class.

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

Cr-Commit-Position: refs/heads/master@{#30962}
parent 4f55b830
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "src/compiler/graph-reducer.h" #include "src/compiler/graph-reducer.h"
#include "src/compiler/node.h" #include "src/compiler/node.h"
#include "src/compiler/node-properties.h" #include "src/compiler/node-properties.h"
#include "src/compiler/verifier.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
...@@ -159,22 +160,6 @@ void GraphReducer::Replace(Node* node, Node* replacement) { ...@@ -159,22 +160,6 @@ void GraphReducer::Replace(Node* node, Node* replacement) {
} }
namespace {
void VerifyUseReplacement(const Edge& edge, const Node* replacement) {
// Check that the user does not misuse the replacement.
DCHECK(!NodeProperties::IsControlEdge(edge) ||
replacement->op()->ControlOutputCount() > 0);
DCHECK(!NodeProperties::IsEffectEdge(edge) ||
replacement->op()->EffectOutputCount() > 0);
DCHECK(!NodeProperties::IsFrameStateEdge(edge) ||
replacement->opcode() == IrOpcode::kFrameState);
}
} // namespace
void GraphReducer::Replace(Node* node, Node* replacement, NodeId max_id) { void GraphReducer::Replace(Node* node, Node* replacement, NodeId max_id) {
if (node == graph()->start()) graph()->SetStart(replacement); if (node == graph()->start()) graph()->SetStart(replacement);
if (node == graph()->end()) graph()->SetEnd(replacement); if (node == graph()->end()) graph()->SetEnd(replacement);
...@@ -183,7 +168,7 @@ void GraphReducer::Replace(Node* node, Node* replacement, NodeId max_id) { ...@@ -183,7 +168,7 @@ void GraphReducer::Replace(Node* node, Node* replacement, NodeId max_id) {
// {replacement} was already reduced and finish. // {replacement} was already reduced and finish.
for (Edge edge : node->use_edges()) { for (Edge edge : node->use_edges()) {
Node* const user = edge.from(); Node* const user = edge.from();
VerifyUseReplacement(edge, replacement); Verifier::VerifyEdgeInputReplacement(edge, replacement);
edge.UpdateTo(replacement); edge.UpdateTo(replacement);
// Don't revisit this node if it refers to itself. // Don't revisit this node if it refers to itself.
if (user != node) Revisit(user); if (user != node) Revisit(user);
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "src/base/bits.h" #include "src/base/bits.h"
#include "src/compiler/node.h" #include "src/compiler/node.h"
#include "src/compiler/node-properties.h" #include "src/compiler/node-properties.h"
#include "src/compiler/verifier.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
...@@ -45,9 +46,7 @@ void Graph::RemoveDecorator(GraphDecorator* decorator) { ...@@ -45,9 +46,7 @@ void Graph::RemoveDecorator(GraphDecorator* decorator) {
Node* Graph::NewNode(const Operator* op, int input_count, Node** inputs, Node* Graph::NewNode(const Operator* op, int input_count, Node** inputs,
bool incomplete) { bool incomplete) {
Node* node = NewNodeUnchecked(op, input_count, inputs, incomplete); Node* node = NewNodeUnchecked(op, input_count, inputs, incomplete);
#ifdef DEBUG Verifier::VerifyNode(node);
NodeProperties::Verify(node);
#endif // DEBUG
return node; return node;
} }
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include "src/compiler/graph.h" #include "src/compiler/graph.h"
#include "src/compiler/node-properties.h" #include "src/compiler/node-properties.h"
#include "src/compiler/operator-properties.h" #include "src/compiler/operator-properties.h"
#include "src/compiler/verifier.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
...@@ -198,10 +199,7 @@ void NodeProperties::ReplaceUses(Node* node, Node* value, Node* effect, ...@@ -198,10 +199,7 @@ void NodeProperties::ReplaceUses(Node* node, Node* value, Node* effect,
// static // static
void NodeProperties::ChangeOp(Node* node, const Operator* new_op) { void NodeProperties::ChangeOp(Node* node, const Operator* new_op) {
node->set_op(new_op); node->set_op(new_op);
Verifier::VerifyNode(node);
#ifdef DEBUG
Verify(node);
#endif // DEBUG
} }
...@@ -270,51 +268,6 @@ void NodeProperties::CollectControlProjections(Node* node, Node** projections, ...@@ -270,51 +268,6 @@ void NodeProperties::CollectControlProjections(Node* node, Node** projections,
} }
// static
void NodeProperties::Verify(Node* node) {
CHECK_EQ(OperatorProperties::GetTotalInputCount(node->op()),
node->InputCount());
// If this node has no effect or no control outputs,
// we check that no its uses are effect or control inputs.
bool check_no_control = node->op()->ControlOutputCount() == 0;
bool check_no_effect = node->op()->EffectOutputCount() == 0;
bool check_no_frame_state = node->opcode() != IrOpcode::kFrameState;
if (check_no_effect || check_no_control) {
for (Edge edge : node->use_edges()) {
Node* const user = edge.from();
CHECK(!user->IsDead());
if (NodeProperties::IsControlEdge(edge)) {
CHECK(!check_no_control);
} else if (NodeProperties::IsEffectEdge(edge)) {
CHECK(!check_no_effect);
} else if (NodeProperties::IsFrameStateEdge(edge)) {
CHECK(!check_no_frame_state);
}
}
}
// Frame state inputs should be frame states (or sentinels).
for (int i = 0; i < OperatorProperties::GetFrameStateInputCount(node->op());
i++) {
Node* input = NodeProperties::GetFrameStateInput(node, i);
CHECK(input->opcode() == IrOpcode::kFrameState ||
input->opcode() == IrOpcode::kStart ||
input->opcode() == IrOpcode::kDead);
}
// Effect inputs should be effect-producing nodes (or sentinels).
for (int i = 0; i < node->op()->EffectInputCount(); i++) {
Node* input = NodeProperties::GetEffectInput(node, i);
CHECK(input->op()->EffectOutputCount() > 0 ||
input->opcode() == IrOpcode::kDead);
}
// Control inputs should be control-producing nodes (or sentinels).
for (int i = 0; i < node->op()->ControlInputCount(); i++) {
Node* input = NodeProperties::GetControlInput(node, i);
CHECK(input->op()->ControlOutputCount() > 0 ||
input->opcode() == IrOpcode::kDead);
}
}
// static // static
bool NodeProperties::AllValueInputsAreTyped(Node* node) { bool NodeProperties::AllValueInputsAreTyped(Node* node) {
int input_count = node->op()->ValueInputCount(); int input_count = node->op()->ValueInputCount();
......
...@@ -110,17 +110,6 @@ class NodeProperties final { ...@@ -110,17 +110,6 @@ class NodeProperties final {
// - Switch: [ IfValue, ..., IfDefault ] // - Switch: [ IfValue, ..., IfDefault ]
static void CollectControlProjections(Node* node, Node** proj, size_t count); static void CollectControlProjections(Node* node, Node** proj, size_t count);
// Verifies consistency of node inputs and uses:
// - node inputs should agree with the input count computed from
// the node's operator.
// - effect inputs should have effect outputs.
// - control inputs should have control outputs.
// - frame state inputs should be frame states.
// - if the node has control uses, it should produce control.
// - if the node has effect uses, it should produce effect.
// - if the node has frame state uses, it must be a frame state.
static void Verify(Node* node);
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Type. // Type.
......
...@@ -1154,6 +1154,68 @@ void ScheduleVerifier::Run(Schedule* schedule) { ...@@ -1154,6 +1154,68 @@ void ScheduleVerifier::Run(Schedule* schedule) {
} }
} }
} }
#ifdef DEBUG
// static
void Verifier::VerifyNode(Node* node) {
CHECK_EQ(OperatorProperties::GetTotalInputCount(node->op()),
node->InputCount());
// If this node has no effect or no control outputs,
// we check that no its uses are effect or control inputs.
bool check_no_control = node->op()->ControlOutputCount() == 0;
bool check_no_effect = node->op()->EffectOutputCount() == 0;
bool check_no_frame_state = node->opcode() != IrOpcode::kFrameState;
if (check_no_effect || check_no_control) {
for (Edge edge : node->use_edges()) {
Node* const user = edge.from();
CHECK(!user->IsDead());
if (NodeProperties::IsControlEdge(edge)) {
CHECK(!check_no_control);
} else if (NodeProperties::IsEffectEdge(edge)) {
CHECK(!check_no_effect);
} else if (NodeProperties::IsFrameStateEdge(edge)) {
CHECK(!check_no_frame_state);
}
}
}
// Frame state inputs should be frame states (or sentinels).
for (int i = 0; i < OperatorProperties::GetFrameStateInputCount(node->op());
i++) {
Node* input = NodeProperties::GetFrameStateInput(node, i);
CHECK(input->opcode() == IrOpcode::kFrameState ||
input->opcode() == IrOpcode::kStart ||
input->opcode() == IrOpcode::kDead);
}
// Effect inputs should be effect-producing nodes (or sentinels).
for (int i = 0; i < node->op()->EffectInputCount(); i++) {
Node* input = NodeProperties::GetEffectInput(node, i);
CHECK(input->op()->EffectOutputCount() > 0 ||
input->opcode() == IrOpcode::kDead);
}
// Control inputs should be control-producing nodes (or sentinels).
for (int i = 0; i < node->op()->ControlInputCount(); i++) {
Node* input = NodeProperties::GetControlInput(node, i);
CHECK(input->op()->ControlOutputCount() > 0 ||
input->opcode() == IrOpcode::kDead);
}
}
void Verifier::VerifyEdgeInputReplacement(const Edge& edge,
const Node* replacement) {
// Check that the user does not misuse the replacement.
DCHECK(!NodeProperties::IsControlEdge(edge) ||
replacement->op()->ControlOutputCount() > 0);
DCHECK(!NodeProperties::IsEffectEdge(edge) ||
replacement->op()->EffectOutputCount() > 0);
DCHECK(!NodeProperties::IsFrameStateEdge(edge) ||
replacement->opcode() == IrOpcode::kFrameState);
}
#endif // DEBUG
} // namespace compiler } // namespace compiler
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
...@@ -12,6 +12,8 @@ namespace internal { ...@@ -12,6 +12,8 @@ namespace internal {
namespace compiler { namespace compiler {
class Graph; class Graph;
class Edge;
class Node;
class Schedule; class Schedule;
// Verifies properties of a graph, such as the well-formedness of inputs to // Verifies properties of a graph, such as the well-formedness of inputs to
...@@ -22,6 +24,28 @@ class Verifier { ...@@ -22,6 +24,28 @@ class Verifier {
static void Run(Graph* graph, Typing typing = TYPED); static void Run(Graph* graph, Typing typing = TYPED);
#ifdef DEBUG
// Verifies consistency of node inputs and uses:
// - node inputs should agree with the input count computed from
// the node's operator.
// - effect inputs should have effect outputs.
// - control inputs should have control outputs.
// - frame state inputs should be frame states.
// - if the node has control uses, it should produce control.
// - if the node has effect uses, it should produce effect.
// - if the node has frame state uses, it must be a frame state.
static void VerifyNode(Node* node);
// Verify that {replacement} has the required outputs
// (effect, control or frame state) to be used as an input for {edge}.
static void VerifyEdgeInputReplacement(const Edge& edge,
const Node* replacement);
#else
static void VerifyNode(Node* node) {}
static void VerifyEdgeInputReplacement(const Edge& edge,
const Node* replacement) {}
#endif // DEBUG
private: private:
class Visitor; class Visitor;
DISALLOW_COPY_AND_ASSIGN(Verifier); DISALLOW_COPY_AND_ASSIGN(Verifier);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment