yosys-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
opt_clean.cc File Reference
#include "kernel/register.h"
#include "kernel/sigtools.h"
#include "kernel/log.h"
#include "kernel/celltypes.h"
#include <stdlib.h>
#include <stdio.h>
#include <set>
+ Include dependency graph for opt_clean.cc:

Go to the source code of this file.

Data Structures

struct  OptCleanPass
 
struct  CleanPass
 

Functions

void rmunused_module_cells (RTLIL::Module *module, bool verbose)
 
int count_nontrivial_wire_attrs (RTLIL::Wire *w)
 
bool compare_signals (RTLIL::SigBit &s1, RTLIL::SigBit &s2, SigPool &regs, SigPool &conns, std::set< RTLIL::Wire * > &direct_wires)
 
bool check_public_name (RTLIL::IdString id)
 
void rmunused_module_signals (RTLIL::Module *module, bool purge_mode, bool verbose)
 
void rmunused_module (RTLIL::Module *module, bool purge_mode, bool verbose)
 

Variables

CellTypes ct
 
CellTypes ct_reg
 
CellTypes ct_all
 
int count_rm_cells
 
int count_rm_wires
 
OptCleanPass OptCleanPass
 
CleanPass CleanPass
 

Function Documentation

bool check_public_name ( RTLIL::IdString  id)

Definition at line 135 of file opt_clean.cc.

136 {
137  const std::string &id_str = id.str();
138  if (id_str[0] == '$')
139  return false;
140  if (id_str.substr(0, 2) == "\\_" && (id_str[id_str.size()-1] == '_' || id_str.find("_[") != std::string::npos))
141  return false;
142  if (id_str.find(".$") != std::string::npos)
143  return false;
144  return true;
145 }

+ Here is the caller graph for this function:

bool compare_signals ( RTLIL::SigBit s1,
RTLIL::SigBit s2,
SigPool regs,
SigPool conns,
std::set< RTLIL::Wire * > &  direct_wires 
)

Definition at line 100 of file opt_clean.cc.

101 {
102  RTLIL::Wire *w1 = s1.wire;
103  RTLIL::Wire *w2 = s2.wire;
104 
105  if (w1 == NULL || w2 == NULL)
106  return w2 == NULL;
107 
108  if (w1->port_input != w2->port_input)
109  return w2->port_input;
110 
111  if (w1->name[0] == '\\' && w2->name[0] == '\\') {
112  if (regs.check_any(s1) != regs.check_any(s2))
113  return regs.check_any(s2);
114  if (direct_wires.count(w1) != direct_wires.count(w2))
115  return direct_wires.count(w2) != 0;
116  if (conns.check_any(s1) != conns.check_any(s2))
117  return conns.check_any(s2);
118  }
119 
120  if (w1->port_output != w2->port_output)
121  return w2->port_output;
122 
123  if (w1->name[0] != w2->name[0])
124  return w2->name[0] == '\\';
125 
126  int attrs1 = count_nontrivial_wire_attrs(w1);
127  int attrs2 = count_nontrivial_wire_attrs(w2);
128 
129  if (attrs1 != attrs2)
130  return attrs2 > attrs1;
131 
132  return w2->name < w1->name;
133 }
RTLIL::Wire * wire
Definition: rtlil.h:907
int count_nontrivial_wire_attrs(RTLIL::Wire *w)
Definition: opt_clean.cc:92
bool port_input
Definition: rtlil.h:827
bool port_output
Definition: rtlil.h:827
bool check_any(RTLIL::SigSpec sig)
Definition: sigtools.h:100
RTLIL::IdString name
Definition: rtlil.h:825
#define NULL

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

int count_nontrivial_wire_attrs ( RTLIL::Wire w)

Definition at line 92 of file opt_clean.cc.

93 {
94  int count = w->attributes.size();
95  count -= w->attributes.count("\\src");
96  count -= w->attributes.count("\\unused_bits");
97  return count;
98 }

+ Here is the caller graph for this function:

void rmunused_module ( RTLIL::Module module,
bool  purge_mode,
bool  verbose 
)

Definition at line 284 of file opt_clean.cc.

285 {
286  if (verbose)
287  log("Finding unused cells or wires in module %s..\n", module->name.c_str());
288 
289  std::vector<RTLIL::Cell*> delcells;
290  for (auto cell : module->cells())
291  if (cell->type.in("$pos", "$_BUF_")) {
292  bool is_signed = cell->type == "$pos" && cell->getParam("\\A_SIGNED").as_bool();
293  RTLIL::SigSpec a = cell->getPort("\\A");
294  RTLIL::SigSpec y = cell->getPort("\\Y");
295  a.extend_u0(GetSize(y), is_signed);
296  module->connect(y, a);
297  delcells.push_back(cell);
298  }
299  for (auto cell : delcells)
300  module->remove(cell);
301 
302  rmunused_module_cells(module, verbose);
303  rmunused_module_signals(module, purge_mode, verbose);
304 }
const char * c_str() const
Definition: rtlil.h:178
void rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool verbose)
Definition: opt_clean.cc:147
void rmunused_module_cells(RTLIL::Module *module, bool verbose)
Definition: opt_clean.cc:36
void extend_u0(int width, bool is_signed=false)
Definition: rtlil.cc:2612
void connect(const RTLIL::SigSig &conn)
Definition: rtlil.cc:1278
int GetSize(RTLIL::Wire *wire)
Definition: yosys.cc:334
RTLIL::IdString name
Definition: rtlil.h:599
RTLIL::ObjRange< RTLIL::Cell * > cells()
Definition: rtlil.h:641
void remove(const std::set< RTLIL::Wire * > &wires)
Definition: rtlil.cc:1158
void log(const char *format,...)
Definition: log.cc:180

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void rmunused_module_cells ( RTLIL::Module module,
bool  verbose 
)

Definition at line 36 of file opt_clean.cc.

37 {
38  SigMap sigmap(module);
39  std::set<RTLIL::Cell*, RTLIL::sort_by_name_id<RTLIL::Cell>> queue, unused;
40 
41  SigSet<RTLIL::Cell*> wire2driver;
42  for (auto &it : module->cells_) {
43  RTLIL::Cell *cell = it.second;
44  for (auto &it2 : cell->connections()) {
45  if (!ct.cell_input(cell->type, it2.first))
46  wire2driver.insert(sigmap(it2.second), cell);
47  }
48  if (cell->type == "$memwr" || cell->type == "$assert" || cell->has_keep_attr())
49  queue.insert(cell);
50  unused.insert(cell);
51  }
52 
53  for (auto &it : module->wires_) {
54  RTLIL::Wire *wire = it.second;
55  if (wire->port_output || wire->get_bool_attribute("\\keep")) {
56  std::set<RTLIL::Cell*> cell_list;
57  wire2driver.find(sigmap(wire), cell_list);
58  for (auto cell : cell_list)
59  queue.insert(cell);
60  }
61  }
62 
63  while (!queue.empty())
64  {
65  std::set<RTLIL::Cell*, RTLIL::sort_by_name_id<RTLIL::Cell>> new_queue;
66  for (auto cell : queue)
67  unused.erase(cell);
68  for (auto cell : queue) {
69  for (auto &it : cell->connections()) {
70  if (!ct.cell_output(cell->type, it.first)) {
71  std::set<RTLIL::Cell*> cell_list;
72  wire2driver.find(sigmap(it.second), cell_list);
73  for (auto c : cell_list) {
74  if (unused.count(c))
75  new_queue.insert(c);
76  }
77  }
78  }
79  }
80  queue.swap(new_queue);
81  }
82 
83  for (auto cell : unused) {
84  if (verbose)
85  log(" removing unused `%s' cell `%s'.\n", cell->type.c_str(), cell->name.c_str());
86  module->design->scratchpad_set_bool("opt.did_something", true);
87  module->remove(cell);
89  }
90 }
const char * c_str() const
Definition: rtlil.h:178
CellTypes ct
Definition: opt_clean.cc:33
std::map< RTLIL::IdString, RTLIL::Wire * > wires_
Definition: rtlil.h:595
RTLIL::IdString name
Definition: rtlil.h:853
RTLIL::IdString type
Definition: rtlil.h:854
bool port_output
Definition: rtlil.h:827
bool cell_output(RTLIL::IdString type, RTLIL::IdString port)
Definition: celltypes.h:193
int count_rm_cells
Definition: opt_clean.cc:34
std::map< RTLIL::IdString, RTLIL::Cell * > cells_
Definition: rtlil.h:596
void remove(const std::set< RTLIL::Wire * > &wires)
Definition: rtlil.cc:1158
void log(const char *format,...)
Definition: log.cc:180
void scratchpad_set_bool(std::string varname, bool value)
Definition: rtlil.cc:296
bool cell_input(RTLIL::IdString type, RTLIL::IdString port)
Definition: celltypes.h:199
RTLIL::Design * design
Definition: rtlil.h:589
const std::map< RTLIL::IdString, RTLIL::SigSpec > & connections() const
Definition: rtlil.cc:1814
void find(RTLIL::SigSpec sig, std::set< T > &result)
Definition: sigtools.h:187
void insert(RTLIL::SigSpec sig, T data)
Definition: sigtools.h:152
bool has_keep_attr() const
Definition: rtlil.h:875

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void rmunused_module_signals ( RTLIL::Module module,
bool  purge_mode,
bool  verbose 
)

