Skip to content

Commit 5cfd7c4

Browse files
committed
Use simplify_exprtt::resultt in pre-order simplification steps
The use of resultt increases type safety as the expression to be simplified is no longer modified in place. All post-order simplification steps already use resultt, but pre-order steps had been left to be done.
1 parent 339505b commit 5cfd7c4

File tree

3 files changed

+136
-119
lines changed

3 files changed

+136
-119
lines changed

src/util/simplify_expr.cpp

+67-56
Original file line numberDiff line numberDiff line change
@@ -816,9 +816,8 @@ simplify_exprt::simplify_typecast(const typecast_exprt &expr)
816816
// rewrite (T)(bool) to bool?1:0
817817
auto one = from_integer(1, expr_type);
818818
auto zero = from_integer(0, expr_type);
819-
exprt new_expr = if_exprt(expr.op(), std::move(one), std::move(zero));
820-
simplify_if_preorder(to_if_expr(new_expr));
821-
return new_expr;
819+
return changed(simplify_if_preorder(
820+
if_exprt{expr.op(), std::move(one), std::move(zero)}));
822821
}
823822

824823
// circular casts through types shorter than `int`
@@ -1336,33 +1335,33 @@ simplify_exprt::simplify_typecast(const typecast_exprt &expr)
13361335
return unchanged(expr);
13371336
}
13381337

1339-
bool simplify_exprt::simplify_typecast_preorder(typecast_exprt &expr)
1338+
simplify_exprt::resultt<>
1339+
simplify_exprt::simplify_typecast_preorder(const typecast_exprt &expr)
13401340
{
1341-
const typet &expr_type = as_const(expr).type();
1342-
const typet &op_type = as_const(expr).op().type();
1341+
const typet &expr_type = expr.type();
1342+
const typet &op_type = expr.op().type();
13431343

13441344
// (T)(a?b:c) --> a?(T)b:(T)c; don't do this for floating-point type casts as
13451345
// the type cast itself may be costly
13461346
if(
1347-
as_const(expr).op().id() == ID_if && expr_type.id() != ID_floatbv &&
1347+
expr.op().id() == ID_if && expr_type.id() != ID_floatbv &&
13481348
op_type.id() != ID_floatbv)
13491349
{
13501350
if_exprt if_expr = lift_if(expr, 0);
1351-
simplify_if_preorder(if_expr);
1352-
expr.swap(if_expr);
1353-
return false;
1351+
return changed(simplify_if_preorder(if_expr));
13541352
}
13551353
else
13561354
{
13571355
auto r_it = simplify_rec(expr.op()); // recursive call
13581356
if(r_it.has_changed())
13591357
{
1360-
expr.op() = r_it.expr;
1361-
return false;
1358+
auto tmp = expr;
1359+
tmp.op() = r_it.expr;
1360+
return tmp;
13621361
}
1363-
else
1364-
return true;
13651362
}
1363+
1364+
return unchanged(expr);
13661365
}
13671366

13681367
simplify_exprt::resultt<>
@@ -2700,9 +2699,10 @@ simplify_exprt::simplify_overflow_result(const overflow_result_exprt &expr)
27002699
}
27012700
}
27022701

2703-
bool simplify_exprt::simplify_node_preorder(exprt &expr)
2702+
simplify_exprt::resultt<>
2703+
simplify_exprt::simplify_node_preorder(const exprt &expr)
27042704
{
2705-
bool result=true;
2705+
auto result = unchanged(expr);
27062706

27072707
// The ifs below could one day be replaced by a switch()
27082708

@@ -2711,40 +2711,50 @@ bool simplify_exprt::simplify_node_preorder(exprt &expr)
27112711
// the argument of this expression needs special treatment
27122712
}
27132713
else if(expr.id()==ID_if)
2714-
result=simplify_if_preorder(to_if_expr(expr));
2714+
{
2715+
result = simplify_if_preorder(to_if_expr(expr));
2716+
}
27152717
else if(expr.id() == ID_typecast)
2718+
{
27162719
result = simplify_typecast_preorder(to_typecast_expr(expr));
2717-
else
2720+
}
2721+
else if(expr.has_operands())
27182722
{
2719-
if(expr.has_operands())
2723+
optionalt<exprt::operandst> new_operands;
2724+
2725+
for(std::size_t i = 0; i < expr.operands().size(); ++i)
27202726
{
2721-
Forall_operands(it, expr)
2727+
auto r_it = simplify_rec(expr.operands()[i]); // recursive call
2728+
if(r_it.has_changed())
27222729
{
2723-
auto r_it = simplify_rec(*it); // recursive call
2724-
if(r_it.has_changed())
2725-
{
2726-
*it = r_it.expr;
2727-
result=false;
2728-
}
2730+
if(!new_operands.has_value())
2731+
new_operands = expr.operands();
2732+
(*new_operands)[i] = std::move(r_it.expr);
27292733
}
27302734
}
2735+
2736+
if(new_operands.has_value())
2737+
{
2738+
std::swap(result.expr.operands(), *new_operands);
2739+
result.expr_changed = resultt<>::CHANGED;
2740+
}
27312741
}
27322742

2733-
if(as_const(expr).type().id() == ID_array)
2743+
if(as_const(result.expr).type().id() == ID_array)
27342744
{
2735-
const array_typet &array_type = to_array_type(as_const(expr).type());
2745+
const array_typet &array_type = to_array_type(as_const(result.expr).type());
27362746
resultt<> simp_size = simplify_rec(array_type.size());
27372747
if(simp_size.has_changed())
27382748
{
2739-
to_array_type(expr.type()).size() = simp_size.expr;
2740-
result = false;
2749+
to_array_type(result.expr.type()).size() = simp_size.expr;
2750+
result.expr_changed = resultt<>::CHANGED;
27412751
}
27422752
}
27432753

