Skip to content

Commit a3b9755

Browse files
authored
Merge pull request #979 from diffblue/reduction-expression-classes
Verilog: classes for the reduction operator expressions
2 parents 578d1af + ddb4bf0 commit a3b9755

File tree

3 files changed

+193
-12
lines changed

3 files changed

+193
-12
lines changed

src/verilog/expr2verilog.cpp

+6-6
Original file line numberDiff line numberDiff line change
@@ -1670,27 +1670,27 @@ expr2verilogt::resultt expr2verilogt::convert_rec(const exprt &src)
16701670

16711671
else if(src.id()==ID_reduction_or)
16721672
return convert_unary(
1673-
to_unary_expr(src), "|", precedence = verilog_precedencet::NOT);
1673+
to_reduction_or_expr(src), "|", precedence = verilog_precedencet::NOT);
16741674

16751675
else if(src.id()==ID_reduction_and)
16761676
return convert_unary(
1677-
to_unary_expr(src), "&", precedence = verilog_precedencet::NOT);
1677+
to_reduction_and_expr(src), "&", precedence = verilog_precedencet::NOT);
16781678

16791679
else if(src.id()==ID_reduction_nor)
16801680
return convert_unary(
1681-
to_unary_expr(src), "~|", precedence = verilog_precedencet::NOT);
1681+
to_reduction_nor_expr(src), "~|", precedence = verilog_precedencet::NOT);
16821682

16831683
else if(src.id()==ID_reduction_nand)
16841684
return convert_unary(
1685-
to_unary_expr(src), "~&", precedence = verilog_precedencet::NOT);
1685+
to_reduction_nand_expr(src), "~&", precedence = verilog_precedencet::NOT);
16861686

16871687
else if(src.id()==ID_reduction_xor)
16881688
return convert_unary(
1689-
to_unary_expr(src), "^", precedence = verilog_precedencet::NOT);
1689+
to_reduction_xor_expr(src), "^", precedence = verilog_precedencet::NOT);
16901690

16911691
else if(src.id()==ID_reduction_xnor)
16921692
return convert_unary(
1693-
to_unary_expr(src), "~^", precedence = verilog_precedencet::NOT);
1693+
to_reduction_xnor_expr(src), "~^", precedence = verilog_precedencet::NOT);
16941694

16951695
else if(src.id()==ID_AG || src.id()==ID_EG ||
16961696
src.id()==ID_AX || src.id()==ID_EX)

src/verilog/verilog_expr.h

+180
Original file line numberDiff line numberDiff line change
@@ -3046,4 +3046,184 @@ inline verilog_package_scope_exprt &to_verilog_package_scope_expr(exprt &expr)
30463046
return static_cast<verilog_package_scope_exprt &>(expr);
30473047
}
30483048

