// Sort the nodes in topological order. int CompilationGraph::TopologicalSort(std::vector<const Node*>& Out) { std::queue<const Node*> Q; Node* Root = getNode("root"); if (Root == 0) return 1; Q.push(Root); while (!Q.empty()) { const Node* A = Q.front(); Q.pop(); Out.push_back(A); for (Node::const_iterator EB = A->EdgesBegin(), EE = A->EdgesEnd(); EB != EE; ++EB) { Node* B = getNode((*EB)->ToolName()); if (B == 0) return 1; B->DecrInEdges(); if (B->HasNoInEdges()) Q.push(B); } } return 0; }
int CompilationGraph::CheckCycles() { unsigned deleted = 0; std::queue<Node*> Q; Node* Root = getNode("root"); if (Root == 0) return 1; Q.push(Root); // Try to delete all nodes that have no ingoing edges, starting from the // root. If there are any nodes left after this operation, then we have a // cycle. This relies on '--check-graph' not performing the topological sort. while (!Q.empty()) { Node* A = Q.front(); Q.pop(); ++deleted; for (Node::iterator EB = A->EdgesBegin(), EE = A->EdgesEnd(); EB != EE; ++EB) { Node* B = getNode((*EB)->ToolName()); if (B == 0) return 1; B->DecrInEdges(); if (B->HasNoInEdges()) Q.push(B); } } if (deleted != NodesMap.size()) { errs() << "Error: there are cycles in the compilation graph!\n" << "Try inspecting the diagram produced by " << "'llvmc --view-graph'.\n\n"; return 1; } return 0; }