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; delete *it;
} }
bool RTLIL::CaseRule::empty() const
{
return actions.empty() && switches.empty();
}
RTLIL::CaseRule *RTLIL::CaseRule::clone() const RTLIL::CaseRule *RTLIL::CaseRule::clone() const
{ {
RTLIL::CaseRule *new_caserule = new RTLIL::CaseRule; RTLIL::CaseRule *new_caserule = new RTLIL::CaseRule;
@ -3809,6 +3814,11 @@ RTLIL::SwitchRule::~SwitchRule()
delete *it; delete *it;
} }
bool RTLIL::SwitchRule::empty() const
{
return cases.empty();
}
RTLIL::SwitchRule *RTLIL::SwitchRule::clone() const RTLIL::SwitchRule *RTLIL::SwitchRule::clone() const
{ {
RTLIL::SwitchRule *new_switchrule = new RTLIL::SwitchRule; RTLIL::SwitchRule *new_switchrule = new RTLIL::SwitchRule;

View File

@ -1227,6 +1227,8 @@ struct RTLIL::CaseRule
~CaseRule(); ~CaseRule();
void optimize(); void optimize();
bool empty() const;
template<typename T> void rewrite_sigspecs(T &functor); template<typename T> void rewrite_sigspecs(T &functor);
RTLIL::CaseRule *clone() const; RTLIL::CaseRule *clone() const;
}; };
@ -1238,6 +1240,8 @@ struct RTLIL::SwitchRule : public RTLIL::AttrObject
~SwitchRule(); ~SwitchRule();
bool empty() const;
template<typename T> void rewrite_sigspecs(T &functor); template<typename T> void rewrite_sigspecs(T &functor);
RTLIL::SwitchRule *clone() const; RTLIL::SwitchRule *clone() const;
}; };

View File

@ -77,18 +77,36 @@ void proc_clean_switch(RTLIL::SwitchRule *sw, RTLIL::CaseRule *parent, bool &did
} }
else else
{ {
bool all_cases_are_empty = true; bool all_fully_def = true;
for (auto cs : sw->cases) { for (auto cs : sw->cases)
if (cs->actions.size() != 0 || cs->switches.size() != 0) {
all_cases_are_empty = false;
if (max_depth != 0) if (max_depth != 0)
proc_clean_case(cs, did_something, count, max_depth-1); 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)
did_something = true; {
for (auto cs : sw->cases) for (auto cs = sw->cases.begin(); cs != sw->cases.end();)
delete cs; {
sw->cases.clear(); 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++) { for (size_t i = 0; i < cs->switches.size(); i++) {
RTLIL::SwitchRule *sw = cs->switches[i]; RTLIL::SwitchRule *sw = cs->switches[i];
if (sw->cases.size() == 0) { if (sw->empty()) {
cs->switches.erase(cs->switches.begin() + (i--)); cs->switches.erase(cs->switches.begin() + (i--));
did_something = true; did_something = true;
delete sw; delete sw;