Factor out some common eval_tree code.

The eval_tree() function is identical in most of the NetEBinary and
NetEUnary sub-classes.
This commit is contained in:
Martin Whitaker 2013-02-03 23:58:06 +00:00 committed by Cary R
parent afd23d13d5
commit f3a51fdfd1
3 changed files with 73 additions and 223 deletions

View File

@ -77,8 +77,28 @@ static bool get_real_arguments(const NetExpr*le, const NetExpr*re,
return true;
}
NetExpr* NetEBinary::eval_tree()
{
eval_expr(left_);
eval_expr(right_);
NetExpr*res = eval_arguments_(left_, right_);
if (res != 0) {
res->set_line(*this);
if (debug_eval_tree) {
cerr << get_fileline() << ": debug: Evaluated";
if (left_->expr_type() == IVL_VT_REAL ||
right_->expr_type() == IVL_VT_REAL)
cerr << " (real)";
cerr << ": " << *this << " --> " << *res << endl;
}
}
return res;
}
NetExpr* NetEBinary::eval_arguments_(const NetExpr*, const NetExpr*) const
{
// this method should be overridden in all sub-classes
ivl_assert(*this, 0);
return 0;
}
@ -106,12 +126,6 @@ NetECReal* NetEBAdd::eval_tree_real_(const NetExpr*l, const NetExpr*r) const
NetECReal*res = new NetECReal( verireal(res_val) );
ivl_assert(*this, res);
res->set_line(*this);
if (debug_eval_tree)
cerr << get_fileline() << ": debug: Evaluated (real): " << *this
<< " --> " << *res << endl;
return res;
}
@ -122,8 +136,17 @@ NetExpr* NetEBAdd::eval_tree()
// First try to elaborate the expression completely.
NetExpr*res = eval_arguments_(left_,right_);
if (res != 0)
if (res != 0) {
res->set_line(*this);
if (debug_eval_tree) {
cerr << get_fileline() << ": debug: Evaluated";
if (left_->expr_type() == IVL_VT_REAL ||
right_->expr_type() == IVL_VT_REAL)
cerr << " (real)";
cerr << ": " << *this << " --> " << *res << endl;
}
return res;
}
// If the expression type is real, then do not attempt the
// following alternative processing.
@ -213,12 +236,6 @@ NetExpr* NetEBAdd::eval_arguments_(const NetExpr*l, const NetExpr*r) const
NetEConst *res = new NetEConst(val);
ivl_assert(*this, res);
res->set_line(*this);
if (debug_eval_tree)
cerr << get_fileline() << ": debug: Evaluated: " << *this
<< " --> " << *res << endl;
return res;
}
@ -227,14 +244,6 @@ NetExpr* NetEBAdd::eval_arguments_(const NetExpr*l, const NetExpr*r) const
return 0;
}
NetEConst* NetEBBits::eval_tree()
{
eval_expr(left_);
eval_expr(right_);
return eval_arguments_(left_, right_);
}
NetEConst* NetEBBits::eval_arguments_(const NetExpr*l, const NetExpr*r) const
{
const NetEConst*lc = dynamic_cast<const NetEConst*>(l);
@ -246,12 +255,16 @@ NetEConst* NetEBBits::eval_arguments_(const NetExpr*l, const NetExpr*r) const
known to be 0. */
if ((op() == '&') && (lc->value() == verinum(0))) {
verinum res (verinum::V0, expr_width());
return new NetEConst(res);
NetEConst*tmp = new NetEConst(res);
ivl_assert(*this, tmp);
return tmp;
}
if ((op() == '&') && (rc->value() == verinum(0))) {
verinum res (verinum::V0, expr_width());
return new NetEConst(res);
NetEConst*tmp = new NetEConst(res);
ivl_assert(*this, tmp);
return tmp;
}
verinum lval = lc->value();
@ -293,12 +306,6 @@ NetEConst* NetEBBits::eval_arguments_(const NetExpr*l, const NetExpr*r) const
NetEConst*tmp = new NetEConst(res);
ivl_assert(*this, tmp);
tmp->set_line(*this);
if (debug_eval_tree)
cerr << get_fileline() << ": debug: Evaluated: " << *this
<< " --> " << *tmp << endl;
return tmp;
}
@ -747,26 +754,6 @@ NetEConst* NetEBComp::eval_arguments_(const NetExpr*l, const NetExpr*r) const
break;
}
return res;
}
NetEConst* NetEBComp::eval_tree()
{
eval_expr(left_);
eval_expr(right_);
NetEConst*res = eval_arguments_(left_, right_);
if (res == 0) return 0;
res->set_line(*this);
if (debug_eval_tree) {
cerr << get_fileline() << ": debug: Evaluated";
if (left_->expr_type() == IVL_VT_REAL ||
right_->expr_type() == IVL_VT_REAL)
cerr << " (real)";
cerr << ": " << *this << " --> " << *res << endl;
}
return res;
}
@ -793,27 +780,9 @@ NetExpr* NetEBDiv::eval_tree_real_(const NetExpr*l, const NetExpr*r) const
}
NetECReal*res = new NetECReal( verireal(res_val) );
ivl_assert(*this, res);
res->set_line(*this);
if (debug_eval_tree)
cerr << get_fileline() << ": debug: Evaluated (real): " << *this
<< " --> " << *res << endl;
return res;
}
/*
* The NetEBDiv operator includes the / and % operators. First evaluate
* the sub-expressions, then perform the required operation.
*/
NetExpr* NetEBDiv::eval_tree()
{
eval_expr(left_);
eval_expr(right_);
return eval_arguments_(left_, right_);
}
NetExpr* NetEBDiv::eval_arguments_(const NetExpr*l, const NetExpr*r) const
{
if (expr_type() == IVL_VT_REAL) return eval_tree_real_(l,r);
@ -844,12 +813,6 @@ NetExpr* NetEBDiv::eval_arguments_(const NetExpr*l, const NetExpr*r) const
}
NetExpr*tmp = new NetEConst(val);
ivl_assert(*this, tmp);
tmp->set_line(*this);
if (debug_eval_tree)
cerr << get_fileline() << ": debug: Evaluated: " << *this
<< " --> " << *tmp << endl;
return tmp;
}
@ -883,23 +846,9 @@ NetEConst* NetEBLogic::eval_tree_real_(const NetExpr*l, const NetExpr*r) const
NetEConst*tmp = new NetEConst(verinum(res, 1));
ivl_assert(*this, tmp);
tmp->set_line(*this);
if (debug_eval_tree)
cerr << get_fileline() << ": debug: Evaluated (real): " << *this
<< " --> " << *tmp << endl;
return tmp;
}
NetEConst* NetEBLogic::eval_tree()
{
eval_expr(left_);
eval_expr(right_);
return eval_arguments_(left_, right_);
}
NetEConst* NetEBLogic::eval_arguments_(const NetExpr*l, const NetExpr*r) const
{
if (l->expr_type() == IVL_VT_REAL || r->expr_type() == IVL_VT_REAL)
@ -963,12 +912,6 @@ NetEConst* NetEBLogic::eval_arguments_(const NetExpr*l, const NetExpr*r) const
NetEConst*tmp = new NetEConst(verinum(res, 1));
ivl_assert(*this, tmp);
tmp->set_line(*this);
if (debug_eval_tree)
cerr << get_fileline() << ": debug: Evaluated: " << *this
<< " --> " << *tmp << endl;
return tmp;
}
@ -994,23 +937,9 @@ NetExpr* NetEBMinMax::eval_tree_real_(const NetExpr*l, const NetExpr*r) const
NetECReal*res = new NetECReal( verireal(res_val) );
ivl_assert(*this, res);
res->set_line(*this);
if (debug_eval_tree)
cerr << get_fileline() << ": debug: Evaluated (real): " << *this
<< " --> " << *res << endl;
return res;
}
NetExpr* NetEBMinMax::eval_tree()
{
eval_expr(left_);
eval_expr(right_);
return eval_arguments_(left_, right_);
}
NetExpr* NetEBMinMax::eval_arguments_(const NetExpr*l, const NetExpr*r) const
{
if (expr_type() == IVL_VT_REAL) return eval_tree_real_(l,r);
@ -1045,12 +974,6 @@ NetExpr* NetEBMinMax::eval_arguments_(const NetExpr*l, const NetExpr*r) const
}
NetEConst*res = new NetEConst(res_val);
ivl_assert(*this, res);
res->set_line(*this);
if (debug_eval_tree)
cerr << get_fileline() << ": debug: Evaluated: " << *this
<< " --> " << *res << endl;
return res;
}
@ -1064,23 +987,9 @@ NetExpr* NetEBMult::eval_tree_real_(const NetExpr*l, const NetExpr*r) const
NetECReal*res = new NetECReal( verireal(lval * rval) );
ivl_assert(*this, res);
res->set_line(*this);
if (debug_eval_tree)
cerr << get_fileline() << ": debug: Evaluated (real): " << *this
<< " --> " << *res << endl;
return res;
}
NetExpr* NetEBMult::eval_tree()
{
eval_expr(left_);
eval_expr(right_);
return eval_arguments_(left_, right_);
}
NetExpr* NetEBMult::eval_arguments_(const NetExpr*l, const NetExpr*r) const
{
if (expr_type() == IVL_VT_REAL) return eval_tree_real_(l,r);
@ -1101,12 +1010,6 @@ NetExpr* NetEBMult::eval_arguments_(const NetExpr*l, const NetExpr*r) const
verinum val(lval * rval, wid);
NetEConst*tmp = new NetEConst(val);
ivl_assert(*this, tmp);
tmp->set_line(*this);
if (debug_eval_tree)
cerr << get_fileline() << ": debug: Evaluated: " << *this
<< " --> " << *tmp << endl;
return tmp;
}
@ -1120,23 +1023,9 @@ NetExpr* NetEBPow::eval_tree_real_(const NetExpr*l, const NetExpr*r) const
NetECReal*res = new NetECReal( verireal( pow(lval,rval) ) );
ivl_assert(*this, res);
res->set_line(*this);
if (debug_eval_tree)
cerr << get_fileline() << ": debug: Evaluated (real): " << *this
<< " --> " << *res << endl;
return res;
}
NetExpr* NetEBPow::eval_tree()
{
eval_expr(left_);
eval_expr(right_);
return eval_arguments_(left_, right_);
}
NetExpr* NetEBPow::eval_arguments_(const NetExpr*l, const NetExpr*r) const
{
if (expr_type() == IVL_VT_REAL) return eval_tree_real_(l,r);
@ -1156,27 +1045,9 @@ NetExpr* NetEBPow::eval_arguments_(const NetExpr*l, const NetExpr*r) const
verinum val(pow(lval, rval), wid);
NetEConst*res = new NetEConst(val);
ivl_assert(*this, res);
res->set_line(*this);
if (debug_eval_tree)
cerr << get_fileline() << ": debug: Evaluated: " << *this
<< " --> " << *res << endl;
return res;
}
/*
* Evaluate the shift operator if possible. For this to work, both
* operands must be constant.
*/
NetEConst* NetEBShift::eval_tree()
{
eval_expr(left_);
eval_expr(right_);
return eval_arguments_(left_,right_);
}
NetEConst* NetEBShift::eval_arguments_(const NetExpr*l, const NetExpr*r) const
{
const NetEConst*le = dynamic_cast<const NetEConst*>(l);
@ -1213,12 +1084,7 @@ NetEConst* NetEBShift::eval_arguments_(const NetExpr*l, const NetExpr*r) const
}
val.has_sign(has_sign());
res = new NetEConst(val);
res->set_line(*this);
if (debug_eval_tree)
cerr << get_fileline() << ": debug: Evaluated: " << *this
<< " --> " << *res << endl;
ivl_assert(*this, res);
return res;
}
@ -1507,6 +1373,22 @@ NetExpr*NetETernary::blended_arguments_(const NetExpr*te, const NetExpr*fe) cons
return rc;
}
NetExpr* NetEUnary::eval_tree()
{
eval_expr(expr_);
NetExpr*res = eval_arguments_(expr_);
if (res != 0) {
res->set_line(*this);
if (debug_eval_tree) {
cerr << get_fileline() << ": debug: Evaluated";
if (expr_->expr_type() == IVL_VT_REAL)
cerr << " (real)";
cerr << ": " << *this << " --> " << *res << endl;
}
}
return res;
}
NetExpr* NetEUnary::eval_tree_real_(const NetExpr*ex) const
{
const NetECReal*val= dynamic_cast<const NetECReal*> (ex);
@ -1530,21 +1412,9 @@ NetExpr* NetEUnary::eval_tree_real_(const NetExpr*ex) const
}
NetECReal *res = new NetECReal( verireal(res_val) );
ivl_assert(*this, res);
res->set_line(*this);
if (debug_eval_tree)
cerr << get_fileline() << ": debug: Evaluated (real): " << *this
<< " --> " << *res << endl;
return res;
}
NetExpr* NetEUnary::eval_tree()
{
eval_expr(expr_);
return eval_arguments_(expr_);
}
NetExpr* NetEUnary::eval_arguments_(const NetExpr*ex) const
{
if (expr_type() == IVL_VT_REAL) return eval_tree_real_(ex);
@ -1608,21 +1478,10 @@ NetExpr* NetEUnary::eval_arguments_(const NetExpr*ex) const
NetEConst *res = new NetEConst(val);
ivl_assert(*this, res);
res->set_line(*this);
if (debug_eval_tree)
cerr << get_fileline() << ": debug: Evaluated: " << *this
<< " --> " << *res << endl;
return res;
}
NetExpr* NetEUBits::eval_tree()
{
return NetEUnary::eval_tree();
}
NetEConst* NetEUReduce::eval_tree_real_(const NetExpr*ex) const
{
ivl_assert(*this, op_ == '!');
@ -1635,21 +1494,9 @@ NetEConst* NetEUReduce::eval_tree_real_(const NetExpr*ex) const
NetEConst*tmp = new NetEConst(verinum(res, 1));
ivl_assert(*this, tmp);
tmp->set_line(*this);
if (debug_eval_tree)
cerr << get_fileline() << ": debug: Evaluated (real): " << *this
<< " --> " << *tmp << endl;
return tmp;
}
NetEConst* NetEUReduce::eval_tree()
{
eval_expr(expr_);
return eval_arguments_(expr_);
}
NetEConst* NetEUReduce::eval_arguments_(const NetExpr*ex) const
{
if (expr_type() == IVL_VT_REAL) return eval_tree_real_(ex);
@ -1738,12 +1585,6 @@ NetEConst* NetEUReduce::eval_arguments_(const NetExpr*ex) const
NetEConst*tmp = new NetEConst(verinum(res, 1));
ivl_assert(*this, tmp);
tmp->set_line(*this);
if (debug_eval_tree)
cerr << get_fileline() << ": debug: Evaluated: " << *this
<< " --> " << *tmp << endl;
return tmp;
}

