Internals: Refactor Ast to Dfg conversion for reusability. (#6276)
This is mainly code motion, with minimal algorithmic changes to facilitate reusing parts in future code. No functional change intended.
This commit is contained in:
parent
d1f851e1e1
commit
16d32cdd4a
File diff suppressed because it is too large
Load Diff
|
|
@ -171,7 +171,7 @@ public:
|
|||
|
||||
private:
|
||||
V3DfgDfgToAstContext(V3DfgContext& ctx, const std::string& label)
|
||||
: V3DfgSubContext{ctx, label, "Dfg2Ast"} {}
|
||||
: V3DfgSubContext{ctx, label, "DfgToAst"} {}
|
||||
~V3DfgDfgToAstContext() { addStat("result equations", m_resultEquations); }
|
||||
};
|
||||
class V3DfgEliminateVarsContext final : public V3DfgSubContext {
|
||||
|
|
|
|||
|
|
@ -262,7 +262,7 @@ class DataflowOptimize final {
|
|||
|
||||
// Attempt to convert cyclic components into acyclic ones
|
||||
std::vector<std::unique_ptr<DfgGraph>> madeAcyclicComponents;
|
||||
if (v3Global.opt.fDfgBreakCyckes()) {
|
||||
if (v3Global.opt.fDfgBreakCycles()) {
|
||||
for (auto it = cyclicComponents.begin(); it != cyclicComponents.end();) {
|
||||
auto result = V3DfgPasses::breakCycles(**it, m_ctx);
|
||||
if (!result.first) {
|
||||
|
|
@ -335,7 +335,7 @@ class DataflowOptimize final {
|
|||
UINFO(4, "Applying DFG optimization to module '" << modp->name() << "'");
|
||||
++m_ctx.m_modules;
|
||||
// Build the DFG of this module or netlist
|
||||
const std::unique_ptr<DfgGraph> dfgp{V3DfgPasses::astToDfg(*modp, m_ctx)};
|
||||
const std::unique_ptr<DfgGraph> dfgp = V3DfgPasses::astToDfg(*modp, m_ctx);
|
||||
// Actually process the graph
|
||||
optimize(*dfgp);
|
||||
// Convert back to Ast
|
||||
|
|
@ -345,7 +345,7 @@ class DataflowOptimize final {
|
|||
// Post V3Scope application. Run on whole netlist.
|
||||
UINFO(4, "Applying DFG optimization to entire netlist");
|
||||
// Build the DFG of the entire netlist
|
||||
const std::unique_ptr<DfgGraph> dfgp{V3DfgPasses::astToDfg(*netlistp, m_ctx)};
|
||||
const std::unique_ptr<DfgGraph> dfgp = V3DfgPasses::astToDfg(*netlistp, m_ctx);
|
||||
// Actually process the graph
|
||||
optimize(*dfgp);
|
||||
// Convert back to Ast
|
||||
|
|
|
|||
|
|
@ -139,6 +139,11 @@ void V3DfgPasses::removeUnused(DfgGraph& dfg) {
|
|||
vtxp->unlinkDelete(dfg);
|
||||
}
|
||||
|
||||
// Remove unused and undriven variable vertices
|
||||
for (DfgVertexVar* const vtxp : dfg.varVertices().unlinkable()) {
|
||||
if (!vtxp->hasSinks() && !vtxp->srcp()) VL_DO_DANGLING(vtxp->unlinkDelete(dfg), vtxp);
|
||||
}
|
||||
|
||||
// Finally remove unused constants
|
||||
for (DfgConst* const vtxp : dfg.constVertices().unlinkable()) {
|
||||
if (!vtxp->hasSinks()) VL_DO_DANGLING(vtxp->unlinkDelete(dfg), vtxp);
|
||||
|
|
|
|||
|
|
@ -33,10 +33,10 @@ namespace V3DfgPasses {
|
|||
// Construct a DfGGraph representing the combinational logic in the given AstModule. The logic
|
||||
// that is represented by the graph is removed from the given AstModule. Returns the
|
||||
// constructed DfgGraph.
|
||||
DfgGraph* astToDfg(AstModule&, V3DfgContext&) VL_MT_DISABLED;
|
||||
std::unique_ptr<DfgGraph> astToDfg(AstModule&, V3DfgContext&) VL_MT_DISABLED;
|
||||
|
||||
// Same as above, but for the entire netlist, after V3Scope
|
||||
DfgGraph* astToDfg(AstNetlist&, V3DfgContext&) VL_MT_DISABLED;
|
||||
std::unique_ptr<DfgGraph> astToDfg(AstNetlist&, V3DfgContext&) VL_MT_DISABLED;
|
||||
|
||||
// Attempt to make the given cyclic graph into an acyclic, or "less cyclic"
|
||||
// equivalent. If the returned pointer is null, then no improvement was
|
||||
|
|
|
|||
|
|
@ -736,7 +736,7 @@ public:
|
|||
bool fConstBitOpTree() const { return m_fConstBitOpTree; }
|
||||
bool fConstEager() const { return m_fConstEager; }
|
||||
bool fDedupe() const { return m_fDedupe; }
|
||||
bool fDfgBreakCyckes() const { return m_fDfgBreakCycles; }
|
||||
bool fDfgBreakCycles() const { return m_fDfgBreakCycles; }
|
||||
bool fDfgPeephole() const { return m_fDfgPeephole; }
|
||||
bool fDfgPreInline() const { return m_fDfgPreInline; }
|
||||
bool fDfgPostInline() const { return m_fDfgPostInline; }
|
||||
|
|
|
|||
|
|
@ -1250,6 +1250,9 @@ def write_dfg_ast_to_dfg(filename):
|
|||
continue
|
||||
|
||||
fh.write("void visit(Ast{t}* nodep) override {{\n".format(t=node.name))
|
||||
fh.write(
|
||||
' UASSERT_OBJ(m_converting, nodep, "AstToDfg visit called without m_converting");\n'
|
||||
)
|
||||
fh.write(' UASSERT_OBJ(!nodep->user2p(), nodep, "Already has Dfg vertex");\n\n')
|
||||
fh.write(" if (unhandled(nodep)) return;\n\n")
|
||||
for i in range(node.arity):
|
||||
|
|
@ -1259,8 +1262,8 @@ def write_dfg_ast_to_dfg(filename):
|
|||
' UASSERT_OBJ(nodep->op{j}p()->user2p(), nodep, "Child {j} missing Dfg vertex");\n'
|
||||
.format(j=i + 1))
|
||||
fh.write("\n")
|
||||
fh.write(" Dfg{t}* const vtxp = makeVertex<Dfg{t}>(nodep, *m_dfgp);\n".format(
|
||||
t=node.name))
|
||||
fh.write(
|
||||
" Dfg{t}* const vtxp = makeVertex<Dfg{t}>(nodep, m_dfg);\n".format(t=node.name))
|
||||
fh.write(" if (!vtxp) {\n")
|
||||
fh.write(" m_foundUnhandled = true;\n")
|
||||
fh.write(" ++m_ctx.m_nonRepNode;\n")
|
||||
|
|
@ -1271,7 +1274,6 @@ def write_dfg_ast_to_dfg(filename):
|
|||
" vtxp->relinkSource<{i}>(nodep->op{j}p()->user2u().to<DfgVertex*>());\n".
|
||||
format(i=i, j=i + 1))
|
||||
fh.write("\n")
|
||||
fh.write(" m_uncommittedVertices.push_back(vtxp);\n")
|
||||
fh.write(" nodep->user2p(vtxp);\n")
|
||||
fh.write("}\n")
|
||||
|
||||
|
|
|
|||
|
|
@ -50,15 +50,15 @@
|
|||
t/t_dfg_multidriver_dfg_bad.v:31:14: ... Location of first driver
|
||||
31 | assign v = j;
|
||||
| ^
|
||||
t/t_dfg_multidriver_dfg_bad.v:32:17: ... Location of other driver
|
||||
t/t_dfg_multidriver_dfg_bad.v:32:13: ... Location of other driver
|
||||
32 | assign v[1] = i;
|
||||
| ^
|
||||
| ^
|
||||
t/t_dfg_multidriver_dfg_bad.v:30:18: ... Only the first driver will be respected
|
||||
%Warning-MULTIDRIVEN: t/t_dfg_multidriver_dfg_bad.v:34:18: Elements [0:0] of signal 'w' have multiple combinational drivers
|
||||
: ... note: In instance 't'
|
||||
t/t_dfg_multidriver_dfg_bad.v:35:17: ... Location of first driver
|
||||
t/t_dfg_multidriver_dfg_bad.v:35:13: ... Location of first driver
|
||||
35 | assign w[0] = i;
|
||||
| ^
|
||||
| ^
|
||||
t/t_dfg_multidriver_dfg_bad.v:36:14: ... Location of other driver
|
||||
36 | assign w = j;
|
||||
| ^
|
||||
|
|
|
|||
Loading…
Reference in New Issue