3049+
class reduction_and_exprt : public unary_predicate_exprt
3050+
{
3051+
public:
3052+
explicit reduction_and_exprt(exprt _op)
3053+
: unary_predicate_exprt(ID_reduction_and, std::move(_op))
3054+
{
3055+
}
3056+
};
3057+
3058+
template <>
3059+
inline bool can_cast_expr<reduction_and_exprt>(const exprt &expr)
3060+
{
3061+
reduction_and_exprt::check(expr);
3062+
return expr.id() == ID_reduction_and;
3063+
}
3064+
3065+
inline const reduction_and_exprt &to_reduction_and_expr(const exprt &expr)
3066+
{
3067+
PRECONDITION(expr.id() == ID_reduction_and);
3068+
reduction_and_exprt::check(expr);
3069+
return static_cast<const reduction_and_exprt &>(expr);
3070+
}
3071+
3072+
inline reduction_and_exprt &to_reduction_and_expr(exprt &expr)
3073+
{
3074+
PRECONDITION(expr.id() == ID_reduction_and);
3075+
reduction_and_exprt::check(expr);
3076+
return static_cast<reduction_and_exprt &>(expr);
3077+
}
3078+
3079+
class reduction_or_exprt : public unary_predicate_exprt
3080+
{
3081+
public:
3082+
explicit reduction_or_exprt(exprt _op)
3083+
: unary_predicate_exprt(ID_reduction_or, std::move(_op))
3084+
{
3085+
}
3086+
};
3087+
3088+
template <>
3089+
inline bool can_cast_expr<reduction_or_exprt>(const exprt &expr)
3090+
{
3091+
reduction_or_exprt::check(expr);
3092+
return expr.id() == ID_reduction_or;
3093+
}
3094+
3095+
inline const reduction_or_exprt &to_reduction_or_expr(const exprt &expr)
3096+
{
3097+
PRECONDITION(expr.id() == ID_reduction_or);
3098+
reduction_or_exprt::check(expr);
3099+
return static_cast<const reduction_or_exprt &>(expr);
3100+
}
3101+
3102+
inline reduction_or_exprt &to_reduction_or_expr(exprt &expr)
3103+
{
3104+
PRECONDITION(expr.id() == ID_reduction_or);
3105+
reduction_or_exprt::check(expr);
3106+
return static_cast<reduction_or_exprt &>(expr);
3107+
}
3108+
3109+
class reduction_nor_exprt : public unary_predicate_exprt
3110+
{
3111+
public:
3112+
explicit reduction_nor_exprt(exprt _op)
3113+
: unary_predicate_exprt(ID_reduction_nor, std::move(_op))
3114+
{
3115+
}
3116+
};
3117+
3118+
template <>
3119+
inline bool can_cast_expr<reduction_nor_exprt>(const exprt &expr)
3120+
{
3121+
reduction_nor_exprt::check(expr);
3122+
return expr.id() == ID_reduction_nor;
3123+
}
3124+
3125+
inline const reduction_nor_exprt &to_reduction_nor_expr(const exprt &expr)
3126+
{
3127+
PRECONDITION(expr.id() == ID_reduction_nor);
3128+
reduction_nor_exprt::check(expr);
3129+
return static_cast<const reduction_nor_exprt &>(expr);
3130+
}
3131+
3132+
inline reduction_nor_exprt &to_reduction_nor_expr(exprt &expr)
3133+
{
3134+
PRECONDITION(expr.id() == ID_reduction_nor);
3135+
reduction_nor_exprt::check(expr);
3136+
return static_cast<reduction_nor_exprt &>(expr);
3137+
}
3138+
3139+
class reduction_nand_exprt : public unary_predicate_exprt
3140+
{
3141+
public:
3142+
explicit reduction_nand_exprt(exprt _op)
3143+
: unary_predicate_exprt(ID_reduction_nand, std::move(_op))
3144+
{
3145+
}
3146+
};
3147+
3148+
template <>
3149+
inline bool can_cast_expr<reduction_nand_exprt>(const exprt &expr)
3150+
{
3151+
reduction_nand_exprt::check(expr);
3152+
return expr.id() == ID_reduction_nand;
3153+
}
3154+
3155+
inline const reduction_nand_exprt &to_reduction_nand_expr(const exprt &expr)
3156+
{
3157+
PRECONDITION(expr.id() == ID_reduction_nand);
3158+
reduction_nand_exprt::check(expr);
3159+
return static_cast<const reduction_nand_exprt &>(expr);
3160+
}
3161+
3162+
inline reduction_nand_exprt &to_reduction_nand_expr(exprt &expr)
3163+
{
3164+
PRECONDITION(expr.id() == ID_reduction_nand);
3165+
reduction_nand_exprt::check(expr);
3166+
return static_cast<reduction_nand_exprt &>(expr);
3167+
}
3168+
3169+
class reduction_xor_exprt : public unary_predicate_exprt
3170+
{
3171+
public:
3172+
explicit reduction_xor_exprt(exprt _op)
3173+
: unary_predicate_exprt(ID_reduction_xor, std::move(_op))
3174+
{
3175+
}
3176+
};
3177+
3178+
template <>
3179+
inline bool can_cast_expr<reduction_xor_exprt>(const exprt &expr)
3180+
{
3181+
reduction_xor_exprt::check(expr);
3182+
return expr.id() == ID_reduction_xor;
3183+
}
3184+
3185+
inline const reduction_xor_exprt &to_reduction_xor_expr(const exprt &expr)
3186+
{
3187+
PRECONDITION(expr.id() == ID_reduction_xor);
3188+
reduction_xor_exprt::check(expr);
3189+
return static_cast<const reduction_xor_exprt &>(expr);
3190+
}
3191+
3192+
inline reduction_xor_exprt &to_reduction_xor_expr(exprt &expr)
3193+
{
3194+
PRECONDITION(expr.id() == ID_reduction_xor);
3195+
reduction_xor_exprt::check(expr);
3196+
return static_cast<reduction_xor_exprt &>(expr);
3197+
}
3198+
3199+
class reduction_xnor_exprt : public unary_predicate_exprt
3200+
{
3201+
public:
3202+
explicit reduction_xnor_exprt(exprt _op)
3203+
: unary_predicate_exprt(ID_reduction_xnor, std::move(_op))
3204+
{
3205+
}
3206+
};
3207+
3208+
template <>
3209+
inline bool can_cast_expr<reduction_xnor_exprt>(const exprt &expr)
3210+
{
3211+
reduction_xnor_exprt::check(expr);
3212+
return expr.id() == ID_reduction_xnor;
3213+
}
3214+
3215+
inline const reduction_xnor_exprt &to_reduction_xnor_expr(const exprt &expr)
3216+
{
3217+
PRECONDITION(expr.id() == ID_reduction_xnor);
3218+
reduction_xnor_exprt::check(expr);
3219+
return static_cast<const reduction_xnor_exprt &>(expr);
3220+
}
3221+
3222+
inline reduction_xnor_exprt &to_reduction_xnor_expr(exprt &expr)
3223+
{
3224+
PRECONDITION(expr.id() == ID_reduction_xnor);
3225+
reduction_xnor_exprt::check(expr);
3226+
return static_cast<reduction_xnor_exprt &>(expr);
3227+
}
3228+
30493229
#endif

