From 2ef979a39c3d5e6df95b26f6df305fbec8738f8d Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Tue, 21 Apr 2026 00:34:20 -0400 Subject: [PATCH] Fix dead removing packages with only DPI. --- src/V3Dead.cpp | 6 ++- src/V3GraphAlg.cpp | 2 +- test_regress/t/t_opt_dead.cpp | 10 +++++ test_regress/t/t_opt_dead.py | 9 ++-- test_regress/t/t_opt_dead.v | 79 ++++++++++++++++++++++++++++++++--- 5 files changed, 96 insertions(+), 10 deletions(-) create mode 100644 test_regress/t/t_opt_dead.cpp diff --git a/src/V3Dead.cpp b/src/V3Dead.cpp index f2453eec2..761fbe1a2 100644 --- a/src/V3Dead.cpp +++ b/src/V3Dead.cpp @@ -329,8 +329,12 @@ class DeadVisitor final : public VNVisitor { void visit(AstNodeFTask* nodep) override { iterateChildren(nodep); checkAll(nodep); - if (!nodep->taskPublic() && !nodep->dpiExport() && !nodep->dpiImport()) + if (nodep->taskPublic() || nodep->dpiExport() || nodep->dpiImport()) { + if (m_modp && !m_modp->dead() && !m_modp->verilatorLib()) + m_modp->user1Inc(); // Keep container + } else { m_tasksp.push(nodep); + } if (nodep->classOrPackagep()) { if (m_elimCells) { nodep->classOrPackagep(nullptr); diff --git a/src/V3GraphAlg.cpp b/src/V3GraphAlg.cpp index 9640f6272..a501b96a4 100644 --- a/src/V3GraphAlg.cpp +++ b/src/V3GraphAlg.cpp @@ -40,7 +40,7 @@ VL_DEFINE_DEBUG_FUNCTIONS; // Changes user() and weight() class GraphRemoveRedundant final : GraphAlg<> { - const bool m_sumWeights; ///< Sum, rather then maximize weights + const bool m_sumWeights; // Sum, rather then maximize weights private: void main() { for (V3GraphVertex& vertex : m_graphp->vertices()) vertexIterate(&vertex); diff --git a/test_regress/t/t_opt_dead.cpp b/test_regress/t/t_opt_dead.cpp new file mode 100644 index 000000000..3714dbfb7 --- /dev/null +++ b/test_regress/t/t_opt_dead.cpp @@ -0,0 +1,10 @@ +// -*- mode: C++; c-file-style: "cc-mode" -*- +//************************************************************************* +// This file ONLY is placed under the Creative Commons Public Domain. +// SPDX-FileCopyrightText: 2026 Wilson Snyder +// SPDX-License-Identifier: CC0-1.0 +//************************************************************************* + +#include "Vt_opt_dead__Dpi.h" + +void dpii_Keep() {} diff --git a/test_regress/t/t_opt_dead.py b/test_regress/t/t_opt_dead.py index a0de4ce68..5b11d5392 100755 --- a/test_regress/t/t_opt_dead.py +++ b/test_regress/t/t_opt_dead.py @@ -11,13 +11,16 @@ import vltest_bootstrap test.scenarios('simulator') -test.compile() +test.compile(verilator_flags2=[test.pli_filename]) test.execute() # bug2227, Verilator unsupported, class dead # This is what we really want: -# test.file_grep_not(test.obj_dir + "/V"+test.name+"__Syms.h", r'dead') -test.file_grep(test.obj_dir + "/V" + test.name + "__Syms.h", r'dead') +# test.file_grep_not(test.obj_dir + "/V"+test.name+"__Syms.h", r'Dead') +# test.file_grep_not(test.obj_dir + "/V" + test.name + "_classes.mk", r'Dead'); +test.file_grep(test.obj_dir + "/V" + test.name + "__Dpi.h", r'dpii_Keep') +test.file_grep(test.obj_dir + "/V" + test.name + "__Dpi.h", r'dpix_Keep') +test.file_grep(test.obj_dir + "/V" + test.name + "_Pkg_public_kpt.h", r'public_int_Keep') test.passes() diff --git a/test_regress/t/t_opt_dead.v b/test_regress/t/t_opt_dead.v index 906e37d6e..4db94ac09 100644 --- a/test_regress/t/t_opt_dead.v +++ b/test_regress/t/t_opt_dead.v @@ -4,26 +4,95 @@ // SPDX-FileCopyrightText: 2020 Wilson Snyder // SPDX-License-Identifier: CC0-1.0 -class EmptyClass_Dead; +// Tests look for magic string "Dead" not to exist; V3Dead should remove these + +class BaseClass_Dead; endclass +class EmptyClass_Dead extends BaseClass_Dead; +endclass + +package Pack_Dead; + typedef bit typedef_Dead; +endpackage + module Mod_Dead; + typedef class ModClass_Co_Dead; class ModClass_Dead; - int memberb_dead; + int m_b_Dead; + ModClass_Co_Dead m_co_dead; + task method_Dead; + endtask + static task method_static_Dead; + endtask + endclass + class ModClass_Co_Dead; + ModClass_Dead m_dead; // Check that ModClass_Dead<->ModClass_Co_Dead link gets Deadified endclass endmodule -//TODO dead check with class extends +module Mod_Empty_Dead; +endmodule -module t; +module Mod_Parent_Empty_Dead; + Mod_Empty_Dead sub (); +endmodule + +interface If_Dead; + function void if_func_Dead; + endfunction + modport modport_Dead(import if_func_Dead); +endinterface + +package Pkg_public_kpt; + parameter int public_int_Keep /*verilator public_flat_rd*/ = 5; +endpackage + +package Pkg_Keep; + import "DPI-C" function void dpii_Keep(); + + export "DPI-C" function dpix_Keep; + function void dpix_Keep; + endfunction +endpackage + +module t ( /*AUTOARG*/); + + typedef struct {int struct_member_Dead;} struct_Dead_t; + struct_Dead_t var_struct_Dead; + + typedef int typedef_Dead1_t; + typedef typedef_Dead1_t typedef_Dead2_t; + + function void func_Dead; + endfunction generate if (0) begin - Mod_Dead cell_dead (); + Mod_Dead cell_nogen_Dead (); + If_Dead if_nogen_Dead (); end endgenerate + Mod_Empty_Dead cell_empty_Dead (); + Mod_Parent_Empty_Dead cell_parent_empty_Dead (); + + typedef_Dead1_t assigned_to_Dead1; + typedef_Dead2_t assigned_to_Dead2; + typedef_Dead2_t assigned_to_Dead3; + typedef_Dead2_t assigned_to_Dead4; + typedef_Dead2_t assigned_to_Dead5; + typedef_Dead2_t assigned_to_Dead6; + + always_comb assigned_to_Dead6 = assigned_to_Dead5; + always_comb assigned_to_Dead5 = assigned_to_Dead4; + always_comb assigned_to_Dead4 = assigned_to_Dead3; + always_comb assigned_to_Dead3 = assigned_to_Dead2; + always_comb assigned_to_Dead2 = assigned_to_Dead1; + initial begin + assigned_to_Dead1 = 1; + assigned_to_Dead1 = 2; $write("*-* All Finished *-*\n"); $finish; end