Make generic algorithm less generic.

R=jarin@chromium.org

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

Cr-Commit-Position: refs/heads/master@{#25064}
git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@25064 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent bb78f231
...@@ -23,16 +23,9 @@ namespace compiler { ...@@ -23,16 +23,9 @@ namespace compiler {
// by specifying custom traits. // by specifying custom traits.
class GenericGraphVisit { class GenericGraphVisit {
public: public:
enum Control {
CONTINUE = 0x0, // Continue depth-first normally
SKIP = 0x1, // Skip this node and its successors
REENTER = 0x2, // Allow reentering this node
DEFER = SKIP | REENTER
};
// struct Visitor { // struct Visitor {
// Control Pre(Traits::Node* current); // void Pre(Traits::Node* current);
// Control Post(Traits::Node* current); // void Post(Traits::Node* current);
// void PreEdge(Traits::Node* from, int index, Traits::Node* to); // void PreEdge(Traits::Node* from, int index, Traits::Node* to);
// void PostEdge(Traits::Node* from, int index, Traits::Node* to); // void PostEdge(Traits::Node* from, int index, Traits::Node* to);
// } // }
...@@ -54,9 +47,8 @@ class GenericGraphVisit { ...@@ -54,9 +47,8 @@ class GenericGraphVisit {
DCHECK(id < Traits::max_id(graph)); // Must be a valid id. DCHECK(id < Traits::max_id(graph)); // Must be a valid id.
bool visit = !GetVisited(&visited, id); bool visit = !GetVisited(&visited, id);
if (visit) { if (visit) {
Control control = visitor->Pre(current); visitor->Pre(current);
visit = !IsSkip(control); SetVisited(&visited, id);
if (!IsReenter(control)) SetVisited(&visited, id, true);
} }
Iterator begin(visit ? Traits::begin(current) : Traits::end(current)); Iterator begin(visit ? Traits::begin(current) : Traits::end(current));
Iterator end(Traits::end(current)); Iterator end(Traits::end(current));
...@@ -66,9 +58,8 @@ class GenericGraphVisit { ...@@ -66,9 +58,8 @@ class GenericGraphVisit {
NodeState top = stack.top(); NodeState top = stack.top();
if (top.first == top.second) { if (top.first == top.second) {
if (visit) { if (visit) {
Control control = visitor->Post(post_order_node); visitor->Post(post_order_node);
DCHECK(!IsSkip(control)); SetVisited(&visited, post_order_node->id());
SetVisited(&visited, post_order_node->id(), !IsReenter(control));
} }
stack.pop(); stack.pop();
if (stack.empty()) { if (stack.empty()) {
...@@ -101,23 +92,19 @@ class GenericGraphVisit { ...@@ -101,23 +92,19 @@ class GenericGraphVisit {
template <class B, class S> template <class B, class S>
struct NullNodeVisitor { struct NullNodeVisitor {
Control Pre(GenericNode<B, S>* node) { return CONTINUE; } void Pre(GenericNode<B, S>* node) {}
Control Post(GenericNode<B, S>* node) { return CONTINUE; } void Post(GenericNode<B, S>* node) {}
void PreEdge(GenericNode<B, S>* from, int index, GenericNode<B, S>* to) {} void PreEdge(GenericNode<B, S>* from, int index, GenericNode<B, S>* to) {}
void PostEdge(GenericNode<B, S>* from, int index, GenericNode<B, S>* to) {} void PostEdge(GenericNode<B, S>* from, int index, GenericNode<B, S>* to) {}
}; };
private: private:
static bool IsSkip(Control c) { return c & SKIP; } static void SetVisited(BoolVector* visited, int id) {
static bool IsReenter(Control c) { return c & REENTER; }
// TODO(turbofan): resizing could be optionally templatized away.
static void SetVisited(BoolVector* visited, int id, bool value) {
if (id >= static_cast<int>(visited->size())) { if (id >= static_cast<int>(visited->size())) {
// Resize and set all values to unvisited. // Resize and set all values to unvisited.
visited->resize((3 * id) / 2, false); visited->resize((3 * id) / 2, false);
} }
visited->at(id) = value; visited->at(id) = true;
} }
static bool GetVisited(BoolVector* visited, int id) { static bool GetVisited(BoolVector* visited, int id) {
......
...@@ -72,10 +72,7 @@ void GraphReducer::ReduceNode(Node* node) { ...@@ -72,10 +72,7 @@ void GraphReducer::ReduceNode(Node* node) {
// A helper class to reuse the node traversal algorithm. // A helper class to reuse the node traversal algorithm.
struct GraphReducerVisitor FINAL : public NullNodeVisitor { struct GraphReducerVisitor FINAL : public NullNodeVisitor {
explicit GraphReducerVisitor(GraphReducer* reducer) : reducer_(reducer) {} explicit GraphReducerVisitor(GraphReducer* reducer) : reducer_(reducer) {}
GenericGraphVisit::Control Post(Node* node) { void Post(Node* node) { reducer_->ReduceNode(node); }
reducer_->ReduceNode(node);
return GenericGraphVisit::CONTINUE;
}
GraphReducer* reducer_; GraphReducer* reducer_;
}; };
......
...@@ -24,14 +24,13 @@ void GraphReplayPrinter::PrintReplay(Graph* graph) { ...@@ -24,14 +24,13 @@ void GraphReplayPrinter::PrintReplay(Graph* graph) {
} }
GenericGraphVisit::Control GraphReplayPrinter::Pre(Node* node) { void GraphReplayPrinter::Pre(Node* node) {
PrintReplayOpCreator(node->op()); PrintReplayOpCreator(node->op());
PrintF(" Node* n%d = graph.NewNode(op", node->id()); PrintF(" Node* n%d = graph.NewNode(op", node->id());
for (int i = 0; i < node->InputCount(); ++i) { for (int i = 0; i < node->InputCount(); ++i) {
PrintF(", nil"); PrintF(", nil");
} }
PrintF("); USE(n%d);\n", node->id()); PrintF("); USE(n%d);\n", node->id());
return GenericGraphVisit::CONTINUE;
} }
......
...@@ -25,7 +25,7 @@ class GraphReplayPrinter FINAL : public NullNodeVisitor { ...@@ -25,7 +25,7 @@ class GraphReplayPrinter FINAL : public NullNodeVisitor {
static void PrintReplay(Graph* graph) {} static void PrintReplay(Graph* graph) {}
#endif #endif
GenericGraphVisit::Control Pre(Node* node); void Pre(Node* node);
void PostEdge(Node* from, int index, Node* to); void PostEdge(Node* from, int index, Node* to);
private: private:
......
...@@ -66,7 +66,7 @@ class JSONGraphNodeWriter : public NullNodeVisitor { ...@@ -66,7 +66,7 @@ class JSONGraphNodeWriter : public NullNodeVisitor {
void Print() { const_cast<Graph*>(graph_)->VisitNodeInputsFromEnd(this); } void Print() { const_cast<Graph*>(graph_)->VisitNodeInputsFromEnd(this); }
GenericGraphVisit::Control Pre(Node* node); void Pre(Node* node);
private: private:
std::ostream& os_; std::ostream& os_;
...@@ -77,7 +77,7 @@ class JSONGraphNodeWriter : public NullNodeVisitor { ...@@ -77,7 +77,7 @@ class JSONGraphNodeWriter : public NullNodeVisitor {
}; };
GenericGraphVisit::Control JSONGraphNodeWriter::Pre(Node* node) { void JSONGraphNodeWriter::Pre(Node* node) {
if (first_node_) { if (first_node_) {
first_node_ = false; first_node_ = false;
} else { } else {
...@@ -105,7 +105,6 @@ GenericGraphVisit::Control JSONGraphNodeWriter::Pre(Node* node) { ...@@ -105,7 +105,6 @@ GenericGraphVisit::Control JSONGraphNodeWriter::Pre(Node* node) {
os_ << ",\"control\":" << (NodeProperties::IsControl(node) ? "true" os_ << ",\"control\":" << (NodeProperties::IsControl(node) ? "true"
: "false"); : "false");
os_ << "}"; os_ << "}";
return GenericGraphVisit::CONTINUE;
} }
...@@ -172,7 +171,7 @@ class GraphVisualizer : public NullNodeVisitor { ...@@ -172,7 +171,7 @@ class GraphVisualizer : public NullNodeVisitor {
void Print(); void Print();
GenericGraphVisit::Control Pre(Node* node); void Pre(Node* node);
private: private:
void AnnotateNode(Node* node); void AnnotateNode(Node* node);
...@@ -202,7 +201,7 @@ static Node* GetControlCluster(Node* node) { ...@@ -202,7 +201,7 @@ static Node* GetControlCluster(Node* node) {
} }
GenericGraphVisit::Control GraphVisualizer::Pre(Node* node) { void GraphVisualizer::Pre(Node* node) {
if (all_nodes_.count(node) == 0) { if (all_nodes_.count(node) == 0) {
Node* control_cluster = GetControlCluster(node); Node* control_cluster = GetControlCluster(node);
if (control_cluster != NULL) { if (control_cluster != NULL) {
...@@ -215,7 +214,6 @@ GenericGraphVisit::Control GraphVisualizer::Pre(Node* node) { ...@@ -215,7 +214,6 @@ GenericGraphVisit::Control GraphVisualizer::Pre(Node* node) {
all_nodes_.insert(node); all_nodes_.insert(node);
if (use_to_def_) white_nodes_.insert(node); if (use_to_def_) white_nodes_.insert(node);
} }
return GenericGraphVisit::CONTINUE;
} }
......
...@@ -20,7 +20,7 @@ class ContextSpecializationVisitor : public NullNodeVisitor { ...@@ -20,7 +20,7 @@ class ContextSpecializationVisitor : public NullNodeVisitor {
explicit ContextSpecializationVisitor(JSContextSpecializer* spec) explicit ContextSpecializationVisitor(JSContextSpecializer* spec)
: spec_(spec) {} : spec_(spec) {}
GenericGraphVisit::Control Post(Node* node) { void Post(Node* node) {
switch (node->opcode()) { switch (node->opcode()) {
case IrOpcode::kJSLoadContext: { case IrOpcode::kJSLoadContext: {
Reduction r = spec_->ReduceJSLoadContext(node); Reduction r = spec_->ReduceJSLoadContext(node);
...@@ -41,7 +41,6 @@ class ContextSpecializationVisitor : public NullNodeVisitor { ...@@ -41,7 +41,6 @@ class ContextSpecializationVisitor : public NullNodeVisitor {
default: default:
break; break;
} }
return GenericGraphVisit::CONTINUE;
} }
private: private:
......
...@@ -32,7 +32,7 @@ class InlinerVisitor : public NullNodeVisitor { ...@@ -32,7 +32,7 @@ class InlinerVisitor : public NullNodeVisitor {
public: public:
explicit InlinerVisitor(JSInliner* inliner) : inliner_(inliner) {} explicit InlinerVisitor(JSInliner* inliner) : inliner_(inliner) {}
GenericGraphVisit::Control Post(Node* node) { void Post(Node* node) {
switch (node->opcode()) { switch (node->opcode()) {
case IrOpcode::kJSCallFunction: case IrOpcode::kJSCallFunction:
inliner_->TryInlineJSCall(node); inliner_->TryInlineJSCall(node);
...@@ -45,7 +45,6 @@ class InlinerVisitor : public NullNodeVisitor { ...@@ -45,7 +45,6 @@ class InlinerVisitor : public NullNodeVisitor {
default: default:
break; break;
} }
return GenericGraphVisit::CONTINUE;
} }
private: private:
...@@ -167,7 +166,7 @@ class CopyVisitor : public NullNodeVisitor { ...@@ -167,7 +166,7 @@ class CopyVisitor : public NullNodeVisitor {
sentinel_op_(IrOpcode::kDead, Operator::kNoProperties, "sentinel", 0, 0, sentinel_op_(IrOpcode::kDead, Operator::kNoProperties, "sentinel", 0, 0,
0, 0, 0, 0) {} 0, 0, 0, 0) {}
GenericGraphVisit::Control Post(Node* original) { void Post(Node* original) {
NodeVector inputs(temp_zone_); NodeVector inputs(temp_zone_);
for (InputIter it = original->inputs().begin(); for (InputIter it = original->inputs().begin();
it != original->inputs().end(); ++it) { it != original->inputs().end(); ++it) {
...@@ -180,7 +179,6 @@ class CopyVisitor : public NullNodeVisitor { ...@@ -180,7 +179,6 @@ class CopyVisitor : public NullNodeVisitor {
target_graph_->NewNode(original->op(), static_cast<int>(inputs.size()), target_graph_->NewNode(original->op(), static_cast<int>(inputs.size()),
(inputs.empty() ? NULL : &inputs.front())); (inputs.empty() ? NULL : &inputs.front()));
copies_[original->id()] = copy; copies_[original->id()] = copy;
return GenericGraphVisit::CONTINUE;
} }
Node* GetCopy(Node* original) { Node* GetCopy(Node* original) {
......
...@@ -1012,7 +1012,7 @@ class PrepareUsesVisitor : public NullNodeVisitor { ...@@ -1012,7 +1012,7 @@ class PrepareUsesVisitor : public NullNodeVisitor {
explicit PrepareUsesVisitor(Scheduler* scheduler) explicit PrepareUsesVisitor(Scheduler* scheduler)
: scheduler_(scheduler), schedule_(scheduler->schedule_) {} : scheduler_(scheduler), schedule_(scheduler->schedule_) {}
GenericGraphVisit::Control Pre(Node* node) { void Pre(Node* node) {
if (scheduler_->GetPlacement(node) == Scheduler::kFixed) { if (scheduler_->GetPlacement(node) == Scheduler::kFixed) {
// Fixed nodes are always roots for schedule late. // Fixed nodes are always roots for schedule late.
scheduler_->schedule_root_nodes_.push_back(node); scheduler_->schedule_root_nodes_.push_back(node);
...@@ -1029,8 +1029,6 @@ class PrepareUsesVisitor : public NullNodeVisitor { ...@@ -1029,8 +1029,6 @@ class PrepareUsesVisitor : public NullNodeVisitor {
schedule_->AddNode(block, node); schedule_->AddNode(block, node);
} }
} }
return GenericGraphVisit::CONTINUE;
} }
void PostEdge(Node* from, int index, Node* to) { void PostEdge(Node* from, int index, Node* to) {
......
...@@ -251,44 +251,19 @@ class Typer::RunVisitor : public Typer::Visitor { ...@@ -251,44 +251,19 @@ class Typer::RunVisitor : public Typer::Visitor {
: Visitor(typer), : Visitor(typer),
redo(NodeSet::key_compare(), NodeSet::allocator_type(typer->zone())) {} redo(NodeSet::key_compare(), NodeSet::allocator_type(typer->zone())) {}
GenericGraphVisit::Control Post(Node* node) { void Post(Node* node) {
if (node->op()->ValueOutputCount() > 0) { if (node->op()->ValueOutputCount() > 0) {
Bounds bounds = TypeNode(node); Bounds bounds = TypeNode(node);
NodeProperties::SetBounds(node, bounds); NodeProperties::SetBounds(node, bounds);
// Remember incompletely typed nodes for least fixpoint iteration. // Remember incompletely typed nodes for least fixpoint iteration.
if (!NodeProperties::AllValueInputsAreTyped(node)) redo.insert(node); if (!NodeProperties::AllValueInputsAreTyped(node)) redo.insert(node);
} }
return GenericGraphVisit::CONTINUE;
} }
NodeSet redo; NodeSet redo;
}; };
class Typer::NarrowVisitor : public Typer::Visitor {
public:
explicit NarrowVisitor(Typer* typer) : Visitor(typer) {}
GenericGraphVisit::Control Pre(Node* node) {
if (node->op()->ValueOutputCount() > 0) {
Bounds previous = NodeProperties::GetBounds(node);
Bounds current = TypeNode(node);
NodeProperties::SetBounds(node, Bounds::Both(current, previous, zone()));
DCHECK(current.Narrows(previous));
// Stop when nothing changed (but allow re-entry in case it does later).
return previous.Narrows(current) ? GenericGraphVisit::DEFER
: GenericGraphVisit::REENTER;
} else {
return GenericGraphVisit::SKIP;
}
}
GenericGraphVisit::Control Post(Node* node) {
return GenericGraphVisit::REENTER;
}
};
class Typer::WidenVisitor : public Typer::Visitor { class Typer::WidenVisitor : public Typer::Visitor {
public: public:
explicit WidenVisitor(Typer* typer) explicit WidenVisitor(Typer* typer)
...@@ -361,12 +336,6 @@ void Typer::Run() { ...@@ -361,12 +336,6 @@ void Typer::Run() {
} }
void Typer::Narrow(Node* start) {
NarrowVisitor typing(this);
graph_->VisitNodeUsesFrom(start, &typing);
}
void Typer::Decorator::Decorate(Node* node) { void Typer::Decorator::Decorate(Node* node) {
if (node->op()->ValueOutputCount() > 0) { if (node->op()->ValueOutputCount() > 0) {
// Only eagerly type-decorate nodes with known input types. // Only eagerly type-decorate nodes with known input types.
......
...@@ -21,7 +21,6 @@ class Typer { ...@@ -21,7 +21,6 @@ class Typer {
~Typer(); ~Typer();
void Run(); void Run();
void Narrow(Node* node);
Graph* graph() { return graph_; } Graph* graph() { return graph_; }
MaybeHandle<Context> context() { return context_; } MaybeHandle<Context> context() { return context_; }
...@@ -31,7 +30,6 @@ class Typer { ...@@ -31,7 +30,6 @@ class Typer {
private: private:
class Visitor; class Visitor;
class RunVisitor; class RunVisitor;
class NarrowVisitor;
class WidenVisitor; class WidenVisitor;
class Decorator; class Decorator;
......
...@@ -52,7 +52,7 @@ class Verifier::Visitor : public NullNodeVisitor { ...@@ -52,7 +52,7 @@ class Verifier::Visitor : public NullNodeVisitor {
Visitor(Zone* z, Typing typed) : zone(z), typing(typed) {} Visitor(Zone* z, Typing typed) : zone(z), typing(typed) {}
// Fulfills the PreNodeCallback interface. // Fulfills the PreNodeCallback interface.
GenericGraphVisit::Control Pre(Node* node); void Pre(Node* node);
Zone* zone; Zone* zone;
Typing typing; Typing typing;
...@@ -120,7 +120,7 @@ class Verifier::Visitor : public NullNodeVisitor { ...@@ -120,7 +120,7 @@ class Verifier::Visitor : public NullNodeVisitor {
}; };
GenericGraphVisit::Control Verifier::Visitor::Pre(Node* node) { void Verifier::Visitor::Pre(Node* node) {
int value_count = node->op()->ValueInputCount(); int value_count = node->op()->ValueInputCount();
int context_count = OperatorProperties::GetContextInputCount(node->op()); int context_count = OperatorProperties::GetContextInputCount(node->op());
int frame_state_count = int frame_state_count =
...@@ -728,8 +728,6 @@ GenericGraphVisit::Control Verifier::Visitor::Pre(Node* node) { ...@@ -728,8 +728,6 @@ GenericGraphVisit::Control Verifier::Visitor::Pre(Node* node) {
// TODO(rossberg): Check. // TODO(rossberg): Check.
break; break;
} }
return GenericGraphVisit::CONTINUE;
} }
......
...@@ -23,10 +23,9 @@ static Operator dummy_operator(IrOpcode::kParameter, Operator::kNoWrite, ...@@ -23,10 +23,9 @@ static Operator dummy_operator(IrOpcode::kParameter, Operator::kNoWrite,
class PreNodeVisitor : public NullNodeVisitor { class PreNodeVisitor : public NullNodeVisitor {
public: public:
GenericGraphVisit::Control Pre(Node* node) { void Pre(Node* node) {
printf("NODE ID: %d\n", node->id()); printf("NODE ID: %d\n", node->id());
nodes_.push_back(node); nodes_.push_back(node);
return GenericGraphVisit::CONTINUE;
} }
std::vector<Node*> nodes_; std::vector<Node*> nodes_;
}; };
...@@ -34,10 +33,9 @@ class PreNodeVisitor : public NullNodeVisitor { ...@@ -34,10 +33,9 @@ class PreNodeVisitor : public NullNodeVisitor {
class PostNodeVisitor : public NullNodeVisitor { class PostNodeVisitor : public NullNodeVisitor {
public: public:
GenericGraphVisit::Control Post(Node* node) { void Post(Node* node) {
printf("NODE ID: %d\n", node->id()); printf("NODE ID: %d\n", node->id());
nodes_.push_back(node); nodes_.push_back(node);
return GenericGraphVisit::CONTINUE;
} }
std::vector<Node*> nodes_; std::vector<Node*> nodes_;
}; };
...@@ -173,142 +171,6 @@ TEST(TestUseNodePreOrderVisitCycle) { ...@@ -173,142 +171,6 @@ TEST(TestUseNodePreOrderVisitCycle) {
} }
struct ReenterNodeVisitor : NullNodeVisitor {
GenericGraphVisit::Control Pre(Node* node) {
printf("[%d] PRE NODE: %d\n", static_cast<int>(nodes_.size()), node->id());
nodes_.push_back(node->id());
int size = static_cast<int>(nodes_.size());
switch (node->id()) {
case 0:
return size < 6 ? GenericGraphVisit::REENTER : GenericGraphVisit::SKIP;
case 1:
return size < 4 ? GenericGraphVisit::DEFER
: GenericGraphVisit::CONTINUE;
default:
return GenericGraphVisit::REENTER;
}
}
GenericGraphVisit::Control Post(Node* node) {
printf("[%d] POST NODE: %d\n", static_cast<int>(nodes_.size()), node->id());
nodes_.push_back(-node->id());
return node->id() == 4 ? GenericGraphVisit::REENTER
: GenericGraphVisit::CONTINUE;
}
void PreEdge(Node* from, int index, Node* to) {
printf("[%d] PRE EDGE: %d-%d\n", static_cast<int>(edges_.size()),
from->id(), to->id());
edges_.push_back(std::make_pair(from->id(), to->id()));
}
void PostEdge(Node* from, int index, Node* to) {
printf("[%d] POST EDGE: %d-%d\n", static_cast<int>(edges_.size()),
from->id(), to->id());
edges_.push_back(std::make_pair(-from->id(), -to->id()));
}
std::vector<int> nodes_;
std::vector<std::pair<int, int> > edges_;
};
TEST(TestUseNodeReenterVisit) {
GraphWithStartNodeTester graph;
Node* n0 = graph.start_node();
Node* n1 = graph.NewNode(&dummy_operator, n0);
Node* n2 = graph.NewNode(&dummy_operator, n0);
Node* n3 = graph.NewNode(&dummy_operator, n2);
Node* n4 = graph.NewNode(&dummy_operator, n0);
Node* n5 = graph.NewNode(&dummy_operator, n4);
n0->AppendInput(graph.main_zone(), n3);
graph.SetStart(n0);
graph.SetEnd(n5);
ReenterNodeVisitor visitor;
graph.VisitNodeUsesFromStart(&visitor);
CHECK_EQ(22, static_cast<int>(visitor.nodes_.size()));
CHECK_EQ(24, static_cast<int>(visitor.edges_.size()));
CHECK(n0->id() == visitor.nodes_[0]);
CHECK(n0->id() == visitor.edges_[0].first);
CHECK(n1->id() == visitor.edges_[0].second);
CHECK(n1->id() == visitor.nodes_[1]);
// N1 is deferred.
CHECK(-n1->id() == visitor.edges_[1].second);
CHECK(-n0->id() == visitor.edges_[1].first);
CHECK(n0->id() == visitor.edges_[2].first);
CHECK(n2->id() == visitor.edges_[2].second);
CHECK(n2->id() == visitor.nodes_[2]);
CHECK(n2->id() == visitor.edges_[3].first);
CHECK(n3->id() == visitor.edges_[3].second);
CHECK(n3->id() == visitor.nodes_[3]);
// Circle back to N0, which we may reenter for now.
CHECK(n3->id() == visitor.edges_[4].first);
CHECK(n0->id() == visitor.edges_[4].second);
CHECK(n0->id() == visitor.nodes_[4]);
CHECK(n0->id() == visitor.edges_[5].first);
CHECK(n1->id() == visitor.edges_[5].second);
CHECK(n1->id() == visitor.nodes_[5]);
// This time N1 is no longer deferred.
CHECK(-n1->id() == visitor.nodes_[6]);
CHECK(-n1->id() == visitor.edges_[6].second);
CHECK(-n0->id() == visitor.edges_[6].first);
CHECK(n0->id() == visitor.edges_[7].first);
CHECK(n2->id() == visitor.edges_[7].second);
CHECK(n2->id() == visitor.nodes_[7]);
CHECK(n2->id() == visitor.edges_[8].first);
CHECK(n3->id() == visitor.edges_[8].second);
CHECK(n3->id() == visitor.nodes_[8]);
CHECK(n3->id() == visitor.edges_[9].first);
CHECK(n0->id() == visitor.edges_[9].second);
CHECK(n0->id() == visitor.nodes_[9]);
// This time we break at N0 and skip it.
CHECK(-n0->id() == visitor.edges_[10].second);
CHECK(-n3->id() == visitor.edges_[10].first);
CHECK(-n3->id() == visitor.nodes_[10]);
CHECK(-n3->id() == visitor.edges_[11].second);
CHECK(-n2->id() == visitor.edges_[11].first);
CHECK(-n2->id() == visitor.nodes_[11]);
CHECK(-n2->id() == visitor.edges_[12].second);
CHECK(-n0->id() == visitor.edges_[12].first);
CHECK(n0->id() == visitor.edges_[13].first);
CHECK(n4->id() == visitor.edges_[13].second);
CHECK(n4->id() == visitor.nodes_[12]);
CHECK(n4->id() == visitor.edges_[14].first);
CHECK(n5->id() == visitor.edges_[14].second);
CHECK(n5->id() == visitor.nodes_[13]);
CHECK(-n5->id() == visitor.nodes_[14]);
CHECK(-n5->id() == visitor.edges_[15].second);
CHECK(-n4->id() == visitor.edges_[15].first);
CHECK(-n4->id() == visitor.nodes_[15]);
CHECK(-n4->id() == visitor.edges_[16].second);
CHECK(-n0->id() == visitor.edges_[16].first);
CHECK(-n0->id() == visitor.nodes_[16]);
CHECK(-n0->id() == visitor.edges_[17].second);
CHECK(-n3->id() == visitor.edges_[17].first);
CHECK(-n3->id() == visitor.nodes_[17]);
CHECK(-n3->id() == visitor.edges_[18].second);
CHECK(-n2->id() == visitor.edges_[18].first);
CHECK(-n2->id() == visitor.nodes_[18]);
CHECK(-n2->id() == visitor.edges_[19].second);
CHECK(-n0->id() == visitor.edges_[19].first);
// N4 may be reentered.
CHECK(n0->id() == visitor.edges_[20].first);
CHECK(n4->id() == visitor.edges_[20].second);
CHECK(n4->id() == visitor.nodes_[19]);
CHECK(n4->id() == visitor.edges_[21].first);
CHECK(n5->id() == visitor.edges_[21].second);
CHECK(-n5->id() == visitor.edges_[22].second);
CHECK(-n4->id() == visitor.edges_[22].first);
CHECK(-n4->id() == visitor.nodes_[20]);
CHECK(-n4->id() == visitor.edges_[23].second);
CHECK(-n0->id() == visitor.edges_[23].first);
CHECK(-n0->id() == visitor.nodes_[21]);
}
TEST(TestPrintNodeGraphToNodeGraphviz) { TEST(TestPrintNodeGraphToNodeGraphviz) {
GraphWithStartNodeTester graph; GraphWithStartNodeTester graph;
Node* n2 = graph.NewNode(&dummy_operator, graph.start()); Node* n2 = graph.NewNode(&dummy_operator, graph.start());
......
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