proc_prune: fix handling of exactly identical assigns.
authorwhitequark <whitequark@whitequark.org>
Thu, 8 Aug 2019 05:28:01 +0000 (05:28 +0000)
committerwhitequark <whitequark@whitequark.org>
Thu, 8 Aug 2019 05:32:35 +0000 (05:32 +0000)
Before this commit, in a process like:
   process $proc$bug.v:8$3
     assign $foo \bar
     switch \sel
       case 1'1
         assign $foo 1'1
         assign $foo 1'1
       case
         assign $foo 1'0
     end
   end
both of the "assign $foo 1'1" would incorrectly be removed.

Fixes #1243.

passes/proc/proc_prune.cc

index b47ee79c2fd5136f38eb6148e981ac1e17d042a9..d4aee9df02d12c5a5f38fc798e2c7ab2c4689567 100644 (file)
@@ -65,8 +65,7 @@ struct PruneWorker
                        pool<RTLIL::SigBit> sw_assigned = do_switch((*it), assigned, affected);
                        assigned.insert(sw_assigned.begin(), sw_assigned.end());
                }
-               pool<RTLIL::SigSig> remove;
-               for (auto it = cs->actions.rbegin(); it != cs->actions.rend(); ++it) {
+               for (auto it = cs->actions.rbegin(); it != cs->actions.rend(); ) {
                        RTLIL::SigSpec lhs = sigmap(it->first);
                        bool redundant = true;
                        for (auto &bit : lhs) {
@@ -75,9 +74,10 @@ struct PruneWorker
                                        break;
                                }
                        }
+                       bool remove = false;
                        if (redundant) {
                                removed_count++;
-                               remove.insert(*it);
+                               remove = true;
                        } else {
                                if (root) {
                                        bool promotable = true;
@@ -99,7 +99,7 @@ struct PruneWorker
                                                }
                                                promoted_count++;
                                                module->connect(conn);
-                                               remove.insert(*it);
+                                               remove = true;
                                        }
                                }
                                for (auto &bit : lhs)
@@ -109,11 +109,9 @@ struct PruneWorker
                                        if (bit.wire)
                                                affected.insert(bit);
                        }
-               }
-               for (auto it = cs->actions.begin(); it != cs->actions.end(); ) {
-                       if (remove[*it]) {
-                               it = cs->actions.erase(it);
-                       } else it++;
+                       if (remove)
+                               cs->actions.erase((it++).base() - 1);
+                       else it++;
                }
                return assigned;
        }