Optimize more always blocks in Dfg (#7775)

Optimize always blocks that:
- drive an unused variable (so logic can be pruned)
- write only a single variable (regardless of CFG size)
This commit is contained in:
Geza Lore 2026-07-05 09:24:01 +01:00 committed by GitHub
parent 1bab793c75
commit 2285e5b6da
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 17 additions and 5 deletions

View File

@ -78,7 +78,13 @@ void V3DfgPasses::removeUnobservable(DfgGraph& dfg, V3DfgContext& dfgCtx) {
&& !vVtxp->hasExtWrRefs() //
&& !vVtxp->hasModWrRefs();
VL_DO_DANGLING(vVtxp->unlinkDelete(dfg), vVtxp);
if (srcp) VL_DO_DANGLING(srcp->unlinkDelete(dfg), srcp);
if (srcp) {
srcp->foreachSource([&](DfgVertex& src) {
src.as<DfgLogic>()->setDrivesUnusedVars();
return false;
});
VL_DO_DANGLING(srcp->unlinkDelete(dfg), srcp);
}
if (delAst) {
VL_DO_DANGLING(vscp->unlinkFrBack()->deleteTree(), vscp);
++ctx.m_varsDeleted;

View File

@ -2005,6 +2005,11 @@ static void dfgSelectLogicForSynthesis(DfgGraph& dfg) {
for (DfgVertex& vtx : dfg.opVertices()) {
DfgLogic* const logicp = vtx.cast<DfgLogic>();
if (!logicp) continue;
// If drives an unused variable, synthesize it so the partial logic can be removed
if (logicp->drivesUnusedVars()) {
worklist.push_front(*logicp);
continue;
}
// Blocks corresponding to continuous assignments
if (logicp->nodep()->keyword() == VAlwaysKwd::CONT_ASSIGN) {
worklist.push_front(*logicp);
@ -2016,10 +2021,8 @@ static void dfgSelectLogicForSynthesis(DfgGraph& dfg) {
worklist.push_front(*logicp);
continue;
}
// Simple blocks driving exactly 1 variable, e.g if (rst) a = b else a = c;
if (!logicp->hasMultipleSinks() && cfg.nBlocks() <= 4 && cfg.nEdges() <= 4) {
worklist.push_front(*logicp);
}
// Blocks driving exactly 1 variable
if (!logicp->hasMultipleSinks()) worklist.push_front(*logicp);
}
// Now expand to cover all logic driving the same set of variables and mark

View File

@ -512,6 +512,7 @@ class DfgLogic final : public DfgVertexVariadic {
AstScope* const m_scopep; // The AstScope m_nodep is under, iff scoped
const std::unique_ptr<CfgGraph> m_cfgp;
std::vector<DfgVertex*> m_synth; // Vertices this logic was synthesized into
bool m_drivesUnusedVars = false; // Logic drives unused variables
bool m_selectedForSynthesis = false; // Logic selected for synthesis
bool m_nonSynthesizable = false; // Logic is not synthesizeable (by DfgSynthesis)
bool m_reverted = false; // Logic was synthesized (in part if non-synthesizable) then reverted
@ -538,6 +539,8 @@ public:
const CfgGraph& cfg() const { return *m_cfgp; }
std::vector<DfgVertex*>& synth() { return m_synth; }
const std::vector<DfgVertex*>& synth() const { return m_synth; }
bool drivesUnusedVars() const { return m_drivesUnusedVars; }
void setDrivesUnusedVars() { m_drivesUnusedVars = true; }
bool selectedForSynthesis() const { return m_selectedForSynthesis; }
void setSelectedForSynthesis() { m_selectedForSynthesis = true; }
bool nonSynthesizable() const { return m_nonSynthesizable; }