From 13dc77a71cd614fb29a88196ecc1860f06f74ef9 Mon Sep 17 00:00:00 2001 From: "Emil J. Tywoniak" Date: Thu, 26 Mar 2026 16:55:08 +0100 Subject: [PATCH] genrtlil: even fastererer removeSignalFromCaseTree --- frontends/ast/genrtlil.cc | 41 ++++++++++++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 9 deletions(-) diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index c78512377..2b9ca85f4 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -566,17 +566,40 @@ struct AST_INTERNAL::ProcessGenerator // the third assignment. void removeSignalFromCaseTree(const pool &pattern_bits, const pool &pattern_wires, RTLIL::CaseRule *cs) { - for (auto it = cs->actions.begin(); it != cs->actions.end(); ++it) { - // Quick check: if the lvalue doesn't reference any pattern wires, skip - bool may_overlap = false; - for (auto &chunk : it->first.chunks()) { - if (chunk.wire != NULL && pattern_wires.count(chunk.wire)) { - may_overlap = true; - break; + // If pattern only uses one wire, we can check more efficiently + if (pattern_wires.size() == 1) { + RTLIL::Wire *pattern_wire = *pattern_wires.begin(); + for (auto it = cs->actions.begin(); it != cs->actions.end(); ++it) { + // Quick check using first/last bit heuristic + int sz = it->first.size(); + if (sz == 0) continue; + RTLIL::Wire *first_wire = it->first[0].wire; + if (first_wire == pattern_wire || + (sz > 1 && it->first[sz-1].wire == pattern_wire)) { + it->first.remove2(pattern_bits, &it->second); + } else if (first_wire != it->first[sz > 1 ? sz-1 : 0].wire) { + // Multiple wires - need full check + for (auto &chunk : it->first.chunks()) { + if (chunk.wire == pattern_wire) { + it->first.remove2(pattern_bits, &it->second); + break; + } + } } } - if (may_overlap) - it->first.remove2(pattern_bits, &it->second); + } else { + for (auto it = cs->actions.begin(); it != cs->actions.end(); ++it) { + // Quick check: if the lvalue doesn't reference any pattern wires, skip + bool may_overlap = false; + for (auto &chunk : it->first.chunks()) { + if (chunk.wire != NULL && pattern_wires.count(chunk.wire)) { + may_overlap = true; + break; + } + } + if (may_overlap) + it->first.remove2(pattern_bits, &it->second); + } } for (auto it = cs->switches.begin(); it != cs->switches.end(); it++)