From acb435b6cf583b6c18f405a9c92566c4e9fb85e5 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 18 Aug 2014 00:02:30 +0200 Subject: [PATCH] Added const folding of AST_CASE to AST simplifier --- frontends/ast/ast.cc | 8 ++++++++ frontends/ast/ast.h | 1 + frontends/ast/simplify.cc | 33 ++++++++++++++++++++++++++++++++- 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 6ac771447..0ea38b506 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -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 bits = this->bits; diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 6ea241fa9..ef54d76f4 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -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 diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 76d1f8270..85671213d 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -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 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 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()) {