diff --git a/passes/opt/opt_clean/cells_all.cc b/passes/opt/opt_clean/cells_all.cc index 1ec5f279c..160d2d32d 100644 --- a/passes/opt/opt_clean/cells_all.cc +++ b/passes/opt/opt_clean/cells_all.cc @@ -33,7 +33,7 @@ unsigned int hash_bit(const SigBit &bit) { return static_cast(hash_ops::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); 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 // Also check driver conflicts // 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())) { Cell *cell = const_module->cell_at(i); 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)}); } } - bool keep = keep_cache.query(cell); + bool keep = clean_ctx.keep_cache.query(cell); unused[i].store(!keep, std::memory_order_relaxed); if (keep) cell_queue.push(ctx, i); @@ -267,7 +267,7 @@ void rmunused_module_cells(Module *module, ParallelDispatchThreadPool::Subpool & } for (auto cell : unused_cells) { - if (verbose) + if (clean_ctx.flags.verbose) log_debug(" removing unused `%s' cell `%s'.\n", cell->type, cell->name); module->design->scratchpad_set_bool("opt.did_something", true); 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)) continue; RTLIL::IdString id(it.first); - if (verbose) + if (clean_ctx.flags.verbose) log_debug(" removing unused memory `%s'.\n", id.unescape()); delete module->memories.at(id); module->memories.erase(id); diff --git a/passes/opt/opt_clean/opt_clean.cc b/passes/opt/opt_clean/opt_clean.cc index 1af177174..ac861bfc6 100644 --- a/passes/opt/opt_clean/opt_clean.cc +++ b/passes/opt/opt_clean/opt_clean.cc @@ -34,21 +34,21 @@ PRIVATE_NAMESPACE_BEGIN 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); // Use no more than one worker per thousand cells, rounded down, so // we only start multithreading with at least 2000 cells. int num_worker_threads = ThreadPool::work_pool_size(0, module->cells_size(), 1000); - ParallelDispatchThreadPool::Subpool subpool(thread_pool, num_worker_threads); - remove_temporary_cells(module, subpool, verbose); - rmunused_module_cells(module, subpool, verbose, clean_ctx, keep_cache); - while (rmunused_module_signals(module, subpool, purge_mode, verbose, clean_ctx)) { } + ParallelDispatchThreadPool::Subpool subpool(clean_ctx.thread_pool, num_worker_threads); + remove_temporary_cells(module, subpool, clean_ctx.flags.verbose); + rmunused_module_cells(module, subpool, clean_ctx); + while (rmunused_module_signals(module, subpool, clean_ctx)) { } - if (rminit && rmunused_module_init(module, subpool, verbose)) - while (rmunused_module_signals(module, subpool, purge_mode, verbose, clean_ctx)) { } + if (rminit && rmunused_module_init(module, subpool, clean_ctx.flags.verbose)) + while (rmunused_module_signals(module, subpool, clean_ctx)) { } } struct OptCleanPass : public Pass { 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); { - CleanRunContext clean_ctx(design); + CleanRunContext clean_ctx(design, {purge_mode, true}); 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(); design->optimize(); @@ -143,20 +143,10 @@ struct CleanPass : public Pass { } extra_args(args, argidx, design); - std::vector 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); - for (auto module : selected_modules) - rmunused_module(module, thread_pool, purge_mode, ys_debug(), true, clean_ctx, keep_cache); + CleanRunContext clean_ctx(design, {purge_mode, ys_debug()}); + for (auto module : clean_ctx.selected_modules) + rmunused_module(module, true, clean_ctx); log_suppressed(); clean_ctx.stats.log(); diff --git a/passes/opt/opt_clean/shared.h b/passes/opt/opt_clean/shared.h index 99173419b..89f74e8ad 100644 --- a/passes/opt/opt_clean/shared.h +++ b/passes/opt/opt_clean/shared.h @@ -22,6 +22,7 @@ #include "kernel/threading.h" #include "kernel/celltypes.h" #include "kernel/yosys_common.h" +#include "passes/opt/opt_clean/keep_cache.h" #ifndef 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 { CellTypes ct_reg; CellTypes ct_all; RmStats stats; - CleanRunContext(RTLIL::Design* design) { + ParallelDispatchThreadPool thread_pool; + std::vector 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 get_selected_modules(RTLIL::Design* design) { + std::vector 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_anyinit(); ct_reg.setup_stdcells_mem(); - ct_all.setup(design); } + ~CleanRunContext() { ct_reg.clear(); ct_all.clear(); } }; -struct keep_cache_t; 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); -bool rmunused_module_signals(RTLIL::Module *module, ParallelDispatchThreadPool::Subpool &subpool, bool purge_mode, bool verbose, CleanRunContext &clean_ctx); +void rmunused_module_cells(Module *module, ParallelDispatchThreadPool::Subpool &subpool, 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); YOSYS_NAMESPACE_END diff --git a/passes/opt/opt_clean/wires.cc b/passes/opt/opt_clean/wires.cc index 35bea96f1..c2e3c0110 100644 --- a/passes/opt/opt_clean/wires.cc +++ b/passes/opt/opt_clean/wires.cc @@ -537,13 +537,13 @@ PRIVATE_NAMESPACE_END 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 // 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 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: 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); 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); 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); 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); if (deleted_total)