27442754
return result;
27452755
}
27462756

2747-
simplify_exprt::resultt<> simplify_exprt::simplify_node(exprt node)
2757+
simplify_exprt::resultt<> simplify_exprt::simplify_node(const exprt &node)
27482758
{
27492759
if(!node.has_operands())
27502760
return unchanged(node); // no change
@@ -3029,53 +3039,54 @@ simplify_exprt::resultt<> simplify_exprt::simplify_rec(const exprt &expr)
30293039
#endif
30303040

30313041
// We work on a copy to prevent unnecessary destruction of sharing.
3032-
exprt tmp=expr;
3033-
bool no_change = simplify_node_preorder(tmp);
3042+
auto simplify_node_preorder_result = simplify_node_preorder(expr);
30343043

3035-
auto simplify_node_result = simplify_node(tmp);
3044+
auto simplify_node_result = simplify_node(simplify_node_preorder_result.expr);
30363045

3037-
if(simplify_node_result.has_changed())
3046+
if(
3047+
!simplify_node_result.has_changed() &&
3048+
simplify_node_preorder_result.has_changed())
30383049
{
3039-
no_change = false;
3040-
tmp = simplify_node_result.expr;
3050+
simplify_node_result.expr_changed =
3051+
simplify_node_preorder_result.expr_changed;
30413052
}
30423053

30433054
#ifdef USE_LOCAL_REPLACE_MAP
3044-
#if 1
3045-
replace_mapt::const_iterator it=local_replace_map.find(tmp);
3055+
exprt tmp = simplify_node_result.expr;
3056+
# if 1
3057+
replace_mapt::const_iterator it =
3058+
local_replace_map.find(simplify_node_result.expr);
30463059
if(it!=local_replace_map.end())
3060+
simplify_node_result = changed(it->second);
3061+
# else
3062+
if(
3063+
!local_replace_map.empty() &&
3064+
!replace_expr(local_replace_map, simplify_node_result.expr))
30473065
{
3048-
tmp=it->second;
3049-
no_change = false;
3050-
}
3051-
#else
3052-
if(!local_replace_map.empty() &&
3053-
!replace_expr(local_replace_map, tmp))
3054-
{
3055-
simplify_rec(tmp);
3056-
no_change = false;
3066+
simplify_node_result = changed(simplify_rec(simplify_node_result.expr));
30573067
}
3058-
#endif
3068+
# endif
30593069
#endif
30603070

3061-
if(no_change) // no change
3071+
if(!simplify_node_result.has_changed())
30623072
{
30633073
return unchanged(expr);
30643074
}
3065-
else // change, new expression is 'tmp'
3075+
else
30663076
{
30673077
POSTCONDITION_WITH_DIAGNOSTICS(
3068-
(as_const(tmp).type().id() == ID_array && expr.type().id() == ID_array) ||
3069-
as_const(tmp).type() == expr.type(),
3070-
tmp.pretty(),
3078+
(as_const(simplify_node_result.expr).type().id() == ID_array &&
3079+
expr.type().id() == ID_array) ||
3080+
as_const(simplify_node_result.expr).type() == expr.type(),
3081+
simplify_node_result.expr.pretty(),
30713082
expr.pretty());
30723083

30733084
#ifdef USE_CACHE
30743085
// save in cache
3075-
cache_result.first->second = tmp;
3086+
cache_result.first->second = simplify_node_result.expr;
30763087
#endif
30773088

3078-
return std::move(tmp);
3089+
return simplify_node_result;
30793090
}
30803091
}
30813092

src/util/simplify_expr_class.h

+4-4
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ class simplify_exprt
147147
// These below all return 'true' if the simplification wasn't applicable.
148148
// If false is returned, the expression has changed.
149149
NODISCARD resultt<> simplify_typecast(const typecast_exprt &);
150-
bool simplify_typecast_preorder(typecast_exprt &);
150+
NODISCARD resultt<> simplify_typecast_preorder(const typecast_exprt &);
151151
NODISCARD resultt<> simplify_extractbit(const extractbit_exprt &);
152152
NODISCARD resultt<> simplify_extractbits(const extractbits_exprt &);
153153
NODISCARD resultt<> simplify_concatenation(const concatenation_exprt &);
@@ -161,7 +161,7 @@ class simplify_exprt
161161
NODISCARD resultt<> simplify_shifts(const shift_exprt &);
162162
NODISCARD resultt<> simplify_power(const binary_exprt &);
163163
NODISCARD resultt<> simplify_bitwise(const multi_ary_exprt &);
164-
bool simplify_if_preorder(if_exprt &expr);
164+
NODISCARD resultt<> simplify_if_preorder(const if_exprt &expr);
165165
NODISCARD resultt<> simplify_if(const if_exprt &);
166166
NODISCARD resultt<> simplify_bitnot(const bitnot_exprt &);
167167
NODISCARD resultt<> simplify_not(const not_exprt &);
@@ -249,8 +249,8 @@ class simplify_exprt
249249
simplify_inequality_pointer_object(const binary_relation_exprt &);
250250

251251
// main recursion
252-
NODISCARD resultt<> simplify_node(exprt);
253-
bool simplify_node_preorder(exprt &expr);
252+
NODISCARD resultt<> simplify_node(const exprt &);
253+
NODISCARD resultt<> simplify_node_preorder(const exprt &);
254254
NODISCARD resultt<> simplify_rec(const exprt &);
255255

256256
virtual bool simplify(exprt &expr);

0 commit comments

Comments
 (0)