Optimize table lookups in Dfg

This commit is contained in:
Geza Lore 2026-06-12 16:24:39 +01:00
parent e03fa6c783
commit 9afd1fa7c5
3 changed files with 50 additions and 3 deletions

View File

@ -1885,10 +1885,24 @@ class V3DfgPeephole final : public DfgVisitor {
if (!idxp) return;
DfgVarArray* const varp = vtxp->fromp()->cast<DfgVarArray>();
if (!varp) return;
if (varp->vscp()->varp()->isForced()) return;
if (varp->vscp()->varp()->isSigUserRWPublic()) return;
AstVar* const astVarp = varp->vscp()->varp();
if (astVarp->isForced()) return;
if (astVarp->isSigUserRWPublic()) return;
DfgVertex* const srcp = varp->srcp();
if (!srcp) return;
if (!srcp) {
if (vtxp->isPacked()) {
if (AstInitArray* const iap = VN_CAST(astVarp->valuep(), InitArray)) {
if (AstConst* const valp
= VN_CAST(iap->getIndexDefaultedValuep(idxp->toSizeT()), Const)) {
APPLYING(FOLD_ARRAYSEL_TABLE) {
replace(new DfgConst{m_dfg, valp->fileline(), valp->num()});
return;
}
}
}
}
return;
}
if (DfgSpliceArray* const splicep = srcp->cast<DfgSpliceArray>()) {
DfgVertex* const driverp = splicep->driverAt(idxp->toSizeT());

View File

@ -27,6 +27,7 @@
// Enumeration of each peephole optimization. Must be kept in sorted order (enforced by tests).
// clang-format off
#define FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION(macro) \
_FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, FOLD_ARRAYSEL_TABLE) \
_FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, FOLD_ASSOC_BINARY_LHS_OF_RHS) \
_FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, FOLD_ASSOC_BINARY_RHS_OF_LHS) \
_FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, FOLD_BINARY) \

View File

@ -50,6 +50,9 @@ module t (
assign unitArrayParts[0][1] = rand_a[1];
assign unitArrayParts[0][9] = rand_a[9];
// Complicated way to write constant 0 that only Dfg can decipher
wire [63:0] convoluted_zero = (({64{rand_a[0]}} & ~{64{rand_a[0]}}));
`signal(FOLD_UNARY_LogNot, !const_a[0]);
`signal(FOLD_UNARY_Negate, -const_a);
`signal(FOLD_UNARY_Not, ~const_a);
@ -133,6 +136,13 @@ module t (
`signal(FOLD_SEL, const_a[3:1]);
int fold_arraysel_table_one;
ffs ffs_a(convoluted_zero[0] ? 8'hff: 8'd2, fold_arraysel_table_one);
int fold_arraysel_table_two;
ffs ffs_b(convoluted_zero[1] ? 8'hff: 8'd7, fold_arraysel_table_two);
`signal(FOLD_ARRAYSEL_TABLE_ONE, fold_arraysel_table_one);
`signal(FOLD_ARRAYSEL_TABLE_TWO, fold_arraysel_table_two);
`signal(SWAP_CONST_IN_COMMUTATIVE_BINARY, rand_a + const_a);
`signal(SWAP_NOT_IN_COMMUTATIVE_BINARY, rand_a + ~rand_a);
`signal(SWAP_VAR_IN_COMMUTATIVE_BINARY, rand_b + rand_a);
@ -427,3 +437,25 @@ module t (
assign zero = '0;
assign ones = '1;
endmodule
module ffs(
input logic [7:0] i,
output int o
);
// V3Table will convert this
always_comb begin
// verilator lint_off CASEOVERLAP
casez (i)
8'b1???????: o = 7;
8'b?1??????: o = 6;
8'b??1?????: o = 5;
8'b???1????: o = 4;
8'b????1???: o = 3;
8'b?????1??: o = 2;
8'b??????1?: o = 1;
8'b???????1: o = 0;
8'b00000000: o = -1;
endcase
// verilator lint_on CASEOVERLAP
end
endmodule