Added const folding of AST_CASE to AST simplifier

This commit is contained in:
Clifford Wolf 2014-08-18 00:02:30 +02:00
parent aa7a3ed83f
commit acb435b6cf
3 changed files with 41 additions and 1 deletions

View File

@ -722,6 +722,14 @@ AstNode *AstNode::mkconst_str(const std::string &str)
return node;
}
bool AstNode::bits_only_01()
{
for (auto bit : bits)
if (bit != RTLIL::S0 && bit != RTLIL::S1)
return false;
return true;
}
RTLIL::Const AstNode::bitsAsConst(int width, bool is_signed)
{
std::vector<RTLIL::State> bits = this->bits;

View File

@ -246,6 +246,7 @@ namespace AST
RTLIL::Const bitsAsConst(int width = -1);
RTLIL::Const asAttrConst();
RTLIL::Const asParaConst();
bool bits_only_01();
bool asBool();
// helper functions for real valued const eval

View File

@ -1567,7 +1567,7 @@ skip_dynamic_range_lvalue_expansion:;
}
// perform const folding when activated
if (const_fold && newNode == NULL)
if (const_fold)
{
bool string_op;
std::vector<RTLIL::State> tmp_bits;
@ -1746,6 +1746,37 @@ skip_dynamic_range_lvalue_expansion:;
newNode->realvalue = -children[0]->asReal(sign_hint);
}
break;
case AST_CASE:
if (children[0]->type == AST_CONSTANT && children[0]->bits_only_01()) {
std::vector<AstNode*> new_children;
new_children.push_back(children[0]);
for (int i = 1; i < SIZE(children); i++) {
AstNode *child = children[i];
log_assert(child->type == AST_COND);
for (auto v : child->children) {
if (v->type == AST_DEFAULT)
goto keep_const_cond;
if (v->type == AST_BLOCK)
continue;
if (v->type == AST_CONSTANT && v->bits_only_01()) {
if (v->bits == children[0]->bits) {
while (i+1 < SIZE(children))
delete children[++i];
goto keep_const_cond;
}
continue;
}
goto keep_const_cond;
}
if (0)
keep_const_cond:
new_children.push_back(child);
else
delete child;
}
new_children.swap(children);
}
break;
case AST_TERNARY:
if (children[0]->isConst())
{