mirror of
https://github.com/YosysHQ/yosys
synced 2026-05-04 17:35:18 +00:00
opt_clean: refactor
This commit is contained in:
parent
930bd3acc5
commit
5d3b3ff18d
4 changed files with 62 additions and 38 deletions
|
|
@ -33,7 +33,7 @@ unsigned int hash_bit(const SigBit &bit) {
|
||||||
return static_cast<unsigned int>(hash_ops<SigBit>::hash(bit).yield());
|
return static_cast<unsigned int>(hash_ops<SigBit>::hash(bit).yield());
|
||||||
}
|
}
|
||||||
|
|
||||||
void rmunused_module_cells(Module *module, ParallelDispatchThreadPool::Subpool &subpool, bool verbose, CleanRunContext &clean_ctx, keep_cache_t &keep_cache)
|
void rmunused_module_cells(Module *module, ParallelDispatchThreadPool::Subpool &subpool, CleanRunContext &clean_ctx)
|
||||||
{
|
{
|
||||||
SigMap sigmap(module);
|
SigMap sigmap(module);
|
||||||
FfInitVals ffinit;
|
FfInitVals ffinit;
|
||||||
|
|
@ -134,7 +134,7 @@ void rmunused_module_cells(Module *module, ParallelDispatchThreadPool::Subpool &
|
||||||
// Prepare "input cone" traversal from memory to write port or meminit as mem2cells
|
// Prepare "input cone" traversal from memory to write port or meminit as mem2cells
|
||||||
// Also check driver conflicts
|
// Also check driver conflicts
|
||||||
// Also mark cells unused to true unless keep (we override this later)
|
// Also mark cells unused to true unless keep (we override this later)
|
||||||
subpool.run([&sigmap, &raw_sigmap, &keep_cache, const_module, &mem2cells_vector, &driver_driver_logs, &keep_wires, &cell_queue, &wire2driver_builder, &clean_ctx, &unused](const ParallelDispatchThreadPool::RunCtx &ctx) {
|
subpool.run([&sigmap, &raw_sigmap, const_module, &mem2cells_vector, &driver_driver_logs, &keep_wires, &cell_queue, &wire2driver_builder, &clean_ctx, &unused](const ParallelDispatchThreadPool::RunCtx &ctx) {
|
||||||
for (int i : ctx.item_range(const_module->cells_size())) {
|
for (int i : ctx.item_range(const_module->cells_size())) {
|
||||||
Cell *cell = const_module->cell_at(i);
|
Cell *cell = const_module->cell_at(i);
|
||||||
if (cell->type.in(ID($memwr), ID($memwr_v2), ID($meminit), ID($meminit_v2)))
|
if (cell->type.in(ID($memwr), ID($memwr_v2), ID($meminit), ID($meminit_v2)))
|
||||||
|
|
@ -157,7 +157,7 @@ void rmunused_module_cells(Module *module, ParallelDispatchThreadPool::Subpool &
|
||||||
wire2driver_builder.insert(ctx, {{bit, i}, hash_bit(bit)});
|
wire2driver_builder.insert(ctx, {{bit, i}, hash_bit(bit)});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool keep = keep_cache.query(cell);
|
bool keep = clean_ctx.keep_cache.query(cell);
|
||||||
unused[i].store(!keep, std::memory_order_relaxed);
|
unused[i].store(!keep, std::memory_order_relaxed);
|
||||||
if (keep)
|
if (keep)
|
||||||
cell_queue.push(ctx, i);
|
cell_queue.push(ctx, i);
|
||||||
|
|
@ -267,7 +267,7 @@ void rmunused_module_cells(Module *module, ParallelDispatchThreadPool::Subpool &
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto cell : unused_cells) {
|
for (auto cell : unused_cells) {
|
||||||
if (verbose)
|
if (clean_ctx.flags.verbose)
|
||||||
log_debug(" removing unused `%s' cell `%s'.\n", cell->type, cell->name);
|
log_debug(" removing unused `%s' cell `%s'.\n", cell->type, cell->name);
|
||||||
module->design->scratchpad_set_bool("opt.did_something", true);
|
module->design->scratchpad_set_bool("opt.did_something", true);
|
||||||
if (cell->is_builtin_ff())
|
if (cell->is_builtin_ff())
|
||||||
|
|
@ -280,7 +280,7 @@ void rmunused_module_cells(Module *module, ParallelDispatchThreadPool::Subpool &
|
||||||
if (!mem_unused[it.second].load(std::memory_order_relaxed))
|
if (!mem_unused[it.second].load(std::memory_order_relaxed))
|
||||||
continue;
|
continue;
|
||||||
RTLIL::IdString id(it.first);
|
RTLIL::IdString id(it.first);
|
||||||
if (verbose)
|
if (clean_ctx.flags.verbose)
|
||||||
log_debug(" removing unused memory `%s'.\n", id.unescape());
|
log_debug(" removing unused memory `%s'.\n", id.unescape());
|
||||||
delete module->memories.at(id);
|
delete module->memories.at(id);
|
||||||
module->memories.erase(id);
|
module->memories.erase(id);
|
||||||
|
|
|
||||||
|
|
@ -34,21 +34,21 @@ PRIVATE_NAMESPACE_BEGIN
|
||||||
|
|
||||||
using RTLIL::id2cstr;
|
using RTLIL::id2cstr;
|
||||||
|
|
||||||
void rmunused_module(RTLIL::Module *module, ParallelDispatchThreadPool &thread_pool, bool purge_mode, bool verbose, bool rminit, CleanRunContext &clean_ctx, keep_cache_t &keep_cache)
|
void rmunused_module(RTLIL::Module *module, bool rminit, CleanRunContext &clean_ctx)
|
||||||
{
|
{
|
||||||
if (verbose)
|
if (clean_ctx.flags.verbose)
|
||||||
log("Finding unused cells or wires in module %s..\n", module->name);
|
log("Finding unused cells or wires in module %s..\n", module->name);
|
||||||
|
|
||||||
// Use no more than one worker per thousand cells, rounded down, so
|
// Use no more than one worker per thousand cells, rounded down, so
|
||||||
// we only start multithreading with at least 2000 cells.
|
// we only start multithreading with at least 2000 cells.
|
||||||
int num_worker_threads = ThreadPool::work_pool_size(0, module->cells_size(), 1000);
|
int num_worker_threads = ThreadPool::work_pool_size(0, module->cells_size(), 1000);
|
||||||
ParallelDispatchThreadPool::Subpool subpool(thread_pool, num_worker_threads);
|
ParallelDispatchThreadPool::Subpool subpool(clean_ctx.thread_pool, num_worker_threads);
|
||||||
remove_temporary_cells(module, subpool, verbose);
|
remove_temporary_cells(module, subpool, clean_ctx.flags.verbose);
|
||||||
rmunused_module_cells(module, subpool, verbose, clean_ctx, keep_cache);
|
rmunused_module_cells(module, subpool, clean_ctx);
|
||||||
while (rmunused_module_signals(module, subpool, purge_mode, verbose, clean_ctx)) { }
|
while (rmunused_module_signals(module, subpool, clean_ctx)) { }
|
||||||
|
|
||||||
if (rminit && rmunused_module_init(module, subpool, verbose))
|
if (rminit && rmunused_module_init(module, subpool, clean_ctx.flags.verbose))
|
||||||
while (rmunused_module_signals(module, subpool, purge_mode, verbose, clean_ctx)) { }
|
while (rmunused_module_signals(module, subpool, clean_ctx)) { }
|
||||||
}
|
}
|
||||||
struct OptCleanPass : public Pass {
|
struct OptCleanPass : public Pass {
|
||||||
OptCleanPass() : Pass("opt_clean", "remove unused cells and wires") { }
|
OptCleanPass() : Pass("opt_clean", "remove unused cells and wires") { }
|
||||||
|
|
@ -97,9 +97,9 @@ struct OptCleanPass : public Pass {
|
||||||
keep_cache_t keep_cache(purge_mode, thread_pool, selected_modules);
|
keep_cache_t keep_cache(purge_mode, thread_pool, selected_modules);
|
||||||
|
|
||||||
{
|
{
|
||||||
CleanRunContext clean_ctx(design);
|
CleanRunContext clean_ctx(design, {purge_mode, true});
|
||||||
for (auto module : selected_modules)
|
for (auto module : selected_modules)
|
||||||
rmunused_module(module, thread_pool, purge_mode, true, true, clean_ctx, keep_cache);
|
rmunused_module(module, true, clean_ctx);
|
||||||
clean_ctx.stats.log();
|
clean_ctx.stats.log();
|
||||||
|
|
||||||
design->optimize();
|
design->optimize();
|
||||||
|
|
@ -143,20 +143,10 @@ struct CleanPass : public Pass {
|
||||||
}
|
}
|
||||||
extra_args(args, argidx, design);
|
extra_args(args, argidx, design);
|
||||||
|
|
||||||
std::vector<RTLIL::Module*> selected_modules;
|
|
||||||
for (auto module : design->selected_unboxed_whole_modules())
|
|
||||||
if (!module->has_processes())
|
|
||||||
selected_modules.push_back(module);
|
|
||||||
int thread_pool_size = 0;
|
|
||||||
for (RTLIL::Module *m : selected_modules)
|
|
||||||
thread_pool_size = std::max(thread_pool_size, ThreadPool::work_pool_size(0, m->cells_size(), 1000));
|
|
||||||
ParallelDispatchThreadPool thread_pool(thread_pool_size);
|
|
||||||
keep_cache_t keep_cache(purge_mode, thread_pool, selected_modules);
|
|
||||||
|
|
||||||
{
|
{
|
||||||
CleanRunContext clean_ctx(design);
|
CleanRunContext clean_ctx(design, {purge_mode, ys_debug()});
|
||||||
for (auto module : selected_modules)
|
for (auto module : clean_ctx.selected_modules)
|
||||||
rmunused_module(module, thread_pool, purge_mode, ys_debug(), true, clean_ctx, keep_cache);
|
rmunused_module(module, true, clean_ctx);
|
||||||
|
|
||||||
log_suppressed();
|
log_suppressed();
|
||||||
clean_ctx.stats.log();
|
clean_ctx.stats.log();
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@
|
||||||
#include "kernel/threading.h"
|
#include "kernel/threading.h"
|
||||||
#include "kernel/celltypes.h"
|
#include "kernel/celltypes.h"
|
||||||
#include "kernel/yosys_common.h"
|
#include "kernel/yosys_common.h"
|
||||||
|
#include "passes/opt/opt_clean/keep_cache.h"
|
||||||
|
|
||||||
#ifndef OPT_CLEAN_SHARED_H
|
#ifndef OPT_CLEAN_SHARED_H
|
||||||
#define OPT_CLEAN_SHARED_H
|
#define OPT_CLEAN_SHARED_H
|
||||||
|
|
@ -47,27 +48,60 @@ struct RmStats {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Flags {
|
||||||
|
bool purge = false;
|
||||||
|
bool verbose = false;
|
||||||
|
};
|
||||||
struct CleanRunContext {
|
struct CleanRunContext {
|
||||||
CellTypes ct_reg;
|
CellTypes ct_reg;
|
||||||
CellTypes ct_all;
|
CellTypes ct_all;
|
||||||
RmStats stats;
|
RmStats stats;
|
||||||
CleanRunContext(RTLIL::Design* design) {
|
ParallelDispatchThreadPool thread_pool;
|
||||||
|
std::vector<RTLIL::Module*> selected_modules;
|
||||||
|
keep_cache_t keep_cache;
|
||||||
|
Flags flags;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Helper to compute thread pool size
|
||||||
|
static int compute_thread_pool_size(RTLIL::Design* design) {
|
||||||
|
int thread_pool_size = 0;
|
||||||
|
for (auto module : design->selected_unboxed_whole_modules())
|
||||||
|
if (!module->has_processes())
|
||||||
|
thread_pool_size = std::max(thread_pool_size,
|
||||||
|
ThreadPool::work_pool_size(0, module->cells_size(), 1000));
|
||||||
|
return thread_pool_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<RTLIL::Module*> get_selected_modules(RTLIL::Design* design) {
|
||||||
|
std::vector<RTLIL::Module*> modules;
|
||||||
|
for (auto module : design->selected_unboxed_whole_modules())
|
||||||
|
if (!module->has_processes())
|
||||||
|
modules.push_back(module);
|
||||||
|
return modules;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
CleanRunContext(RTLIL::Design* design, Flags f)
|
||||||
|
: thread_pool(compute_thread_pool_size(design)),
|
||||||
|
selected_modules(get_selected_modules(design)),
|
||||||
|
keep_cache(f.purge, thread_pool, selected_modules),
|
||||||
|
flags(f)
|
||||||
|
{
|
||||||
ct_reg.setup_internals_mem();
|
ct_reg.setup_internals_mem();
|
||||||
ct_reg.setup_internals_anyinit();
|
ct_reg.setup_internals_anyinit();
|
||||||
ct_reg.setup_stdcells_mem();
|
ct_reg.setup_stdcells_mem();
|
||||||
|
|
||||||
ct_all.setup(design);
|
ct_all.setup(design);
|
||||||
}
|
}
|
||||||
|
|
||||||
~CleanRunContext() {
|
~CleanRunContext() {
|
||||||
ct_reg.clear();
|
ct_reg.clear();
|
||||||
ct_all.clear();
|
ct_all.clear();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct keep_cache_t;
|
|
||||||
void remove_temporary_cells(RTLIL::Module *module, ParallelDispatchThreadPool::Subpool &subpool, bool verbose);
|
void remove_temporary_cells(RTLIL::Module *module, ParallelDispatchThreadPool::Subpool &subpool, bool verbose);
|
||||||
void rmunused_module_cells(Module *module, ParallelDispatchThreadPool::Subpool &subpool, bool verbose, CleanRunContext &clean_ctx, keep_cache_t &keep_cache);
|
void rmunused_module_cells(Module *module, ParallelDispatchThreadPool::Subpool &subpool, CleanRunContext &clean_ctx);
|
||||||
bool rmunused_module_signals(RTLIL::Module *module, ParallelDispatchThreadPool::Subpool &subpool, bool purge_mode, bool verbose, CleanRunContext &clean_ctx);
|
bool rmunused_module_signals(RTLIL::Module *module, ParallelDispatchThreadPool::Subpool &subpool, CleanRunContext &clean_ctx);
|
||||||
bool rmunused_module_init(RTLIL::Module *module, ParallelDispatchThreadPool::Subpool &subpool, bool verbose);
|
bool rmunused_module_init(RTLIL::Module *module, ParallelDispatchThreadPool::Subpool &subpool, bool verbose);
|
||||||
|
|
||||||
YOSYS_NAMESPACE_END
|
YOSYS_NAMESPACE_END
|
||||||
|
|
|
||||||
|
|
@ -537,13 +537,13 @@ PRIVATE_NAMESPACE_END
|
||||||
|
|
||||||
YOSYS_NAMESPACE_BEGIN
|
YOSYS_NAMESPACE_BEGIN
|
||||||
|
|
||||||
bool rmunused_module_signals(RTLIL::Module *module, ParallelDispatchThreadPool::Subpool &subpool, bool purge_mode, bool verbose, CleanRunContext &clean_ctx)
|
bool rmunused_module_signals(RTLIL::Module *module, ParallelDispatchThreadPool::Subpool &subpool, CleanRunContext &clean_ctx)
|
||||||
{
|
{
|
||||||
// Passing actx to function == function does parallel work
|
// Passing actx to function == function does parallel work
|
||||||
// Not passing module as function argument == function does not modify module
|
// Not passing module as function argument == function does not modify module
|
||||||
// TODO the above sentence is false due to constness laundering in wire_at / cell_at
|
// TODO the above sentence is false due to constness laundering in wire_at / cell_at
|
||||||
AnalysisContext actx(module, subpool);
|
AnalysisContext actx(module, subpool);
|
||||||
SigConnKinds conn_kinds(purge_mode, actx, clean_ctx);
|
SigConnKinds conn_kinds(clean_ctx.flags.purge, actx, clean_ctx);
|
||||||
|
|
||||||
// Main thread's cached direct wires are retained and used later:
|
// Main thread's cached direct wires are retained and used later:
|
||||||
DirectWires direct_wires(conn_kinds.direct, actx.assign_map);
|
DirectWires direct_wires(conn_kinds.direct, actx.assign_map);
|
||||||
|
|
@ -565,17 +565,17 @@ bool rmunused_module_signals(RTLIL::Module *module, ParallelDispatchThreadPool::
|
||||||
fixup_update_ports(deferred.update_connections);
|
fixup_update_ports(deferred.update_connections);
|
||||||
consume_inits(deferred.initialized_wires, actx.assign_map).apply_normalised_inits();
|
consume_inits(deferred.initialized_wires, actx.assign_map).apply_normalised_inits();
|
||||||
|
|
||||||
WireDeleter deleter(used, purge_mode, actx);
|
WireDeleter deleter(used, clean_ctx.flags.purge, actx);
|
||||||
|
|
||||||
used.clear(subpool);
|
used.clear(subpool);
|
||||||
|
|
||||||
deleter.commit_changes(module);
|
deleter.commit_changes(module);
|
||||||
int deleted_and_unreported = deleter.delete_wires(module, verbose);
|
int deleted_and_unreported = deleter.delete_wires(module, clean_ctx.flags.verbose);
|
||||||
int deleted_total = GetSize(deleter.del_wires_queue);
|
int deleted_total = GetSize(deleter.del_wires_queue);
|
||||||
|
|
||||||
clean_ctx.stats.count_rm_wires += deleted_total;
|
clean_ctx.stats.count_rm_wires += deleted_total;
|
||||||
|
|
||||||
if (verbose && deleted_and_unreported)
|
if (clean_ctx.flags.verbose && deleted_and_unreported)
|
||||||
log_debug(" removed %d unused temporary wires.\n", deleted_and_unreported);
|
log_debug(" removed %d unused temporary wires.\n", deleted_and_unreported);
|
||||||
|
|
||||||
if (deleted_total)
|
if (deleted_total)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue