Fix leak removing cells during ABC integration; also preserve attr
authorEddie Hung <eddie@fpgeh.com>
Mon, 17 Jun 2019 19:54:24 +0000 (12:54 -0700)
committerEddie Hung <eddie@fpgeh.com>
Mon, 17 Jun 2019 19:54:24 +0000 (12:54 -0700)
kernel/rtlil.cc
kernel/rtlil.h
passes/techmap/abc9.cc

index 790ba52a30f70b61ab2e4ed864b13bd90e1975c7..f732b56b0ea74edbb7be62dc706c39374f3eaa79 100644 (file)
@@ -1565,13 +1565,21 @@ void RTLIL::Module::remove(const pool<RTLIL::Wire*> &wires)
 
 void RTLIL::Module::remove(RTLIL::Cell *cell)
 {
+       auto it = cells_.find(cell->name);
+       log_assert(it != cells_.end());
+       remove(it);
+}
+
+dict<RTLIL::IdString, RTLIL::Cell*>::iterator RTLIL::Module::remove(dict<RTLIL::IdString, RTLIL::Cell*>::iterator it)
+{
+       RTLIL::Cell *cell = it->second;
        while (!cell->connections_.empty())
                cell->unsetPort(cell->connections_.begin()->first);
 
-       log_assert(cells_.count(cell->name) != 0);
        log_assert(refcount_cells_ == 0);
-       cells_.erase(cell->name);
+       it = cells_.erase(it);
        delete cell;
+       return it;
 }
 
 void RTLIL::Module::rename(RTLIL::Wire *wire, RTLIL::IdString new_name)
index f4fcf5dcfb6e2c4fe8928f98c5b93fceb293818a..4a0f8b4f86910b202f3bb564a6b39bafcf9d54f5 100644 (file)
@@ -1040,6 +1040,7 @@ public:
        // Removing wires is expensive. If you have to remove wires, remove them all at once.
        void remove(const pool<RTLIL::Wire*> &wires);
        void remove(RTLIL::Cell *cell);
+       dict<RTLIL::IdString, RTLIL::Cell*>::iterator remove(dict<RTLIL::IdString, RTLIL::Cell*>::iterator it);
 
        void rename(RTLIL::Wire *wire, RTLIL::IdString new_name);
        void rename(RTLIL::Cell *cell, RTLIL::IdString new_name);
index 54aba3b18aa228af99912d1eb381182903be481d..9c4e6bb39846e644e8bb99a766deaea918c17e4a 100644 (file)
@@ -500,24 +500,6 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri
                        }
                }
 
-               // Remove all AND, NOT, and ABC box instances
-               // in preparation for stitching mapped_mod in
-               dict<IdString, decltype(RTLIL::Cell::parameters)> erased_boxes;
-               for (auto it = module->cells_.begin(); it != module->cells_.end(); ) {
-                       RTLIL::Cell* cell = it->second;
-                       if (cell->type.in("$_AND_", "$_NOT_")) {
-                               it = module->cells_.erase(it);
-                               continue;
-                       }
-                       RTLIL::Module* box_module = design->module(cell->type);
-                       if (box_module && box_module->attributes.count("\\abc_box_id")) {
-                               erased_boxes.insert(std::make_pair(it->first, std::move(cell->parameters)));
-                               it = module->cells_.erase(it);
-                               continue;
-                       }
-                       ++it;
-               }
-               // Do the same for module connections
                for (auto &it : module->connections_) {
                        auto &signal = it.first;
                        auto bits = signal.bits();
@@ -527,6 +509,19 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri
                        signal = std::move(bits);
                }
 
+               vector<RTLIL::Cell*> boxes;
+               for (auto it = module->cells_.begin(); it != module->cells_.end(); ) {
+                       RTLIL::Cell* cell = it->second;
+                       if (cell->type.in("$_AND_", "$_NOT_", "$__ABC_FF_")) {
+                               it = module->remove(it);
+                               continue;
+                       }
+                       RTLIL::Module* box_module = design->module(cell->type);
+                       if (box_module && box_module->attributes.count("\\abc_box_id"))
+                               boxes.emplace_back(it->second);
+                       ++it;
+               }
+
                std::map<std::string, int> cell_stats;
                for (auto c : mapped_mod->cells())
                {
@@ -595,18 +590,21 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri
                                        SigSpec my_a = module->wires_[remap_name(c->getPort("\\A").as_wire()->name)];
                                        SigSpec my_y = module->wires_[remap_name(c->getPort("\\Y").as_wire()->name)];
                                        module->connect(my_y, my_a);
+                                        if (markgroups) c->attributes["\\abcgroup"] = map_autoidx;
                                        continue;
                                }
                        }
-                       else {
-                               auto it = erased_boxes.find(c->name);
-                               log_assert(it != erased_boxes.end());
-                               c->parameters = std::move(it->second);
-                       }
 
-                       RTLIL::Cellcell = module->addCell(remap_name(c->name), c->type);
+                       RTLIL::Cell *cell = module->addCell(remap_name(c->name), c->type);
                        if (markgroups) cell->attributes["\\abcgroup"] = map_autoidx;
-                       cell->parameters = c->parameters;
+                        RTLIL::Cell *existing_cell = module->cell(c->name);
+                        if (existing_cell) {
+                                cell->parameters = std::move(existing_cell->parameters);
+                                cell->attributes = std::move(existing_cell->attributes);
+                        }
+                        else {
+                                cell->parameters = std::move(c->parameters);
+                        }
                        for (auto &conn : c->connections()) {
                                RTLIL::SigSpec newsig;
                                for (auto c : conn.second.chunks()) {
@@ -621,6 +619,9 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri
                        }
                }
 
+                for (auto cell : boxes)
+                        module->remove(cell);
+
                // Copy connections (and rename) from mapped_mod to module
                for (auto conn : mapped_mod->connections()) {
                        if (!conn.first.is_fully_const()) {