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.
This commit is contained in:
parent
5d0352ab46
commit
7176bdcff6
|
|
@ -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<Variable*> toRemove;
|
||||
|
||||
// Join each symbol
|
||||
for (std::pair<Variable* const, DfgVertexVar*>& 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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue