mirror of
https://github.com/YosysHQ/yosys
synced 2026-07-15 03:35:40 +00:00
opt_compact_prefix fix 3
This commit is contained in:
parent
9bfe32bffc
commit
da947b72d8
1 changed files with 63 additions and 16 deletions
|
|
@ -961,6 +961,22 @@ struct OptCompactPrefixWorker : CutRegionWorker
|
|||
true, std::max(8192, max_width * max_width * 4), max_width * (max_width + 8));
|
||||
}
|
||||
|
||||
// True if any bit of `sig` is driven by a cell this pass emitted on an
|
||||
// earlier fixpoint sweep (tagged in execute()). The emitted compaction
|
||||
// logic still fingerprints as the same function, so this guard stops the
|
||||
// outer fixpoint loop from re-rewriting its own output indefinitely.
|
||||
bool root_driver_emitted(const SigSpec &sig)
|
||||
{
|
||||
for (auto bit : sigmap(sig)) {
|
||||
if (!bit.wire)
|
||||
continue;
|
||||
Cell *drv = bit_to_driver.at(bit, nullptr);
|
||||
if (drv && drv->get_bool_attribute(ID(opt_compact_prefix_emitted)))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void run()
|
||||
{
|
||||
if (module->has_processes_warn())
|
||||
|
|
@ -990,6 +1006,8 @@ struct OptCompactPrefixWorker : CutRegionWorker
|
|||
}
|
||||
if (root_claimed(root.sig))
|
||||
continue;
|
||||
if (root_driver_emitted(root.sig))
|
||||
continue;
|
||||
|
||||
int width = GetSize(root.sig);
|
||||
// Wide roots (>62) are valid forward-pack candidates; the
|
||||
|
|
@ -1505,28 +1523,57 @@ struct OptCompactPrefixPass : public Pass
|
|||
int total_removed = 0;
|
||||
int total_emitted = 0;
|
||||
|
||||
// Overlapping compaction loops can share post-synthesis logic (e.g. one
|
||||
// loop's start mask feeding the other loop's cone), so a single sweep
|
||||
// claims the first region and masks the second. Iterate each module to
|
||||
// a fixpoint: rewrite, tag the freshly-emitted cells, clean, and re-scan
|
||||
// until a sweep finds nothing new. The tag (consumed by
|
||||
// root_driver_emitted) stops the next sweep from re-matching this pass's
|
||||
// own output, which still fingerprints as the same compaction function.
|
||||
const int max_sweeps = 16;
|
||||
for (auto module : design->selected_modules()) {
|
||||
OptCompactPrefixWorker worker(module, max_width);
|
||||
if (walk_budget > 0)
|
||||
worker.walk_budget = walk_budget;
|
||||
if (eval_budget > 0)
|
||||
worker.eval_budget = eval_budget;
|
||||
if (attempt_budget > 0)
|
||||
worker.attempt_budget = attempt_budget;
|
||||
worker.run();
|
||||
total_forward += worker.forward_rewrites;
|
||||
total_reverse += worker.reverse_rewrites;
|
||||
total_modulo += worker.modulo_rewrites;
|
||||
total_removed += worker.old_cells_removed;
|
||||
total_emitted += worker.new_cells_emitted;
|
||||
for (int sweep = 0; sweep < max_sweeps; sweep++) {
|
||||
pool<Cell *> before;
|
||||
for (auto c : module->cells())
|
||||
before.insert(c);
|
||||
|
||||
OptCompactPrefixWorker worker(module, max_width);
|
||||
if (walk_budget > 0)
|
||||
worker.walk_budget = walk_budget;
|
||||
if (eval_budget > 0)
|
||||
worker.eval_budget = eval_budget;
|
||||
if (attempt_budget > 0)
|
||||
worker.attempt_budget = attempt_budget;
|
||||
worker.run();
|
||||
|
||||
total_forward += worker.forward_rewrites;
|
||||
total_reverse += worker.reverse_rewrites;
|
||||
total_modulo += worker.modulo_rewrites;
|
||||
total_removed += worker.old_cells_removed;
|
||||
total_emitted += worker.new_cells_emitted;
|
||||
|
||||
if (worker.forward_rewrites + worker.reverse_rewrites +
|
||||
worker.modulo_rewrites == 0)
|
||||
break;
|
||||
|
||||
// Tag the cells emitted by this sweep so the next sweep skips
|
||||
// them, then drop the now-dangling old cone so the masked
|
||||
// sibling region becomes visible.
|
||||
for (auto c : module->cells())
|
||||
if (!before.count(c))
|
||||
c->set_bool_attribute(ID(opt_compact_prefix_emitted));
|
||||
Yosys::run_pass("clean -purge");
|
||||
}
|
||||
}
|
||||
|
||||
// Drop the internal bookkeeping tag so it never leaks into the netlist.
|
||||
for (auto module : design->modules())
|
||||
for (auto c : module->cells())
|
||||
c->attributes.erase(ID(opt_compact_prefix_emitted));
|
||||
|
||||
log("Rewrote %d forward pack(s), %d reverse suffix read(s), %d modulo decimation(s); "
|
||||
"removed %d old cell(s), emitted %d new cell(s).\n",
|
||||
total_forward, total_reverse, total_modulo, total_removed, total_emitted);
|
||||
|
||||
if (total_forward || total_reverse || total_modulo)
|
||||
Yosys::run_pass("clean -purge");
|
||||
}
|
||||
} OptCompactPrefixPass;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue