Merge pull request #761 from whitequark/proc_clean_partial

proc_clean: remove any empty cases, if possible to do safely
This commit is contained in:
Clifford Wolf 2018-12-23 16:16:06 +01:00 committed by GitHub
commit 245724a504
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 42 additions and 10 deletions

View File

@ -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;

View File

@ -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;
};

View File

@ -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) {
if (all_fully_def)
{
for (auto cs = sw->cases.begin(); cs != sw->cases.end();)
{
if ((*cs)->empty())
{
did_something = true;
for (auto cs : sw->cases)
delete cs;
sw->cases.clear();
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;