View File

@ -280,6 +280,16 @@ NetExpr* NetEBinary::evaluate_function(const LineInfo&loc,
}
NetExpr*res = eval_arguments_(lval, rval);
if (res != 0) {
res->set_line(*this);
if (debug_eval_tree) {
cerr << get_fileline() << ": debug: Evaluated";
if (lval->expr_type() == IVL_VT_REAL ||
rval->expr_type() == IVL_VT_REAL)
cerr << " (real)";
cerr << ": " << *this << " --> " << *res << endl;
}
}
delete lval;
delete rval;
return res;
@ -387,6 +397,15 @@ NetExpr* NetEUnary::evaluate_function(const LineInfo&loc,
if (val == 0) return 0;
NetExpr*res = eval_arguments_(val);
if (res != 0) {
res->set_line(*this);
if (debug_eval_tree) {
cerr << get_fileline() << ": debug: Evaluated";
if (val->expr_type() == IVL_VT_REAL)
cerr << " (real)";
cerr << ": " << *this << " --> " << *res << endl;
}
}
delete val;
return res;
}

View File

@ -3529,6 +3529,7 @@ class NetEBinary : public NetExpr {
virtual bool has_width() const;
virtual NetEBinary* dup_expr() const;
virtual NetExpr* eval_tree();
virtual NetExpr* evaluate_function(const LineInfo&loc,
std::map<perm_string,NetExpr*>&ctx) const;
virtual NexusSet* nex_input(bool rem_out = true);
@ -3582,7 +3583,6 @@ class NetEBDiv : public NetEBinary {
virtual ivl_variable_type_t expr_type() const;
virtual NetEBDiv* dup_expr() const;
virtual NetExpr* eval_tree();
virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root);
private:
@ -3611,7 +3611,6 @@ class NetEBBits : public NetEBinary {
~NetEBBits();
virtual NetEBBits* dup_expr() const;
virtual NetEConst* eval_tree();
virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root);
private:
@ -3642,7 +3641,6 @@ class NetEBComp : public NetEBinary {
virtual bool has_width() const;
virtual ivl_variable_type_t expr_type() const;
virtual NetEBComp* dup_expr() const;
virtual NetEConst* eval_tree();
virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root);
private:
@ -3673,7 +3671,6 @@ class NetEBLogic : public NetEBinary {
~NetEBLogic();
virtual NetEBLogic* dup_expr() const;
virtual NetEConst* eval_tree();
virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root);
private:
@ -3696,8 +3693,6 @@ class NetEBMinMax : public NetEBinary {
virtual ivl_variable_type_t expr_type() const;
virtual NetExpr* eval_tree();
private:
NetExpr* eval_arguments_(const NetExpr*l, const NetExpr*r) const;
NetExpr* eval_tree_real_(const NetExpr*l, const NetExpr*r) const;
@ -3715,7 +3710,6 @@ class NetEBMult : public NetEBinary {
virtual ivl_variable_type_t expr_type() const;
virtual NetEBMult* dup_expr() const;
virtual NetExpr* eval_tree();
virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root);
private:
@ -3735,7 +3729,6 @@ class NetEBPow : public NetEBinary {
virtual ivl_variable_type_t expr_type() const;
virtual NetEBPow* dup_expr() const;
virtual NetExpr* eval_tree();
virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root);
private:
@ -3762,7 +3755,6 @@ class NetEBShift : public NetEBinary {
virtual bool has_width() const;
virtual NetEBShift* dup_expr() const;
virtual NetEConst* eval_tree();
virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root);
private:
@ -4129,7 +4121,6 @@ class NetEUBits : public NetEUnary {
virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root);
virtual NetEUBits* dup_expr() const;
virtual NetExpr* eval_tree();
virtual ivl_variable_type_t expr_type() const;
};
@ -4141,7 +4132,6 @@ class NetEUReduce : public NetEUnary {
virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root);
virtual NetEUReduce* dup_expr() const;
virtual NetEConst* eval_tree();
virtual ivl_variable_type_t expr_type() const;
private: