From 293feb55fa9a72e0070c765553c5eddcdb6b697a Mon Sep 17 00:00:00 2001 From: nella Date: Wed, 1 Apr 2026 09:07:42 +0200 Subject: [PATCH] Invert. --- passes/techmap/csa_tree.cc | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/passes/techmap/csa_tree.cc b/passes/techmap/csa_tree.cc index 618abe0b5..b05586e58 100644 --- a/passes/techmap/csa_tree.cc +++ b/passes/techmap/csa_tree.cc @@ -91,7 +91,8 @@ struct AluInfo { return GetSize(bi) == 1 && bi[0] == State::S0 && GetSize(ci) == 1 && ci[0] == State::S0; } - // A cell is chainable if it's a plain add/sub with unused carries. + // Chainable cells are adds/subs with no carry usage, connected chainable + // cells form chains that can be replaced with CSA trees. bool is_chainable(Cell* cell) { if (!(is_add(cell) || is_subtract(cell))) @@ -138,7 +139,7 @@ struct Rewriter return consumer; } - // Find cells that consumes another cell's output. + // Find cells that consume another cell's output. dict find_parents(const pool& candidates) { dict parent_of; @@ -151,6 +152,17 @@ struct Rewriter return parent_of; } + std::pair>, pool> invert_parent_map(const dict& parent_of) + { + dict> children_of; + pool has_parent; + for (auto& [child, parent] : parent_of) { + children_of[parent].insert(child); + has_parent.insert(child); + } + return {children_of, has_parent}; + } + pool collect_chain(Cell* root, const dict>& children_of) { pool chain; @@ -376,6 +388,7 @@ struct Rewriter extended.push_back(s); } + // Add correction for negated operands (-x = ~x + 1 so 1 per negation) if (neg_compensation > 0) extended.push_back(SigSpec(neg_compensation, width)); @@ -402,13 +415,7 @@ struct Rewriter return; auto parent_of = find_parents(candidates); - - dict> children_of; - pool has_parent; - for (auto& [child, parent] : parent_of) { - children_of[parent].insert(child); - has_parent.insert(child); - } + auto [children_of, has_parent] = invert_parent_map(parent_of); pool processed; for (auto root : candidates) {