src/verilog/verilog_simplifier.cpp

+7-6
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Author: Daniel Kroening, [email protected]
1515

1616
#include <ebmc/ebmc_error.h>
1717

18+
#include "verilog_expr.h"
1819
#include "verilog_types.h"
1920

2021
static constant_exprt
@@ -76,44 +77,44 @@ static exprt verilog_simplifier_rec(exprt expr, const namespacet &ns)
7677
if(expr.id() == ID_reduction_or)
7778
{
7879
// The simplifier doesn't know how to simplify reduction_or
79-
auto &reduction_or = to_unary_expr(expr);
80+
auto &reduction_or = to_reduction_or_expr(expr);
8081
expr = notequal_exprt(
8182
reduction_or.op(), from_integer(0, reduction_or.op().type()));
8283
}
8384
else if(expr.id() == ID_reduction_nor)
8485
{
8586
// The simplifier doesn't know how to simplify reduction_nor
86-
auto &reduction_nor = to_unary_expr(expr);
87+
auto &reduction_nor = to_reduction_nor_expr(expr);
8788
expr = equal_exprt(
8889
reduction_nor.op(), from_integer(0, reduction_nor.op().type()));
8990
}
9091
else if(expr.id() == ID_reduction_and)
9192
{
9293
// The simplifier doesn't know how to simplify reduction_and
93-
auto &reduction_and = to_unary_expr(expr);
94+
auto &reduction_and = to_reduction_and_expr(expr);
9495
expr =
9596
equal_exprt{reduction_and.op(), make_all_ones(reduction_and.op().type())};
9697
}
9798
else if(expr.id() == ID_reduction_nand)
9899
{
99100
// The simplifier doesn't know how to simplify reduction_nand
100-
auto &reduction_nand = to_unary_expr(expr);
101+
auto &reduction_nand = to_reduction_nand_expr(expr);
101102
expr = notequal_exprt{
102103
reduction_nand.op(), make_all_ones(reduction_nand.op().type())};
103104
}
104105
else if(expr.id() == ID_reduction_xor)
105106
{
106107
// The simplifier doesn't know how to simplify reduction_xor
107108
// Lower to countones.
108-
auto &reduction_xor = to_unary_expr(expr);
109+
auto &reduction_xor = to_reduction_xor_expr(expr);
109110
auto ones = countones(to_constant_expr(reduction_xor.op()), ns);
110111
expr = extractbit_exprt{ones, from_integer(0, natural_typet{})};
111112
}
112113
else if(expr.id() == ID_reduction_xnor)
113114
{
114115
// The simplifier doesn't know how to simplify reduction_xnor
115116
// Lower to countones.
116-
auto &reduction_xnor = to_unary_expr(expr);
117+
auto &reduction_xnor = to_reduction_xnor_expr(expr);
117118
auto ones = countones(to_constant_expr(reduction_xnor.op()), ns);
118119
expr = not_exprt{extractbit_exprt{ones, from_integer(0, natural_typet{})}};
119120
}

0 commit comments

Comments
 (0)