diff --git a/src/V3Const.cpp b/src/V3Const.cpp index 8e2fde0aa..fad388b35 100644 --- a/src/V3Const.cpp +++ b/src/V3Const.cpp @@ -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) // diff --git a/src/V3Gate.cpp b/src/V3Gate.cpp index 298dc0b03..6d3c1f9b2 100644 --- a/src/V3Gate.cpp +++ b/src/V3Gate.cpp @@ -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: "); diff --git a/src/V3Slice.cpp b/src/V3Slice.cpp index e203201a5..81e622ee2 100644 --- a/src/V3Slice.cpp +++ b/src/V3Slice.cpp @@ -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; diff --git a/test_regress/t/t_opt_slice.py b/test_regress/t/t_opt_slice.py index b77291069..6d138a3d9 100755 --- a/test_regress/t/t_opt_slice.py +++ b/test_regress/t/t_opt_slice.py @@ -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()