mirror of
https://github.com/verilator/verilator.git
synced 2026-09-03 08:24:31 +02:00
Optimize decoder case statements into lookup tables (#7795)
Recognize "decoder" case statements (where every case item only assigns constants to a fixed set of left-hand sides) and replace them with a single packed constant lookup table indexed by the case expression. Small tables are materialized inline in the generated code, and are always optimized. Larger ones are placed in the constant pool and only optimized if deemed beneficial over branches. While this slightly conflicts with V3Table, and is not worth that much on it's own, there will be a follow up patch that converts more cases of this form which will be much more valuable. This patch does the necessary analysis and the simple table conversion when possible. Split -fcase into -fcase-table (this new conversion) and -fcase-tree (the existing bitwise branch-tree conversion); -fno-case is now an alias for both. Default branches, assignments preceding the case (used as default values), casez wildcards, multiple and partial left-hand sides, and both blocking and non-blocking assignments are handled. Cases that cannot be safely tabled (e.g. non-exhaustive with no default, overlapping writes to one variable, or mixed blocking/non-blocking assignments) fall back to the existing if/else lowering. Consequently disabled re-inlining of constant pool variables in V3Const, and rebuild the constant pool hash in V3Dead (previously we didn't create constant pool entries early enough for this to matter)
This commit is contained in:
@@ -78,9 +78,15 @@ class DataflowOptimize final {
|
||||
if (AstVarScope* const vscp = VN_CAST(nodep, VarScope)) {
|
||||
const AstVar* const varp = vscp->varp();
|
||||
// Force and trace have already been processed
|
||||
const bool hasExtRd = varp->isPrimaryIO() || varp->isSigUserRdPublic();
|
||||
const bool hasExtWr
|
||||
= (varp->isPrimaryIO() && varp->isNonOutput()) || varp->isSigUserRWPublic();
|
||||
const bool hasExtRd = //
|
||||
varp->isPrimaryIO() // Top level port - readable
|
||||
|| varp->isSigUserRdPublic() // Readable by user
|
||||
|| varp->constPoolEntry() // Stored in AstConstPool hashmap, but read only
|
||||
;
|
||||
const bool hasExtWr = //
|
||||
(varp->isPrimaryIO() && varp->isNonOutput()) // Top level port - writable
|
||||
|| varp->isSigUserRWPublic() // Writable by user
|
||||
;
|
||||
if (hasExtRd) DfgVertexVar::setHasExtRdRefs(vscp);
|
||||
if (hasExtWr) DfgVertexVar::setHasExtWrRefs(vscp);
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user