From 7176bdcff6e19907a6f9c90022caffa131e0becb Mon Sep 17 00:00:00 2001 From: Geza Lore Date: Tue, 17 Feb 2026 20:00:55 +0000 Subject: [PATCH] Optimize always blocks using local temporary variables in Dfg (#7085) Enable synthesis of blocks that use a variable only within certain branches, if that variable is not externally observable. --- src/V3DfgSynthesize.cpp | 22 +++++++++++++--------- test_regress/t/t_dfg_synthesis.v | 22 ++++++++++++++++++++++ 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/src/V3DfgSynthesize.cpp b/src/V3DfgSynthesize.cpp index dd7a05292..19ae001e5 100644 --- a/src/V3DfgSynthesize.cpp +++ b/src/V3DfgSynthesize.cpp @@ -1034,20 +1034,20 @@ class AstToDfgSynthesize final { // Merge 'thenSymTab' into 'elseSymTab' using the given predicate to join values bool joinSymbolTables(SymTab& elseSymTab, DfgVertexVar* predicatep, const SymTab& thenSymTab) { - // Give up if something is not assigned on all paths ... Latch? - if (thenSymTab.size() != elseSymTab.size()) { - ++m_ctx.m_synt.nonSynLatch; - return false; - } + // Any variable that does not have a binding on both paths will be removed. These might be + // temporaries, loop vars, etc used only in one branch. Conversion will fail if the + // variable is actually referenced later. + std::vector toRemove; + // Join each symbol for (std::pair& pair : elseSymTab) { Variable* const varp = pair.first; // Find same variable on the else path - auto it = thenSymTab.find(varp); - // Give up if something is not assigned on all paths ... Latch? + const auto it = thenSymTab.find(varp); + // Record for removal if not assigned on both paths if (it == thenSymTab.end()) { - ++m_ctx.m_synt.nonSynLatch; - return false; + toRemove.emplace_back(varp); + continue; } // Join paths with the predicate DfgVertexVar* const thenp = it->second; @@ -1056,6 +1056,10 @@ class AstToDfgSynthesize final { if (!newp) return false; pair.second = newp; } + + // Remove variables not assigned on both paths + for (Variable* const varp : toRemove) elseSymTab.erase(varp); + // Done return true; } diff --git a/test_regress/t/t_dfg_synthesis.v b/test_regress/t/t_dfg_synthesis.v index cde222fac..42e2e41db 100644 --- a/test_regress/t/t_dfg_synthesis.v +++ b/test_regress/t/t_dfg_synthesis.v @@ -502,4 +502,26 @@ module t ( end `signal(BOTH_BREAK, both_break); + logic [1:0] uses_tmp; + always_comb begin + uses_tmp = 2'd0; + if (rand_a[0]) begin + automatic logic [1:0] tmp; + tmp = rand_b[1:0]; + uses_tmp = tmp ^ rand_b[3:2]; + end + end + `signal(USES_TMP, uses_tmp); + + logic [3:0] uses_loop_var; + always_comb begin + uses_loop_var = 4'd0; + if (rand_a[0]) begin + for (int i = 0; i < 4; ++i) begin + uses_loop_var[i] = rand_b[2*i]; + end + end + end + `signal(USES_LOOP_VAR, uses_loop_var); + endmodule