3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2025-04-15 21:38:45 +00:00

opt_expr: don't give up on opt when out of effort

This commit is contained in:
Emil J. Tywoniak 2024-11-28 19:48:29 +01:00
parent fcb3ded9fe
commit 888e01290b

View file

@ -491,39 +491,51 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
handle_clkpol_celltype_swap(cell, "$_DLATCHSR_??N_", "$_DLATCHSR_??P_", ID::R, assign_map, invert_map); handle_clkpol_celltype_swap(cell, "$_DLATCHSR_??N_", "$_DLATCHSR_??P_", ID::R, assign_map, invert_map);
} }
TopoSort<RTLIL::Cell*, RTLIL::IdString::compare_ptr_by_name<RTLIL::Cell>> cells; std::vector<Cell*> module_cells = module->cells();
dict<RTLIL::SigBit, Cell*> outbit_to_cell; auto iterator = [&](auto&& replace_cell) {
if (sort_fails >= effort) {
// log("Running on unsorted")
for (auto cell : module_cells)
if (design->selected(module, cell) && yosys_celltypes.cell_evaluable(cell->type))
replace_cell(cell);
} else {
TopoSort<RTLIL::Cell*, RTLIL::IdString::compare_ptr_by_name<RTLIL::Cell>> cells;
dict<RTLIL::SigBit, Cell*> outbit_to_cell;
for (auto cell : module->cells()) for (auto cell : module->cells())
if (design->selected(module, cell) && yosys_celltypes.cell_evaluable(cell->type)) { if (design->selected(module, cell) && yosys_celltypes.cell_evaluable(cell->type)) {
for (auto &conn : cell->connections()) for (auto &conn : cell->connections())
if (yosys_celltypes.cell_output(cell->type, conn.first)) if (yosys_celltypes.cell_output(cell->type, conn.first))
for (auto bit : assign_map(conn.second)) for (auto bit : assign_map(conn.second))
outbit_to_cell[bit] = cell; outbit_to_cell[bit] = cell;
cells.node(cell); cells.node(cell);
} }
for (auto cell : module->cells()) for (auto cell : module->cells())
if (design->selected(module, cell) && yosys_celltypes.cell_evaluable(cell->type)) { if (design->selected(module, cell) && yosys_celltypes.cell_evaluable(cell->type)) {
const int r_index = cells.node(cell); const int r_index = cells.node(cell);
for (auto &conn : cell->connections()) for (auto &conn : cell->connections())
if (yosys_celltypes.cell_input(cell->type, conn.first)) if (yosys_celltypes.cell_input(cell->type, conn.first))
for (auto bit : assign_map(conn.second)) for (auto bit : assign_map(conn.second))
if (outbit_to_cell.count(bit)) if (outbit_to_cell.count(bit))
cells.edge(cells.node(outbit_to_cell.at(bit)), r_index); cells.edge(cells.node(outbit_to_cell.at(bit)), r_index);
} }
if (sort_fails < effort && !cells.sort()) { if (sort_fails < effort && !cells.sort()) {
// There might be a combinational loop, or there might be constants on the output of cells. 'check' may find out more. // There might be a combinational loop, or there might be constants on the output of cells. 'check' may find out more.
// ...unless this is a coarse-grained cell loop, but not a bit loop, in which case it won't, and all is good. // ...unless this is a coarse-grained cell loop, but not a bit loop, in which case it won't, and all is good.
log("Couldn't topologically sort cells, optimizing module %s may take a longer time.\n", log_id(module)); log("Couldn't topologically sort cells, optimizing module %s may take a longer time.\n", log_id(module));
sort_fails++; sort_fails++;
if (sort_fails >= effort) if (sort_fails >= effort)
log("Effort of %d exceeded, no longer attempting toposort on module %s.\n", log("Effort of %d exceeded, no longer attempting toposort on module %s.\n",
effort, log_id(module)); effort, log_id(module));
} }
for (auto cell : cells.sorted) {
for (auto cell : cells.sorted) replace_cell(cell);
}
}
};
iterator([&](auto& cell)
{ {
#define ACTION_DO(_p_, _s_) do { cover("opt.opt_expr.action_" S__LINE__); replace_cell(assign_map, module, cell, input.as_string(), _p_, _s_); goto next_cell; } while (0) #define ACTION_DO(_p_, _s_) do { cover("opt.opt_expr.action_" S__LINE__); replace_cell(assign_map, module, cell, input.as_string(), _p_, _s_); goto next_cell; } while (0)
#define ACTION_DO_Y(_v_) ACTION_DO(ID::Y, RTLIL::SigSpec(RTLIL::State::S ## _v_)) #define ACTION_DO_Y(_v_) ACTION_DO(ID::Y, RTLIL::SigSpec(RTLIL::State::S ## _v_))
@ -2203,7 +2215,7 @@ skip_alu_split:
#undef ACTION_DO_Y #undef ACTION_DO_Y
#undef FOLD_1ARG_CELL #undef FOLD_1ARG_CELL
#undef FOLD_2ARG_CELL #undef FOLD_2ARG_CELL
} });
} }
void replace_const_connections(RTLIL::Module *module) { void replace_const_connections(RTLIL::Module *module) {
@ -2272,7 +2284,6 @@ struct OptExprPass : public Pass {
bool do_fine = false; bool do_fine = false;
bool keepdc = false; bool keepdc = false;
int effort = 5; int effort = 5;
log_header(design, "Executing OPT_EXPR pass (perform const folding).\n"); log_header(design, "Executing OPT_EXPR pass (perform const folding).\n");
log_push(); log_push();