forked from github/verilator
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.
This commit is contained in:
parent
90447d54d1
commit
461f3c1004
@ -46,77 +46,6 @@ void DfgGraph::addGraph(DfgGraph& other) {
|
||||
});
|
||||
}
|
||||
|
||||
bool DfgGraph::sortTopologically(bool reverse) {
|
||||
// Vertices in reverse topological order
|
||||
std::vector<DfgVertex*> order;
|
||||
|
||||
// Markings for algorithm
|
||||
enum class Mark : uint8_t { Scheduled, OnPath, Finished };
|
||||
std::unordered_map<DfgVertex*, Mark> 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<std::pair<DfgVertex*, bool>> 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<std::unique_ptr<DfgGraph>> DfgGraph::splitIntoComponents(std::string label) {
|
||||
size_t componentNumber = 0;
|
||||
std::unordered_map<const DfgVertex*, unsigned> vertex2component;
|
||||
|
@ -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<std::unique_ptr<DfgGraph>> splitIntoComponents(std::string label);
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user