diff options
author | Clifford Wolf <clifford@clifford.at> | 2018-12-23 16:16:06 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-12-23 16:16:06 +0100 |
commit | 245724a504528156485bbb32710b5e5444899ce1 (patch) | |
tree | 0f40d2aad76556901949dff62905a2eb7e40b331 | |
parent | 6dad1913779f729222f65e1098a4facb36c5837a (diff) | |
parent | 18291c20d2b17689729d9c36b08967e928e4e32a (diff) | |
download | yosys-245724a504528156485bbb32710b5e5444899ce1.tar.gz yosys-245724a504528156485bbb32710b5e5444899ce1.tar.bz2 yosys-245724a504528156485bbb32710b5e5444899ce1.zip |
Merge pull request #761 from whitequark/proc_clean_partial
proc_clean: remove any empty cases, if possible to do safely
-rw-r--r-- | kernel/rtlil.cc | 10 | ||||
-rw-r--r-- | kernel/rtlil.h | 4 | ||||
-rw-r--r-- | passes/proc/proc_clean.cc | 38 |
3 files changed, 42 insertions, 10 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 b9e43d1db..3919e4b9c 100644 --- a/passes/proc/proc_clean.cc +++ b/passes/proc/proc_clean.cc @@ -77,18 +77,36 @@ void proc_clean_switch(RTLIL::SwitchRule *sw, RTLIL::CaseRule *parent, bool &did } else { - bool all_cases_are_empty = true; - for (auto cs : sw->cases) { - if (cs->actions.size() != 0 || cs->switches.size() != 0) - all_cases_are_empty = false; + 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; } - if (all_cases_are_empty) { - did_something = true; - for (auto cs : sw->cases) - delete cs; - sw->cases.clear(); + 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(); + } } } } @@ -106,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; |