Do not unroll simple array assignments in V3Slice (#7359)

See also #5644
This commit is contained in:
Geza Lore 2026-04-01 22:35:29 +01:00 committed by GitHub
parent 894f6c4c58
commit 2e151c3b74
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 22 additions and 3 deletions

View File

@ -1630,6 +1630,9 @@ class ConstVisitor final : public VNVisitor {
if (!thensp->lhsp()->sameGateTree(elsesp->lhsp())) return false;
if (!thensp->rhsp()->gateTree()) return false;
if (!elsesp->rhsp()->gateTree()) return false;
// Must not create an expression with unpacked array type
if (VN_IS(thensp->rhsp()->dtypep()->skipRefp(), UnpackArrayDType)) return false;
if (VN_IS(elsesp->rhsp()->dtypep()->skipRefp(), UnpackArrayDType)) return false;
if (m_underRecFunc) return false; // This optimization may lead to infinite recursion
// Only do it if not calls and both pure, otherwise undoes V3LiftExpr
return !VN_IS(thensp->rhsp(), NodeFTaskRef) //

View File

@ -692,11 +692,17 @@ class GateInline final {
}
}
AstVarScope* const vscp = vVtxp->varScp();
AstNodeExpr* const substp = okVisitor.substitutionp();
// Only inline arrays if a simple variable
if (VN_IS(vscp->dtypep()->skipRefp(), UnpackArrayDType)) {
if (!VN_IS(substp, NodeVarRef)) continue;
}
// Process it
++m_statInlined;
AstVarScope* const vscp = vVtxp->varScp();
AstNodeExpr* const substp = okVisitor.substitutionp();
if (debug() >= 9) {
vscp->dumpTree("substituting: ");
substp->dumpTree(" with: ");

View File

@ -260,6 +260,16 @@ class SliceVisitor final : public VNVisitor {
return false;
}
// Skip if this is a simple a = b assignment of identical arrays
if (AstVarRef* const lhsp = VN_CAST(nodep->lhsp(), VarRef)) {
if (AstVarRef* const rhsp = VN_CAST(nodep->rhsp(), VarRef)) {
if (!hasSc && lhsp->dtypep()->skipRefp()->sameTree(rhsp->dtypep()->skipRefp())) {
m_okInitArray = true; // VL_RESTORER in visit(AstNodeAssign)
return false;
}
}
}
UINFO(4, "Slice optimizing " << nodep);
++m_statAssigns;

View File

@ -13,6 +13,6 @@ test.scenarios('simulator')
test.compile(verilator_flags2=['--sc', '--stats'])
test.file_grep(test.stats, r'Optimizations, Slice array assignments\s+(\d+)', 5)
test.file_grep(test.stats, r'Optimizations, Slice array assignments\s+(\d+)', 2)
test.passes()