diff --git a/docs/guide/exe_verilator.rst b/docs/guide/exe_verilator.rst index 938152af8..684d5646d 100644 --- a/docs/guide/exe_verilator.rst +++ b/docs/guide/exe_verilator.rst @@ -590,6 +590,8 @@ Summary: .. option:: -fno-const-bit-op-tree +.. option:: -fno-const-eager + .. option:: -fno-dedup .. option:: -fno-dfg diff --git a/src/V3Expand.cpp b/src/V3Expand.cpp index a0109d51e..952eb2d40 100644 --- a/src/V3Expand.cpp +++ b/src/V3Expand.cpp @@ -357,6 +357,16 @@ class ExpandVisitor final : public VNVisitor { } // VISITORS + void visit(AstCFunc* nodep) override { + iterateChildren(nodep); + + // Constant fold here, as Ast size can likely be reduced + if (v3Global.opt.fConstEager()) { + AstNode* const editedp = V3Const::constifyEditCpp(nodep); + UASSERT_OBJ(editedp == nodep, editedp, "Should not have replaced CFunc"); + } + } + void visit(AstExtend* nodep) override { if (nodep->user1SetOnce()) return; // Process once iterateChildren(nodep); diff --git a/src/V3Options.cpp b/src/V3Options.cpp index 86a7c0c16..257b1c7fe 100644 --- a/src/V3Options.cpp +++ b/src/V3Options.cpp @@ -1320,6 +1320,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, DECL_OPTION("-fconst", FOnOff, &m_fConst); DECL_OPTION("-fconst-before-dfg", FOnOff, &m_fConstBeforeDfg); DECL_OPTION("-fconst-bit-op-tree", FOnOff, &m_fConstBitOpTree); + DECL_OPTION("-fconst-eager", FOnOff, &m_fConstEager); DECL_OPTION("-fdead-assigns", FOnOff, &m_fDeadAssigns); DECL_OPTION("-fdead-cells", FOnOff, &m_fDeadCells); DECL_OPTION("-fdedup", FOnOff, &m_fDedupe); diff --git a/src/V3Options.h b/src/V3Options.h index 6c7fb6acd..8d5a2de1d 100644 --- a/src/V3Options.h +++ b/src/V3Options.h @@ -389,6 +389,7 @@ private: bool m_fConst; // main switch: -fno-const: constant folding bool m_fConstBeforeDfg = true; // main switch: -fno-const-before-dfg for testing only! bool m_fConstBitOpTree; // main switch: -fno-const-bit-op-tree constant bit op tree + bool m_fConstEager = true; // main switch: -fno-const-eagerly run V3Const during passes bool m_fDedupe; // main switch: -fno-dedupe: logic deduplication bool m_fDfgPeephole = true; // main switch: -fno-dfg-peephole bool m_fDfgPreInline; // main switch: -fno-dfg-pre-inline and -fno-dfg @@ -701,6 +702,7 @@ public: bool fConst() const { return m_fConst; } bool fConstBeforeDfg() const { return m_fConstBeforeDfg; } bool fConstBitOpTree() const { return m_fConstBitOpTree; } + bool fConstEager() const { return m_fConstEager; } bool fDedupe() const { return m_fDedupe; } bool fDfgPeephole() const { return m_fDfgPeephole; } bool fDfgPreInline() const { return m_fDfgPreInline; } diff --git a/src/V3Subst.cpp b/src/V3Subst.cpp index 19fd3d9d8..98ceea886 100644 --- a/src/V3Subst.cpp +++ b/src/V3Subst.cpp @@ -26,6 +26,7 @@ #include "V3Subst.h" +#include "V3Const.h" #include "V3Stats.h" #include @@ -361,6 +362,12 @@ class SubstVisitor final : public VNVisitor { iterateChildren(nodep); for (SubstVarEntry& ip : m_entries) ip.deleteUnusedAssign(); m_entries.clear(); + + // Constant fold here, as Ast size can likely be reduced + if (v3Global.opt.fConstEager()) { + AstNode* const editedp = V3Const::constifyEditCpp(nodep); + UASSERT_OBJ(editedp == nodep, editedp, "Should not have replaced CFunc"); + } } void visit(AstNode* nodep) override { diff --git a/test_regress/t/t_case_66bits_no_const_eager.py b/test_regress/t/t_case_66bits_no_const_eager.py new file mode 100755 index 000000000..2ce516e24 --- /dev/null +++ b/test_regress/t/t_case_66bits_no_const_eager.py @@ -0,0 +1,19 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2025 by Wilson Snyder. This program is free software; you +# can redistribute it and/or modify it under the terms of either the GNU +# Lesser General Public License Version 3 or the Perl Artistic License +# Version 2.0. +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +import vltest_bootstrap + +test.scenarios('vlt') +test.top_filename = "t/t_case_66bits.v" + +test.compile(verilator_flags2=['-fno-const-eager']) + +test.execute() + +test.passes()