Optimize away dead ports (#8426)

This commit is contained in:
Geza Lore
2026-09-21 02:02:59 +01:00
committed by GitHub
parent 3c05eef216
commit 46774fded9
3 changed files with 31 additions and 8 deletions
+27 -1
View File
@@ -246,6 +246,7 @@ class DeadVisitor final : public VNVisitor {
// Entire Netlist:
// AstNodeModule::user1() -> int. Count of number of cells referencing this module.
// AstVar::user1() -> int. Count of number of references
// AstVar::user2() -> bool. Is a formal function argument
// AstVarScope::user1() -> int. Count of number of references
// AstNodeDType::user1() -> int. Count of number of references
const VNUser1InUse m_inuser1;
@@ -279,6 +280,7 @@ class DeadVisitor final : public VNVisitor {
AstNodeModule* m_modp = nullptr; // Current module
AstForeachHeader* m_foreachHeaderp = nullptr; // Current foreach header
AstNode* m_containingFTaskRefp = nullptr; // Parent of ftaskref (e.g. task/module)
bool m_inFTask = false; // Under an AstNodeFTask
// STATE - Statistic tracking
VDouble0 m_statFTasksDemoted;
@@ -351,6 +353,16 @@ class DeadVisitor final : public VNVisitor {
iterateChildren(nodep);
checkAll(nodep);
if (nodep->scopep()) nodep->scopep()->user1Inc();
// Keep formal arguments
for (AstVar* varp = nodep->argsp(); varp; varp = VN_AS(varp->nextp(), Var)) {
varp->user1Inc();
varp->user2(1);
}
}
void visit(AstPin* nodep) override {
iterateChildren(nodep);
checkAll(nodep);
if (nodep->modVarp()) nodep->modVarp()->user1Inc();
}
void visit(AstScope* nodep) override {
iterateChildren(nodep);
@@ -400,6 +412,11 @@ class DeadVisitor final : public VNVisitor {
checkAll(nodep);
needsTask(nodep->ftaskp(), m_containingFTaskRefp);
}
void visit(AstModportVarRef* nodep) override {
iterateChildren(nodep);
checkAll(nodep);
if (nodep->varp()) nodep->varp()->user1Inc();
}
void visit(AstRefDType* nodep) override {
iterateChildren(nodep);
checkDType(nodep);
@@ -510,6 +527,11 @@ class DeadVisitor final : public VNVisitor {
iterateChildren(nodep);
checkAll(nodep);
if (m_foreachHeaderp) nodep->user1Inc();
// Keep formal arguments
if (m_inFTask && nodep->isIO()) {
nodep->user1Inc();
nodep->user2(1);
}
if (mightElimVar(nodep)) {
m_varsp.push_back(nodep);
} else {
@@ -549,7 +571,9 @@ class DeadVisitor final : public VNVisitor {
m_graph.findNewRemovableVertex(nodep, removable);
//
VL_RESTORER(m_containingFTaskRefp);
VL_RESTORER(m_inFTask);
m_containingFTaskRefp = nodep;
m_inFTask = true;
iterateChildren(nodep);
checkAll(nodep);
if (nodep->isVirtual()) m_graph.funcVirtual(nodep);
@@ -668,7 +692,7 @@ class DeadVisitor final : public VNVisitor {
}
bool mightElimVar(const AstVar* nodep) const {
if (nodep->isSigPublic()) return false; // Can't elim publics!
if (nodep->isIO() || nodep->isClassMember() || nodep->sensIfacep()) return false;
if (nodep->isPrimaryIO() || nodep->isClassMember() || nodep->sensIfacep()) return false;
if (nodep->isTemp() && !nodep->isTrace()) return true;
return m_elimUserVars; // Post-Trace can kill most anything
}
@@ -720,6 +744,8 @@ class DeadVisitor final : public VNVisitor {
void deadCheckVar() {
// Delete any unused varscopes
for (AstVarScope* vscp : m_vscsp) {
// Keep formal arguments
if (vscp->varp()->user2()) continue;
if (vscp->user1() == 0) {
UINFO(4, " Dead " << vscp);
const std::pair<AssignMap::iterator, AssignMap::iterator> eqrange
+4 -6
View File
@@ -23,12 +23,10 @@ if test.vlt_all:
r'{"type":"MODULE","name":"l2",.*"loc":"\w,62:[^"]*",.*"origName":"l2"')
test.file_grep(out_filename,
r'{"type":"MODULE","name":"l3",.*"loc":"\w,69:[^"]*",.*"origName":"l3"')
test.file_grep(out_filename,
r'{"type":"MODULE","name":"l4",.*"loc":"\w,76:[^"]*",.*"origName":"l4"')
test.file_grep(out_filename,
r'{"type":"MODULE","name":"l5__P1",.*"loc":"\w,83:[^"]*",.*"origName":"l5"')
test.file_grep(out_filename,
r'{"type":"MODULE","name":"l5__P2",.*"loc":"\w,83:[^"]*",.*"origName":"l5"')
# l4 and l5 hold nothing but combinational logic feeding their single reader,
# so they are optimized away entirely, even though they are marked no_inline
test.file_grep_not(out_filename, r'{"type":"MODULE","name":"l4"')
test.file_grep_not(out_filename, r'{"type":"MODULE","name":"l5__P')
test.execute()
test.file_grep(test.run_log_filename, r"\] (%m|.*t\.ps): Clocked")
-1
View File
@@ -50,7 +50,6 @@
<map from="PSMRXn" to="_trigger_anySet__act"/>
<map from="PSBKaZ" to="_trigger_clear__act"/>
<map from="PSB9K0" to="_trigger_orInto__act_vec_vec"/>
<map from="PScyq8" to="clk"/>
<map from="PSEUqF" to="firstIteration"/>
<map from="PSawda" to="in"/>
<map from="PSMlYB" to="n"/>