aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/rtlil.cc10
-rw-r--r--kernel/rtlil.h4
-rw-r--r--passes/proc/proc_clean.cc34
3 files changed, 42 insertions, 6 deletions
diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc
index 14259f8ed..8404db5e9 100644
--- a/kernel/rtlil.cc
+++ b/kernel/rtlil.cc
@@ -3793,6 +3793,11 @@ RTLIL::CaseRule::~CaseRule()
delete *it;
}
+bool RTLIL::CaseRule::empty() const
+{
+ return actions.empty() && switches.empty();
+}
+
RTLIL::CaseRule *RTLIL::CaseRule::clone() const
{
RTLIL::CaseRule *new_caserule = new RTLIL::CaseRule;
@@ -3809,6 +3814,11 @@ RTLIL::SwitchRule::~SwitchRule()
delete *it;
}
+bool RTLIL::SwitchRule::empty() const
+{
+ return cases.empty();
+}
+
RTLIL::SwitchRule *RTLIL::SwitchRule::clone() const
{
RTLIL::SwitchRule *new_switchrule = new RTLIL::SwitchRule;
diff --git a/kernel/rtlil.h b/kernel/rtlil.h
index 276540aa1..f877622aa 100644
--- a/kernel/rtlil.h
+++ b/kernel/rtlil.h
@@ -1227,6 +1227,8 @@ struct RTLIL::CaseRule
~CaseRule();
void optimize();
+ bool empty() const;
+
template<typename T> void rewrite_sigspecs(T &functor);
RTLIL::CaseRule *clone() const;
};
@@ -1238,6 +1240,8 @@ struct RTLIL::SwitchRule : public RTLIL::AttrObject
~SwitchRule();
+ bool empty() const;
+
template<typename T> void rewrite_sigspecs(T &functor);
RTLIL::SwitchRule *clone() const;
};
diff --git a/passes/proc/proc_clean.cc b/passes/proc/proc_clean.cc
index 477d1ac60..3919e4b9c 100644
--- a/passes/proc/proc_clean.cc
+++ b/passes/proc/proc_clean.cc
@@ -77,14 +77,36 @@ void proc_clean_switch(RTLIL::SwitchRule *sw, RTLIL::CaseRule *parent, bool &did
}
else
{
- for (auto cs : sw->cases) {
+ bool all_fully_def = true;
+ for (auto cs : sw->cases)
+ {
if (max_depth != 0)
proc_clean_case(cs, did_something, count, max_depth-1);
+ for (auto cmp : cs->compare)
+ if (!cmp.is_fully_def())
+ all_fully_def = false;
}
- while (!sw->cases.empty() && (sw->cases.back()->actions.empty() && sw->cases.back()->switches.empty())) {
- did_something = true;
- delete sw->cases.back();
- sw->cases.pop_back();
+ if (all_fully_def)
+ {
+ for (auto cs = sw->cases.begin(); cs != sw->cases.end();)
+ {
+ if ((*cs)->empty())
+ {
+ did_something = true;
+ delete *cs;
+ cs = sw->cases.erase(cs);
+ }
+ else ++cs;
+ }
+ }
+ else
+ {
+ while (!sw->cases.empty() && sw->cases.back()->empty())
+ {
+ did_something = true;
+ delete sw->cases.back();
+ sw->cases.pop_back();
+ }
}
}
}
@@ -102,7 +124,7 @@ void proc_clean_case(RTLIL::CaseRule *cs, bool &did_something, int &count, int m
}
for (size_t i = 0; i < cs->switches.size(); i++) {
RTLIL::SwitchRule *sw = cs->switches[i];
- if (sw->cases.size() == 0) {
+ if (sw->empty()) {
cs->switches.erase(cs->switches.begin() + (i--));
did_something = true;
delete sw;