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
This commit is contained in:
parent
bb78f231ab
commit
c63deb9b56
@ -23,16 +23,9 @@ namespace compiler {
|
||||
// by specifying custom traits.
|
||||
class GenericGraphVisit {
|
||||
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 {
|
||||
// Control Pre(Traits::Node* current);
|
||||
// Control Post(Traits::Node* current);
|
||||
// void Pre(Traits::Node* current);
|
||||
// void Post(Traits::Node* current);
|
||||
// void PreEdge(Traits::Node* from, int index, Traits::Node* to);
|
||||
// void PostEdge(Traits::Node* from, int index, Traits::Node* to);
|
||||
// }
|
||||
@ -54,9 +47,8 @@ class GenericGraphVisit {
|
||||
DCHECK(id < Traits::max_id(graph)); // Must be a valid id.
|
||||
bool visit = !GetVisited(&visited, id);
|
||||
if (visit) {
|
||||
Control control = visitor->Pre(current);
|
||||
visit = !IsSkip(control);
|
||||
if (!IsReenter(control)) SetVisited(&visited, id, true);
|
||||
visitor->Pre(current);
|
||||
SetVisited(&visited, id);
|
||||
}
|
||||
Iterator begin(visit ? Traits::begin(current) : Traits::end(current));
|
||||
Iterator end(Traits::end(current));
|
||||
@ -66,9 +58,8 @@ class GenericGraphVisit {
|
||||
NodeState top = stack.top();
|
||||
if (top.first == top.second) {
|
||||
if (visit) {
|
||||
Control control = visitor->Post(post_order_node);
|
||||
DCHECK(!IsSkip(control));
|
||||
SetVisited(&visited, post_order_node->id(), !IsReenter(control));
|
||||
visitor->Post(post_order_node);
|
||||
SetVisited(&visited, post_order_node->id());
|
||||
}
|
||||
stack.pop();
|
||||
if (stack.empty()) {
|
||||
@ -101,23 +92,19 @@ class GenericGraphVisit {
|
||||
|
||||
template <class B, class S>
|
||||
struct NullNodeVisitor {
|
||||
Control Pre(GenericNode<B, S>* node) { return CONTINUE; }
|
||||
Control Post(GenericNode<B, S>* node) { return CONTINUE; }
|
||||
void Pre(GenericNode<B, S>* node) {}
|
||||
void Post(GenericNode<B, S>* node) {}
|
||||
void PreEdge(GenericNode<B, S>* from, int index, GenericNode<B, S>* to) {}
|
||||
void PostEdge(GenericNode<B, S>* from, int index, GenericNode<B, S>* to) {}
|
||||
};
|
||||
|
||||
private:
|
||||
static bool IsSkip(Control c) { return c & SKIP; }
|
||||
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) {
|
||||
static void SetVisited(BoolVector* visited, int id) {
|
||||
if (id >= static_cast<int>(visited->size())) {
|
||||
// Resize and set all values to unvisited.
|
||||
visited->resize((3 * id) / 2, false);
|
||||
}
|
||||
visited->at(id) = value;
|
||||
visited->at(id) = true;
|
||||
}
|
||||
|
||||
static bool GetVisited(BoolVector* visited, int id) {
|
||||
|
@ -72,10 +72,7 @@ void GraphReducer::ReduceNode(Node* node) {
|
||||
// A helper class to reuse the node traversal algorithm.
|
||||
struct GraphReducerVisitor FINAL : public NullNodeVisitor {
|
||||
explicit GraphReducerVisitor(GraphReducer* reducer) : reducer_(reducer) {}
|
||||
GenericGraphVisit::Control Post(Node* node) {
|
||||
reducer_->ReduceNode(node);
|
||||
return GenericGraphVisit::CONTINUE;
|
||||
}
|
||||
void Post(Node* node) { reducer_->ReduceNode(node); }
|
||||
GraphReducer* reducer_;
|
||||
};
|
||||
|
||||
|
@ -24,14 +24,13 @@ void GraphReplayPrinter::PrintReplay(Graph* graph) {
|
||||
}
|
||||
|
||||
|
||||
GenericGraphVisit::Control GraphReplayPrinter::Pre(Node* node) {
|
||||
void GraphReplayPrinter::Pre(Node* node) {
|
||||
PrintReplayOpCreator(node->op());
|
||||
PrintF(" Node* n%d = graph.NewNode(op", node->id());
|
||||
for (int i = 0; i < node->InputCount(); ++i) {
|
||||
PrintF(", nil");
|
||||
}
|
||||
PrintF("); USE(n%d);\n", node->id());
|
||||
return GenericGraphVisit::CONTINUE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -25,7 +25,7 @@ class GraphReplayPrinter FINAL : public NullNodeVisitor {
|
||||
static void PrintReplay(Graph* graph) {}
|
||||
#endif
|
||||
|
||||
GenericGraphVisit::Control Pre(Node* node);
|
||||
void Pre(Node* node);
|
||||
void PostEdge(Node* from, int index, Node* to);
|
||||
|
||||
private:
|
||||
|
@ -66,7 +66,7 @@ class JSONGraphNodeWriter : public NullNodeVisitor {
|
||||
|
||||
void Print() { const_cast<Graph*>(graph_)->VisitNodeInputsFromEnd(this); }
|
||||
|
||||
GenericGraphVisit::Control Pre(Node* node);
|
||||
void Pre(Node* node);
|
||||
|
||||
private:
|
||||
std::ostream& os_;
|
||||
@ -77,7 +77,7 @@ class JSONGraphNodeWriter : public NullNodeVisitor {
|
||||
};
|
||||
|
||||
|
||||
GenericGraphVisit::Control JSONGraphNodeWriter::Pre(Node* node) {
|
||||
void JSONGraphNodeWriter::Pre(Node* node) {
|
||||
if (first_node_) {
|
||||
first_node_ = false;
|
||||
} else {
|
||||
@ -105,7 +105,6 @@ GenericGraphVisit::Control JSONGraphNodeWriter::Pre(Node* node) {
|
||||
os_ << ",\"control\":" << (NodeProperties::IsControl(node) ? "true"
|
||||
: "false");
|
||||
os_ << "}";
|
||||
return GenericGraphVisit::CONTINUE;
|
||||
}
|
||||
|
||||
|
||||
@ -172,7 +171,7 @@ class GraphVisualizer : public NullNodeVisitor {
|
||||
|
||||
void Print();
|
||||
|
||||
GenericGraphVisit::Control Pre(Node* node);
|
||||
void Pre(Node* node);
|
||||
|
||||
private:
|
||||
void AnnotateNode(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) {
|
||||
Node* control_cluster = GetControlCluster(node);
|
||||
if (control_cluster != NULL) {
|
||||
@ -215,7 +214,6 @@ GenericGraphVisit::Control GraphVisualizer::Pre(Node* node) {
|
||||
all_nodes_.insert(node);
|
||||
if (use_to_def_) white_nodes_.insert(node);
|
||||
}
|
||||
return GenericGraphVisit::CONTINUE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -20,7 +20,7 @@ class ContextSpecializationVisitor : public NullNodeVisitor {
|
||||
explicit ContextSpecializationVisitor(JSContextSpecializer* spec)
|
||||
: spec_(spec) {}
|
||||
|
||||
GenericGraphVisit::Control Post(Node* node) {
|
||||
void Post(Node* node) {
|
||||
switch (node->opcode()) {
|
||||
case IrOpcode::kJSLoadContext: {
|
||||
Reduction r = spec_->ReduceJSLoadContext(node);
|
||||
@ -41,7 +41,6 @@ class ContextSpecializationVisitor : public NullNodeVisitor {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return GenericGraphVisit::CONTINUE;
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -32,7 +32,7 @@ class InlinerVisitor : public NullNodeVisitor {
|
||||
public:
|
||||
explicit InlinerVisitor(JSInliner* inliner) : inliner_(inliner) {}
|
||||
|
||||
GenericGraphVisit::Control Post(Node* node) {
|
||||
void Post(Node* node) {
|
||||
switch (node->opcode()) {
|
||||
case IrOpcode::kJSCallFunction:
|
||||
inliner_->TryInlineJSCall(node);
|
||||
@ -45,7 +45,6 @@ class InlinerVisitor : public NullNodeVisitor {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return GenericGraphVisit::CONTINUE;
|
||||
}
|
||||
|
||||
private:
|
||||
@ -167,7 +166,7 @@ class CopyVisitor : public NullNodeVisitor {
|
||||
sentinel_op_(IrOpcode::kDead, Operator::kNoProperties, "sentinel", 0, 0,
|
||||
0, 0, 0, 0) {}
|
||||
|
||||
GenericGraphVisit::Control Post(Node* original) {
|
||||
void Post(Node* original) {
|
||||
NodeVector inputs(temp_zone_);
|
||||
for (InputIter it = original->inputs().begin();
|
||||
it != original->inputs().end(); ++it) {
|
||||
@ -180,7 +179,6 @@ class CopyVisitor : public NullNodeVisitor {
|
||||
target_graph_->NewNode(original->op(), static_cast<int>(inputs.size()),
|
||||
(inputs.empty() ? NULL : &inputs.front()));
|
||||
copies_[original->id()] = copy;
|
||||
return GenericGraphVisit::CONTINUE;
|
||||
}
|
||||
|
||||
Node* GetCopy(Node* original) {
|
||||
|
@ -1012,7 +1012,7 @@ class PrepareUsesVisitor : public NullNodeVisitor {
|
||||
explicit PrepareUsesVisitor(Scheduler* scheduler)
|
||||
: scheduler_(scheduler), schedule_(scheduler->schedule_) {}
|
||||
|
||||
GenericGraphVisit::Control Pre(Node* node) {
|
||||
void Pre(Node* node) {
|
||||
if (scheduler_->GetPlacement(node) == Scheduler::kFixed) {
|
||||
// Fixed nodes are always roots for schedule late.
|
||||
scheduler_->schedule_root_nodes_.push_back(node);
|
||||
@ -1029,8 +1029,6 @@ class PrepareUsesVisitor : public NullNodeVisitor {
|
||||
schedule_->AddNode(block, node);
|
||||
}
|
||||
}
|
||||
|
||||
return GenericGraphVisit::CONTINUE;
|
||||
}
|
||||
|
||||
void PostEdge(Node* from, int index, Node* to) {
|
||||
|
@ -251,44 +251,19 @@ class Typer::RunVisitor : public Typer::Visitor {
|
||||
: Visitor(typer),
|
||||
redo(NodeSet::key_compare(), NodeSet::allocator_type(typer->zone())) {}
|
||||
|
||||
GenericGraphVisit::Control Post(Node* node) {
|
||||
void Post(Node* node) {
|
||||
if (node->op()->ValueOutputCount() > 0) {
|
||||
Bounds bounds = TypeNode(node);
|
||||
NodeProperties::SetBounds(node, bounds);
|
||||
// Remember incompletely typed nodes for least fixpoint iteration.
|
||||
if (!NodeProperties::AllValueInputsAreTyped(node)) redo.insert(node);
|
||||
}
|
||||
return GenericGraphVisit::CONTINUE;
|
||||
}
|
||||
|
||||
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 {
|
||||
public:
|
||||
explicit WidenVisitor(Typer* typer)
|
||||
@ -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) {
|
||||
if (node->op()->ValueOutputCount() > 0) {
|
||||
// Only eagerly type-decorate nodes with known input types.
|
||||
|
@ -21,7 +21,6 @@ class Typer {
|
||||
~Typer();
|
||||
|
||||
void Run();
|
||||
void Narrow(Node* node);
|
||||
|
||||
Graph* graph() { return graph_; }
|
||||
MaybeHandle<Context> context() { return context_; }
|
||||
@ -31,7 +30,6 @@ class Typer {
|
||||
private:
|
||||
class Visitor;
|
||||
class RunVisitor;
|
||||
class NarrowVisitor;
|
||||
class WidenVisitor;
|
||||
class Decorator;
|
||||
|
||||
|
@ -52,7 +52,7 @@ class Verifier::Visitor : public NullNodeVisitor {
|
||||
Visitor(Zone* z, Typing typed) : zone(z), typing(typed) {}
|
||||
|
||||
// Fulfills the PreNodeCallback interface.
|
||||
GenericGraphVisit::Control Pre(Node* node);
|
||||
void Pre(Node* node);
|
||||
|
||||
Zone* zone;
|
||||
Typing typing;
|
||||
@ -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 context_count = OperatorProperties::GetContextInputCount(node->op());
|
||||
int frame_state_count =
|
||||
@ -728,8 +728,6 @@ GenericGraphVisit::Control Verifier::Visitor::Pre(Node* node) {
|
||||
// TODO(rossberg): Check.
|
||||
break;
|
||||
}
|
||||
|
||||
return GenericGraphVisit::CONTINUE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -23,10 +23,9 @@ static Operator dummy_operator(IrOpcode::kParameter, Operator::kNoWrite,
|
||||
|
||||
class PreNodeVisitor : public NullNodeVisitor {
|
||||
public:
|
||||
GenericGraphVisit::Control Pre(Node* node) {
|
||||
void Pre(Node* node) {
|
||||
printf("NODE ID: %d\n", node->id());
|
||||
nodes_.push_back(node);
|
||||
return GenericGraphVisit::CONTINUE;
|
||||
}
|
||||
std::vector<Node*> nodes_;
|
||||
};
|
||||
@ -34,10 +33,9 @@ class PreNodeVisitor : public NullNodeVisitor {
|
||||
|
||||
class PostNodeVisitor : public NullNodeVisitor {
|
||||
public:
|
||||
GenericGraphVisit::Control Post(Node* node) {
|
||||
void Post(Node* node) {
|
||||
printf("NODE ID: %d\n", node->id());
|
||||
nodes_.push_back(node);
|
||||
return GenericGraphVisit::CONTINUE;
|
||||
}
|
||||
std::vector<Node*> nodes_;
|
||||
};
|
||||
@ -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) {
|
||||
GraphWithStartNodeTester graph;
|
||||
Node* n2 = graph.NewNode(&dummy_operator, graph.start());
|
||||
|
Loading…
Reference in New Issue
Block a user