From 461f3c10041fe1f99a2f6880fe5d51a0ba29dee3 Mon Sep 17 00:00:00 2001 From: Geza Lore Date: Fri, 7 Oct 2022 16:13:54 +0100 Subject: [PATCH] DFG: Remove topological sort Cyclic components are now extracted separately, so there is no functional reason to have to do a topological sort (previously we used it to detect cyclic graphs). Removing it to gain some speed. --- src/V3Dfg.cpp | 71 ------------------------------------------ src/V3Dfg.h | 6 ---- src/V3DfgOptimizer.cpp | 3 -- 3 files changed, 80 deletions(-) diff --git a/src/V3Dfg.cpp b/src/V3Dfg.cpp index 9aac9209d..195bbbfaa 100644 --- a/src/V3Dfg.cpp +++ b/src/V3Dfg.cpp @@ -46,77 +46,6 @@ void DfgGraph::addGraph(DfgGraph& other) { }); } -bool DfgGraph::sortTopologically(bool reverse) { - // Vertices in reverse topological order - std::vector order; - - // Markings for algorithm - enum class Mark : uint8_t { Scheduled, OnPath, Finished }; - std::unordered_map marks; - - // Stack of nodes in depth first search. The second element of the pair is true if the vertex - // is on the current DFS path, and false if it's only scheduled for visitation. - std::vector> stack; - - // Schedule vertex for visitation - const auto scheudle = [&](DfgVertex& vtx) { - // Nothing to do if already finished - if (marks.emplace(&vtx, Mark::Scheduled).first->second == Mark::Finished) return; - // Otherwise scheule for visitation - stack.emplace_back(&vtx, false); - }; - - // For each vertex (direct loop, so we can return early) - for (DfgVertex* vtxp = m_vertices.begin(); vtxp; vtxp = vtxp->m_verticesEnt.nextp()) { - // Initiate DFS from this vertex - scheudle(*vtxp); - while (!stack.empty()) { - // Pick up stack top - const auto pair = stack.back(); - stack.pop_back(); - DfgVertex* const currp = pair.first; - const bool onPath = pair.second; - Mark& mark = marks.at(currp); - - if (onPath) { // Popped node on path - // Mark it as done - UASSERT_OBJ(mark == Mark::OnPath, currp, "DFS got lost"); - mark = Mark::Finished; - // Add to order - order.push_back(currp); - } else { // Otherwise node was scheduled for visitation, so visit it - // If already finished, then nothing to do - if (mark == Mark::Finished) continue; - // If already on path, then not a DAG - if (mark == Mark::OnPath) return false; - // Push to path and mark as such - mark = Mark::OnPath; - stack.emplace_back(currp, true); - // Schedule children - currp->forEachSink(scheudle); - } - } - } - - // Move given vertex to end of vertex list - const auto reinsert = [this](DfgVertex& vtx) { - // Remove from current location - removeVertex(vtx); - // 'addVertex' appends to the end of the vertex list, so can do this in one loop - addVertex(vtx); - }; - - // Remember 'order' is in reverse topological order - if (!reverse) { - for (DfgVertex* vtxp : vlstd::reverse_view(order)) reinsert(*vtxp); - } else { - for (DfgVertex* vtxp : order) reinsert(*vtxp); - } - - // Done - return true; -} - std::vector> DfgGraph::splitIntoComponents(std::string label) { size_t componentNumber = 0; std::unordered_map vertex2component; diff --git a/src/V3Dfg.h b/src/V3Dfg.h index d56ac6f85..822b192d1 100644 --- a/src/V3Dfg.h +++ b/src/V3Dfg.h @@ -179,12 +179,6 @@ public: // Add contents of other graph to this graph. Leaves other graph empty. void addGraph(DfgGraph& other); - // Topologically sort the list of vertices in this graph (such that 'forEachVertex' will - // iterate in topological order), or reverse topologically if the passed boolean argument is - // true. Returns true on success (the graph is acyclic and a topological order exists), false - // if the graph is cyclic. If the graph is cyclic, the vertex ordering is not modified. - bool sortTopologically(bool reverse = false); - // Split this graph into individual components (unique sub-graphs with no edges between them). // Leaves 'this' graph empty. std::vector> splitIntoComponents(std::string label); diff --git a/src/V3DfgOptimizer.cpp b/src/V3DfgOptimizer.cpp index a7cbde164..c2449d678 100644 --- a/src/V3DfgOptimizer.cpp +++ b/src/V3DfgOptimizer.cpp @@ -290,9 +290,6 @@ void V3DfgOptimizer::optimize(AstNetlist* netlistp, const string& label) { // For each acyclic component for (auto& component : acyclicComponents) { if (dumpDfg() >= 7) component->dumpDotFilePrefixed(ctx.prefix() + "source"); - // Reverse topologically sort the component - const bool acyclic = component->sortTopologically(/* reverse: */ true); - UASSERT_OBJ(acyclic, nodep, "Supposedly acyclic graph is cyclic"); // Optimize the component V3DfgPasses::optimize(*component, ctx); // Add back under the main DFG (we will convert everything back in one go)