Definition at line 147 of file opt_clean.cc.

148 {
149  SigPool register_signals;
150  SigPool connected_signals;
151 
152  if (!purge_mode)
153  for (auto &it : module->cells_) {
154  RTLIL::Cell *cell = it.second;
155  if (ct_reg.cell_known(cell->type))
156  for (auto &it2 : cell->connections())
157  if (ct_reg.cell_output(cell->type, it2.first))
158  register_signals.add(it2.second);
159  for (auto &it2 : cell->connections())
160  connected_signals.add(it2.second);
161  }
162 
163  SigMap assign_map(module);
164  std::set<RTLIL::SigSpec> direct_sigs;
165  std::set<RTLIL::Wire*> direct_wires;
166  for (auto &it : module->cells_) {
167  RTLIL::Cell *cell = it.second;
168  if (ct_all.cell_known(cell->type))
169  for (auto &it2 : cell->connections())
170  if (ct_all.cell_output(cell->type, it2.first))
171  direct_sigs.insert(assign_map(it2.second));
172  }
173  for (auto &it : module->wires_) {
174  if (direct_sigs.count(assign_map(it.second)) || it.second->port_input)
175  direct_wires.insert(it.second);
176  }
177 
178  for (auto &it : module->wires_) {
179  RTLIL::Wire *wire = it.second;
180  for (int i = 0; i < wire->width; i++) {
181  RTLIL::SigBit s1 = RTLIL::SigBit(wire, i), s2 = assign_map(s1);
182  if (!compare_signals(s1, s2, register_signals, connected_signals, direct_wires))
183  assign_map.add(s1);
184  }
185  }
186 
187  module->connections_.clear();
188 
189  SigPool used_signals;
190  SigPool used_signals_nodrivers;
191  for (auto &it : module->cells_) {
192  RTLIL::Cell *cell = it.second;
193  for (auto &it2 : cell->connections_) {
194  assign_map.apply(it2.second);
195  used_signals.add(it2.second);
196  if (!ct.cell_output(cell->type, it2.first))
197  used_signals_nodrivers.add(it2.second);
198  }
199  }
200  for (auto &it : module->wires_) {
201  RTLIL::Wire *wire = it.second;
202  if (wire->port_id > 0) {
203  RTLIL::SigSpec sig = RTLIL::SigSpec(wire);
204  assign_map.apply(sig);
205  used_signals.add(sig);
206  if (!wire->port_input)
207  used_signals_nodrivers.add(sig);
208  }
209  if (wire->get_bool_attribute("\\keep")) {
210  RTLIL::SigSpec sig = RTLIL::SigSpec(wire);
211  assign_map.apply(sig);
212  used_signals.add(sig);
213  }
214  }
215 
216  std::vector<RTLIL::Wire*> maybe_del_wires;
217  for (auto wire : module->wires())
218  {
219  if ((!purge_mode && check_public_name(wire->name)) || wire->port_id != 0 || wire->get_bool_attribute("\\keep")) {
220  RTLIL::SigSpec s1 = RTLIL::SigSpec(wire), s2 = s1;
221  assign_map.apply(s2);
222  if (!used_signals.check_any(s2) && wire->port_id == 0 && !wire->get_bool_attribute("\\keep")) {
223  maybe_del_wires.push_back(wire);
224  } else {
225  log_assert(GetSize(s1) == GetSize(s2));
226  RTLIL::SigSig new_conn;
227  for (int i = 0; i < GetSize(s1); i++)
228  if (s1[i] != s2[i]) {
229  new_conn.first.append_bit(s1[i]);
230  new_conn.second.append_bit(s2[i]);
231  }
232  if (new_conn.first.size() > 0) {
233  used_signals.add(new_conn.first);
234  used_signals.add(new_conn.second);
235  module->connect(new_conn);
236  }
237  }
238  } else {
239  if (!used_signals.check_any(RTLIL::SigSpec(wire)))
240  maybe_del_wires.push_back(wire);
241  }
242 
244  if (!used_signals_nodrivers.check_any(sig)) {
245  std::string unused_bits;
246  for (int i = 0; i < GetSize(sig); i++) {
247  if (sig[i].wire == NULL)
248  continue;
249  if (!used_signals_nodrivers.check(sig[i])) {
250  if (!unused_bits.empty())
251  unused_bits += " ";
252  unused_bits += stringf("%d", i);
253  }
254  }
255  if (unused_bits.empty() || wire->port_id != 0)
256  wire->attributes.erase("\\unused_bits");
257  else
258  wire->attributes["\\unused_bits"] = RTLIL::Const(unused_bits);
259  } else {
260  wire->attributes.erase("\\unused_bits");
261  }
262  }
263 
264 
265  std::set<RTLIL::Wire*> del_wires;
266 
267  int del_wires_count = 0;
268  for (auto wire : maybe_del_wires)
269  if (!used_signals.check_any(RTLIL::SigSpec(wire))) {
270  if (check_public_name(wire->name) && verbose) {
271  log(" removing unused non-port wire %s.\n", wire->name.c_str());
272  del_wires_count++;
273  }
274  del_wires.insert(wire);
275  }
276 
277  module->remove(del_wires);
278  count_rm_wires += del_wires.size();;
279 
280  if (del_wires_count > 0)
281  log(" removed %d unused temporary wires.\n", del_wires_count);
282 }
const char * c_str() const
Definition: rtlil.h:178
CellTypes ct_reg
Definition: opt_clean.cc:33
std::string stringf(const char *fmt,...)
Definition: yosys.cc:58
CellTypes ct
Definition: opt_clean.cc:33
CellTypes ct_all
Definition: opt_clean.cc:33
std::map< RTLIL::IdString, RTLIL::Wire * > wires_
Definition: rtlil.h:595
bool compare_signals(RTLIL::SigBit &s1, RTLIL::SigBit &s2, SigPool &regs, SigPool &conns, std::set< RTLIL::Wire * > &direct_wires)
Definition: opt_clean.cc:100
bool port_input
Definition: rtlil.h:827
RTLIL::ObjRange< RTLIL::Wire * > wires()
Definition: rtlil.h:640
int width
Definition: rtlil.h:826
int port_id
Definition: rtlil.h:826
RTLIL::IdString type
Definition: rtlil.h:854
std::vector< RTLIL::SigSig > connections_
Definition: rtlil.h:597
void apply(RTLIL::SigBit &bit) const
Definition: sigtools.h:383
SigMap assign_map
Definition: abc.cc:93
bool check_public_name(RTLIL::IdString id)
Definition: opt_clean.cc:135
bool cell_known(RTLIL::IdString type)
Definition: celltypes.h:188
bool check_any(RTLIL::SigSpec sig)
Definition: sigtools.h:100
void connect(const RTLIL::SigSig &conn)
Definition: rtlil.cc:1278
bool cell_output(RTLIL::IdString type, RTLIL::IdString port)
Definition: celltypes.h:193
int GetSize(RTLIL::Wire *wire)
Definition: yosys.cc:334
#define log_assert(_assert_expr_)
Definition: log.h:85
RTLIL::IdString name
Definition: rtlil.h:825
void add(RTLIL::SigSpec sig)
Definition: sigtools.h:41
bool check(RTLIL::SigBit bit)
Definition: sigtools.h:95
#define NULL
std::map< RTLIL::IdString, RTLIL::Cell * > cells_
Definition: rtlil.h:596
void remove(const std::set< RTLIL::Wire * > &wires)
Definition: rtlil.cc:1158
int count_rm_wires
Definition: opt_clean.cc:34
void log(const char *format,...)
Definition: log.cc:180
void add(RTLIL::SigSpec from, RTLIL::SigSpec to)
Definition: sigtools.h:347
std::map< RTLIL::IdString, RTLIL::SigSpec > connections_
Definition: rtlil.h:855
std::pair< SigSpec, SigSpec > SigSig
Definition: rtlil.h:71
const std::map< RTLIL::IdString, RTLIL::SigSpec > & connections() const
Definition: rtlil.cc:1814

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Variable Documentation

int count_rm_cells

Definition at line 34 of file opt_clean.cc.

int count_rm_wires

Definition at line 34 of file opt_clean.cc.

Definition at line 33 of file opt_clean.cc.

CellTypes ct_all

Definition at line 33 of file opt_clean.cc.

CellTypes ct_reg

Definition at line 33 of file opt_clean.cc.