Internals: Cleanup some V3Graph constructors/funcs and docs. No functional change.

This commit is contained in:
Wilson Snyder 2023-10-28 20:11:28 -04:00
parent e708670f9a
commit 7ba6647c4f
11 changed files with 50 additions and 32 deletions

View File

@ -1119,5 +1119,5 @@ void EmitCSyms::emitDpiImp() {
void V3EmitC::emitcSyms(bool dpiHdrOnly) { void V3EmitC::emitcSyms(bool dpiHdrOnly) {
UINFO(2, __FUNCTION__ << ": " << endl); UINFO(2, __FUNCTION__ << ": " << endl);
EmitCSyms(v3Global.rootp(), dpiHdrOnly); EmitCSyms{v3Global.rootp(), dpiHdrOnly};
} }

View File

@ -266,7 +266,7 @@ void V3Graph::loopsVertexCb(V3GraphVertex* vertexp) {
if (debug()) std::cerr << "-Info-Loop: " << cvtToHex(vertexp) << " " << vertexp << endl; if (debug()) std::cerr << "-Info-Loop: " << cvtToHex(vertexp) << " " << vertexp << endl;
} }
void V3Graph::dump(std::ostream& os) { void V3Graph::dump(std::ostream& os) const {
// This generates a file used by graphviz, https://www.graphviz.org // This generates a file used by graphviz, https://www.graphviz.org
os << " Graph:\n"; os << " Graph:\n";
// Print vertices // Print vertices
@ -284,7 +284,8 @@ void V3Graph::dump(std::ostream& os) {
} }
} }
void V3Graph::dumpEdge(std::ostream& os, const V3GraphVertex* vertexp, const V3GraphEdge* edgep) { void V3Graph::dumpEdge(std::ostream& os, const V3GraphVertex* vertexp,
const V3GraphEdge* edgep) const {
if (edgep->weight() && (edgep->fromp() == vertexp || edgep->top() == vertexp)) { if (edgep->weight() && (edgep->fromp() == vertexp || edgep->top() == vertexp)) {
os << "\t\t"; os << "\t\t";
if (edgep->fromp() == vertexp) os << "-> " << edgep->top()->name(); if (edgep->fromp() == vertexp) os << "-> " << edgep->top()->name();

View File

@ -91,7 +91,7 @@ protected:
// METHODS // METHODS
double orderDFSIterate(V3GraphVertex* vertexp) VL_MT_DISABLED; double orderDFSIterate(V3GraphVertex* vertexp) VL_MT_DISABLED;
void dumpEdge(std::ostream& os, const V3GraphVertex* vertexp, void dumpEdge(std::ostream& os, const V3GraphVertex* vertexp,
const V3GraphEdge* edgep) VL_MT_DISABLED; const V3GraphEdge* edgep) const VL_MT_DISABLED;
void verticesUnlink() { m_vertices.reset(); } void verticesUnlink() { m_vertices.reset(); }
// ACCESSORS // ACCESSORS
@ -102,13 +102,14 @@ public:
// METHODS // METHODS
void clear() VL_MT_DISABLED; // Empty it of all vertices/edges, as if making a new object void clear() VL_MT_DISABLED; // Empty it of all vertices/edges, as if making a new object
void clearColors() VL_MT_DISABLED;
bool empty() const { return m_vertices.empty(); } bool empty() const { return m_vertices.empty(); }
V3GraphVertex* verticesBeginp() const { return m_vertices.begin(); } V3GraphVertex* verticesBeginp() const { return m_vertices.begin(); }
// METHODS - ALGORITHMS // METHODS - ALGORITHMS
/// Clears color
void clearColors() VL_MT_DISABLED;
/// Assign same color to all vertices in the same weakly connected component /// Assign same color to all vertices in the same weakly connected component
/// Thus different color if there's no edges between the two subgraphs /// Thus different color if there's no edges between the two subgraphs
void weaklyConnected(V3EdgeFuncP edgeFuncp) VL_MT_DISABLED; void weaklyConnected(V3EdgeFuncP edgeFuncp) VL_MT_DISABLED;
@ -116,10 +117,12 @@ public:
/// Assign same color to all vertices that are strongly connected /// Assign same color to all vertices that are strongly connected
/// Thus different color if there's no directional circuit within the subgraphs. /// Thus different color if there's no directional circuit within the subgraphs.
/// (I.E. all loops will occur within each color, not between them.) /// (I.E. all loops will occur within each color, not between them.)
/// Side-effect: changes user()
void stronglyConnected(V3EdgeFuncP edgeFuncp) VL_MT_DISABLED; void stronglyConnected(V3EdgeFuncP edgeFuncp) VL_MT_DISABLED;
/// Assign an ordering number to all vertexes in a tree. /// Assign an ordering number to all vertexes in a tree.
/// All nodes with no inputs will get rank 1 /// All nodes with no inputs will get rank 1
/// Side-effect: changes user()
void rank(V3EdgeFuncP edgeFuncp) VL_MT_DISABLED; void rank(V3EdgeFuncP edgeFuncp) VL_MT_DISABLED;
void rank() VL_MT_DISABLED; void rank() VL_MT_DISABLED;
@ -131,20 +134,24 @@ public:
/// Order all vertices by rank and fanout, lowest first /// Order all vertices by rank and fanout, lowest first
/// Sort all vertices by rank and fanout, lowest first /// Sort all vertices by rank and fanout, lowest first
/// Sort all edges by weight, lowest first /// Sort all edges by weight, lowest first
/// Side-effect: assigns ranks to every node. /// Side-effect: assigns ranks to every node, and changes user()
void order() VL_MT_DISABLED; void order() VL_MT_DISABLED;
// Similar to order() but does not assign ranks. Caller must /// Similar to order() but does not assign ranks. Caller must
// ensure that the graph has been ranked ahead of the call. /// ensure that the graph has been ranked ahead of the call.
/// Side-effect: assigns ranks to every node, and changes user()
void orderPreRanked() VL_MT_DISABLED; void orderPreRanked() VL_MT_DISABLED;
/// Make acyclical (into a tree) by breaking a minimal subset of cutable edges. /// Make acyclical (into a tree) by breaking a minimal subset of cutable edges.
/// Side-effect: changes rank(), changes user()
void acyclic(V3EdgeFuncP edgeFuncp) VL_MT_DISABLED; void acyclic(V3EdgeFuncP edgeFuncp) VL_MT_DISABLED;
/// Remove any redundant edges, weights become MAX of any other weight /// Remove any redundant edges, weights become MAX of any other weight
void removeRedundantEdges(V3EdgeFuncP edgeFuncp) VL_MT_DISABLED; /// Side-effect: changes user()
void removeRedundantEdgesMax(V3EdgeFuncP edgeFuncp) VL_MT_DISABLED;
/// Remove any redundant edges, weights become SUM of any other weight /// Remove any redundant edges, weights become SUM of any other weight
/// Side-effect: changes user()
void removeRedundantEdgesSum(V3EdgeFuncP edgeFuncp) VL_MT_DISABLED; void removeRedundantEdgesSum(V3EdgeFuncP edgeFuncp) VL_MT_DISABLED;
/// Remove any transitive edges. E.g. if have edges A->B, B->C, and A->C /// Remove any transitive edges. E.g. if have edges A->B, B->C, and A->C
@ -154,21 +161,25 @@ public:
void removeTransitiveEdges() VL_MT_DISABLED; void removeTransitiveEdges() VL_MT_DISABLED;
/// Call loopsVertexCb on any one loop starting where specified /// Call loopsVertexCb on any one loop starting where specified
/// Side-effect: changes user()
void reportLoops(V3EdgeFuncP edgeFuncp, V3GraphVertex* vertexp) VL_MT_DISABLED; void reportLoops(V3EdgeFuncP edgeFuncp, V3GraphVertex* vertexp) VL_MT_DISABLED;
/// Build a subgraph of all loops starting where specified /// Build a subgraph of all loops starting where specified
/// Side-effect: changes user()
void subtreeLoops(V3EdgeFuncP edgeFuncp, V3GraphVertex* vertexp, void subtreeLoops(V3EdgeFuncP edgeFuncp, V3GraphVertex* vertexp,
V3Graph* loopGraphp) VL_MT_DISABLED; V3Graph* loopGraphp) VL_MT_DISABLED;
/// Clear user()
void userClearVertices() VL_MT_DISABLED;
void userClearEdges() VL_MT_DISABLED;
/// Debugging /// Debugging
void dump(std::ostream& os = std::cout) VL_MT_DISABLED; void dump(std::ostream& os = std::cout) const VL_MT_DISABLED;
void dumpDotFile(const string& filename, bool colorAsSubgraph) const VL_MT_DISABLED; void dumpDotFile(const string& filename, bool colorAsSubgraph) const VL_MT_DISABLED;
void dumpDotFilePrefixed(const string& nameComment, void dumpDotFilePrefixed(const string& nameComment,
bool colorAsSubgraph = false) const VL_MT_DISABLED; bool colorAsSubgraph = false) const VL_MT_DISABLED;
void dumpDotFilePrefixedAlways(const string& nameComment, void dumpDotFilePrefixedAlways(const string& nameComment,
bool colorAsSubgraph = false) const VL_MT_DISABLED; bool colorAsSubgraph = false) const VL_MT_DISABLED;
void userClearVertices() VL_MT_DISABLED;
void userClearEdges() VL_MT_DISABLED;
static void selfTest() VL_MT_DISABLED; static void selfTest() VL_MT_DISABLED;
// CALLBACKS // CALLBACKS

View File

@ -574,7 +574,7 @@ void GraphAcyc::main() {
void V3Graph::acyclic(V3EdgeFuncP edgeFuncp) { void V3Graph::acyclic(V3EdgeFuncP edgeFuncp) {
UINFO(4, "Acyclic\n"); UINFO(4, "Acyclic\n");
GraphAcyc acyc(this, edgeFuncp); GraphAcyc acyc{this, edgeFuncp};
acyc.main(); acyc.main();
UINFO(4, "Acyclic done\n"); UINFO(4, "Acyclic done\n");
} }

View File

@ -34,6 +34,7 @@ VL_DEFINE_DEBUG_FUNCTIONS;
//###################################################################### //######################################################################
//###################################################################### //######################################################################
// Algorithms - Remove redundancies // Algorithms - Remove redundancies
// Changes user() and weight()
class GraphRemoveRedundant final : GraphAlg<> { class GraphRemoveRedundant final : GraphAlg<> {
const bool m_sumWeights; ///< Sum, rather then maximize weights const bool m_sumWeights; ///< Sum, rather then maximize weights
@ -92,11 +93,11 @@ public:
~GraphRemoveRedundant() = default; ~GraphRemoveRedundant() = default;
}; };
void V3Graph::removeRedundantEdges(V3EdgeFuncP edgeFuncp) { void V3Graph::removeRedundantEdgesMax(V3EdgeFuncP edgeFuncp) {
GraphRemoveRedundant(this, edgeFuncp, false); GraphRemoveRedundant{this, edgeFuncp, false};
} }
void V3Graph::removeRedundantEdgesSum(V3EdgeFuncP edgeFuncp) { void V3Graph::removeRedundantEdgesSum(V3EdgeFuncP edgeFuncp) {
GraphRemoveRedundant(this, edgeFuncp, true); GraphRemoveRedundant{this, edgeFuncp, true};
} }
//###################################################################### //######################################################################
@ -132,6 +133,7 @@ void V3Graph::removeTransitiveEdges() { GraphAlgRemoveTransitiveEdges{this}.go()
//###################################################################### //######################################################################
//###################################################################### //######################################################################
// Algorithms - weakly connected components // Algorithms - weakly connected components
// Changes color()
class GraphAlgWeakly final : GraphAlg<> { class GraphAlgWeakly final : GraphAlg<> {
private: private:
@ -173,6 +175,7 @@ void V3Graph::weaklyConnected(V3EdgeFuncP edgeFuncp) { GraphAlgWeakly{this, edge
//###################################################################### //######################################################################
//###################################################################### //######################################################################
// Algorithms - strongly connected components // Algorithms - strongly connected components
// Changes user() and color()
class GraphAlgStrongly final : GraphAlg<> { class GraphAlgStrongly final : GraphAlg<> {
private: private:
@ -263,6 +266,7 @@ void V3Graph::stronglyConnected(V3EdgeFuncP edgeFuncp) { GraphAlgStrongly{this,
//###################################################################### //######################################################################
//###################################################################### //######################################################################
// Algorithms - ranking // Algorithms - ranking
// Changes user() and rank()
class GraphAlgRank final : GraphAlg<> { class GraphAlgRank final : GraphAlg<> {
private: private:
@ -317,7 +321,8 @@ void V3Graph::rank(V3EdgeFuncP edgeFuncp) { GraphAlgRank{this, edgeFuncp}; }
//###################################################################### //######################################################################
//###################################################################### //######################################################################
// Algorithms - ranking // Algorithms - report loops
// Changes user()
class GraphAlgRLoops final : GraphAlg<> { class GraphAlgRLoops final : GraphAlg<> {
private: private:
@ -365,12 +370,13 @@ public:
}; };
void V3Graph::reportLoops(V3EdgeFuncP edgeFuncp, V3GraphVertex* vertexp) { void V3Graph::reportLoops(V3EdgeFuncP edgeFuncp, V3GraphVertex* vertexp) {
GraphAlgRLoops(this, edgeFuncp, vertexp); GraphAlgRLoops{this, edgeFuncp, vertexp};
} }
//###################################################################### //######################################################################
//###################################################################### //######################################################################
// Algorithms - subtrees // Algorithms - subtrees
// Changes user()
class GraphAlgSubtrees final : GraphAlg<> { class GraphAlgSubtrees final : GraphAlg<> {
private: private:
@ -414,7 +420,7 @@ public:
//! Report the entire connected graph with a loop or loops //! Report the entire connected graph with a loop or loops
void V3Graph::subtreeLoops(V3EdgeFuncP edgeFuncp, V3GraphVertex* vertexp, V3Graph* loopGraphp) { void V3Graph::subtreeLoops(V3EdgeFuncP edgeFuncp, V3GraphVertex* vertexp, V3Graph* loopGraphp) {
GraphAlgSubtrees(this, loopGraphp, edgeFuncp, vertexp); GraphAlgSubtrees{this, loopGraphp, edgeFuncp, vertexp};
} }
//###################################################################### //######################################################################

View File

@ -164,7 +164,7 @@ private:
readModNames(); readModNames();
iterateChildren(nodep); iterateChildren(nodep);
// Find levels in graph // Find levels in graph
m_graph.removeRedundantEdges(&V3GraphEdge::followAlwaysTrue); m_graph.removeRedundantEdgesMax(&V3GraphEdge::followAlwaysTrue);
if (dumpGraphLevel()) m_graph.dumpDotFilePrefixed("linkcells"); if (dumpGraphLevel()) m_graph.dumpDotFilePrefixed("linkcells");
m_graph.rank(); m_graph.rank();
for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp = itp->verticesNextp()) { for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp = itp->verticesNextp()) {

View File

@ -3749,7 +3749,7 @@ void V3LinkDot::linkDotGuts(AstNetlist* rootp, VLinkDotStep step) {
if (debug() >= 5 || dumpTreeLevel() >= 9) { if (debug() >= 5 || dumpTreeLevel() >= 9) {
v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("prelinkdot.tree")); v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("prelinkdot.tree"));
} }
LinkDotState state(rootp, step); LinkDotState state{rootp, step};
const LinkDotFindVisitor visitor{rootp, &state}; const LinkDotFindVisitor visitor{rootp, &state};
if (debug() >= 5 || dumpTreeLevel() >= 9) { if (debug() >= 5 || dumpTreeLevel() >= 9) {
v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("prelinkdot-find.tree")); v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("prelinkdot-find.tree"));

View File

@ -1291,12 +1291,12 @@ void OrderProcess::processMTasks() {
mtask_pmbg.build(); mtask_pmbg.build();
// Needed? We do this for m_pomGraph in serial mode, so do it here too: // Needed? We do this for m_pomGraph in serial mode, so do it here too:
logicGraph.removeRedundantEdges(&V3GraphEdge::followAlwaysTrue); logicGraph.removeRedundantEdgesMax(&V3GraphEdge::followAlwaysTrue);
// Partition logicGraph into LogicMTask's. The partitioner will annotate // Partition logicGraph into LogicMTask's. The partitioner will annotate
// each vertex in logicGraph with a 'color' which is really an mtask ID // each vertex in logicGraph with a 'color' which is really an mtask ID
// in this context. // in this context.
V3Partition partitioner(&m_graph, &logicGraph); V3Partition partitioner{&m_graph, &logicGraph};
V3Graph mtasks; V3Graph mtasks;
partitioner.go(&mtasks); partitioner.go(&mtasks);
@ -1307,7 +1307,7 @@ void OrderProcess::processMTasks() {
// This is the order we'll execute logic nodes within the MTask. // This is the order we'll execute logic nodes within the MTask.
// //
// MTasks may span scopes and domains, so sort by both here: // MTasks may span scopes and domains, so sort by both here:
GraphStream<OrderVerticesByDomainThenScope> emit_logic(&logicGraph); GraphStream<OrderVerticesByDomainThenScope> emit_logic{&logicGraph};
const V3GraphVertex* moveVxp; const V3GraphVertex* moveVxp;
while ((moveVxp = emit_logic.nextp())) { while ((moveVxp = emit_logic.nextp())) {
const MTaskMoveVertex* const movep = static_cast<const MTaskMoveVertex*>(moveVxp); const MTaskMoveVertex* const movep = static_cast<const MTaskMoveVertex*>(moveVxp);
@ -1435,7 +1435,7 @@ void OrderProcess::process(bool multiThreaded) {
processMoveBuildGraph(); processMoveBuildGraph();
// Different prefix (ordermv) as it's not the same graph // Different prefix (ordermv) as it's not the same graph
if (dumpGraphLevel() >= 4) m_pomGraph.dumpDotFilePrefixed(m_tag + "_ordermv_start"); if (dumpGraphLevel() >= 4) m_pomGraph.dumpDotFilePrefixed(m_tag + "_ordermv_start");
m_pomGraph.removeRedundantEdges(&V3GraphEdge::followAlwaysTrue); m_pomGraph.removeRedundantEdgesMax(&V3GraphEdge::followAlwaysTrue);
if (dumpGraphLevel() >= 4) m_pomGraph.dumpDotFilePrefixed(m_tag + "_ordermv_simpl"); if (dumpGraphLevel() >= 4) m_pomGraph.dumpDotFilePrefixed(m_tag + "_ordermv_simpl");
UINFO(2, " Move...\n"); UINFO(2, " Move...\n");

View File

@ -2586,7 +2586,7 @@ void V3Partition::debugMTaskGraphStats(const V3Graph* graphp, const string& stag
// Look only at the cost of each mtask, neglect communication cost. // Look only at the cost of each mtask, neglect communication cost.
// This will show us how much parallelism we expect, assuming cache-miss // This will show us how much parallelism we expect, assuming cache-miss
// costs are minor and the cost of running logic is the dominant cost. // costs are minor and the cost of running logic is the dominant cost.
PartParallelismEst vertexParEst(graphp); PartParallelismEst vertexParEst{graphp};
vertexParEst.traverse(); vertexParEst.traverse();
vertexParEst.statsReport(stage); vertexParEst.statsReport(stage);
if (debug() >= 4) { if (debug() >= 4) {
@ -3047,7 +3047,7 @@ static void finalizeCosts(V3Graph* execMTaskGraphp) {
// Record summary stats for final m_tasks graph. // Record summary stats for final m_tasks graph.
// (More verbose stats are available with --debugi-V3Partition >= 3.) // (More verbose stats are available with --debugi-V3Partition >= 3.)
PartParallelismEst parEst(execMTaskGraphp); PartParallelismEst parEst{execMTaskGraphp};
parEst.traverse(); parEst.traverse();
parEst.statsReport("final"); parEst.statsReport("final");
if (debug() >= 3) { if (debug() >= 3) {

View File

@ -456,7 +456,7 @@ protected:
void cleanupBlockGraph(AstNode* nodep) { void cleanupBlockGraph(AstNode* nodep) {
// Transform the graph into what we need // Transform the graph into what we need
UINFO(5, "ReorderBlock " << nodep << endl); UINFO(5, "ReorderBlock " << nodep << endl);
m_graph.removeRedundantEdges(&V3GraphEdge::followAlwaysTrue); m_graph.removeRedundantEdgesMax(&V3GraphEdge::followAlwaysTrue);
if (dumpGraphLevel() >= 9) m_graph.dumpDotFilePrefixed("reorderg_nodup", false); if (dumpGraphLevel() >= 9) m_graph.dumpDotFilePrefixed("reorderg_nodup", false);
@ -893,7 +893,7 @@ protected:
void colorAlwaysGraph() { void colorAlwaysGraph() {
// Color the graph to indicate subsets, each of which // Color the graph to indicate subsets, each of which
// we can split into its own always block. // we can split into its own always block.
m_graph.removeRedundantEdges(&V3GraphEdge::followAlwaysTrue); m_graph.removeRedundantEdgesMax(&V3GraphEdge::followAlwaysTrue);
// Some vars are primary inputs to the always block; prune // Some vars are primary inputs to the always block; prune
// edges on those vars. Reasoning: if two statements both depend // edges on those vars. Reasoning: if two statements both depend

View File

@ -254,7 +254,7 @@ private:
// Remove multiple variables connecting funcs to traces // Remove multiple variables connecting funcs to traces
// We do this twice, as then we have fewer edges to multiply out in the below // We do this twice, as then we have fewer edges to multiply out in the below
// expansion. // expansion.
m_graph.removeRedundantEdges(&V3GraphEdge::followAlwaysTrue); m_graph.removeRedundantEdgesMax(&V3GraphEdge::followAlwaysTrue);
// Remove all Cfunc nodes // Remove all Cfunc nodes
for (V3GraphVertex *nextp, *itp = m_graph.verticesBeginp(); itp; itp = nextp) { for (V3GraphVertex *nextp, *itp = m_graph.verticesBeginp(); itp; itp = nextp) {
nextp = itp->verticesNextp(); nextp = itp->verticesNextp();
@ -266,7 +266,7 @@ private:
} }
// Remove multiple variables connecting funcs to traces // Remove multiple variables connecting funcs to traces
m_graph.removeRedundantEdges(&V3GraphEdge::followAlwaysTrue); m_graph.removeRedundantEdgesMax(&V3GraphEdge::followAlwaysTrue);
// If there are any edges from a always, keep only the always // If there are any edges from a always, keep only the always
for (const V3GraphVertex* itp = m_graph.verticesBeginp(); itp; for (const V3GraphVertex* itp = m_graph.verticesBeginp(); itp;