diff options
| -rw-r--r-- | kernel/rtlil.cc | 10 | ||||
| -rw-r--r-- | kernel/rtlil.h | 4 | ||||
| -rw-r--r-- | passes/proc/proc_clean.cc | 34 | 
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;  | 
