Skip to content

Commit 183bc7e

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 9238a38 commit 183bc7e

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
@@ -820,9 +820,8 @@ simplify_exprt::simplify_typecast(const typecast_exprt &expr)
820820
// rewrite (T)(bool) to bool?1:0
821821
auto one = from_integer(1, expr_type);
822822
auto zero = from_integer(0, expr_type);
823-
exprt new_expr = if_exprt(expr.op(), std::move(one), std::move(zero));
824-
simplify_if_preorder(to_if_expr(new_expr));
825-
return new_expr;
823+
return changed(simplify_if_preorder(
824+
if_exprt{expr.op(), std::move(one), std::move(zero)}));
826825
}
827826

828827
// circular casts through types shorter than `int`
@@ -1340,33 +1339,33 @@ simplify_exprt::simplify_typecast(const typecast_exprt &expr)
13401339
return unchanged(expr);
13411340
}
13421341

1343-
bool simplify_exprt::simplify_typecast_preorder(typecast_exprt &expr)
1342+
simplify_exprt::resultt<>
1343+
simplify_exprt::simplify_typecast_preorder(const typecast_exprt &expr)
13441344
{
1345-
const typet &expr_type = as_const(expr).type();
1346-
const typet &op_type = as_const(expr).op().type();
1345+
const typet &expr_type = expr.type();
1346+
const typet &op_type = expr.op().type();
13471347

13481348
// (T)(a?b:c) --> a?(T)b:(T)c; don't do this for floating-point type casts as
13491349
// the type cast itself may be costly
13501350
if(
1351-
as_const(expr).op().id() == ID_if && expr_type.id() != ID_floatbv &&
1351+
expr.op().id() == ID_if && expr_type.id() != ID_floatbv &&
13521352
op_type.id() != ID_floatbv)
13531353
{
13541354
if_exprt if_expr = lift_if(expr, 0);
1355-
simplify_if_preorder(if_expr);
1356-
expr.swap(if_expr);
1357-
return false;
1355+
return changed(simplify_if_preorder(if_expr));
13581356
}
13591357
else
13601358
{
13611359
auto r_it = simplify_rec(expr.op()); // recursive call
13621360
if(r_it.has_changed())
13631361
{
1364-
expr.op() = r_it.expr;
1365-
return false;
1362+
auto tmp = expr;
1363+
tmp.op() = r_it.expr;
1364+
return tmp;
13661365
}
1367-
else
1368-
return true;
13691366
}
1367+
1368+
return unchanged(expr);
13701369
}
13711370

13721371
simplify_exprt::resultt<>
@@ -2721,9 +2720,10 @@ simplify_exprt::simplify_overflow_result(const overflow_result_exprt &expr)
27212720
}
27222721
}
27232722

2724-
bool simplify_exprt::simplify_node_preorder(exprt &expr)
2723+
simplify_exprt::resultt<>
2724+
simplify_exprt::simplify_node_preorder(const exprt &expr)
27252725
{
2726-
bool result=true;
2726+
auto result = unchanged(expr);
27272727

27282728
// The ifs below could one day be replaced by a switch()
27292729

@@ -2732,40 +2732,50 @@ bool simplify_exprt::simplify_node_preorder(exprt &expr)
27322732
// the argument of this expression needs special treatment
27332733
}
27342734
else if(expr.id()==ID_if)
2735-
result=simplify_if_preorder(to_if_expr(expr));
2735+
{
2736+
result = simplify_if_preorder(to_if_expr(expr));
2737+
}
27362738
else if(expr.id() == ID_typecast)
2739+
{
27372740
result = simplify_typecast_preorder(to_typecast_expr(expr));
2738-
else
2741+
}
2742+
else if(expr.has_operands())
27392743
{
2740-
if(expr.has_operands())
2744+
optionalt<exprt::operandst> new_operands;
2745+
2746+
for(std::size_t i = 0; i < expr.operands().size(); ++i)
27412747
{
2742-
Forall_operands(it, expr)
2748+
auto r_it = simplify_rec(expr.operands()[i]); // recursive call
2749+
if(r_it.has_changed())
27432750
{
2744-
auto r_it = simplify_rec(*it); // recursive call
2745-
if(r_it.has_changed())
2746-
{
2747-
*it = r_it.expr;
2748-
result=false;
2749-
}
2751+
if(!new_operands.has_value())
2752+
new_operands = expr.operands();
2753+
(*new_operands)[i] = std::move(r_it.expr);
27502754
}
27512755
}
2756+
2757+
if(new_operands.has_value())
2758+
{
2759+
std::swap(result.expr.operands(), *new_operands);
2760+
result.expr_changed = resultt<>::CHANGED;
2761+
}
27522762
}
27532763

2754-
if(as_const(expr).type().id() == ID_array)
2764+
if(as_const(result.expr).type().id() == ID_array)
27552765
{
2756-
const array_typet &array_type = to_array_type(as_const(expr).type());
2766+
const array_typet &array_type = to_array_type(as_const(result.expr).type());
27572767
resultt<> simp_size = simplify_rec(array_type.size());
27582768
if(simp_size.has_changed())
27592769
{
2760-
to_array_type(expr.type()).size() = simp_size.expr;
2761-
result = false;
2770+
to_array_type(result.expr.type()).size() = simp_size.expr;
2771+
result.expr_changed = resultt<>::CHANGED;
27622772
}
27632773
}
27642774

27652775
return result;
27662776
}
27672777

2768-
simplify_exprt::resultt<> simplify_exprt::simplify_node(exprt node)
2778+
simplify_exprt::resultt<> simplify_exprt::simplify_node(const exprt &node)
27692779
{
27702780
if(!node.has_operands())
27712781
return unchanged(node); // no change
@@ -3062,53 +3072,54 @@ simplify_exprt::resultt<> simplify_exprt::simplify_rec(const exprt &expr)
30623072
#endif
30633073

30643074
// We work on a copy to prevent unnecessary destruction of sharing.
3065-
exprt tmp=expr;
3066-
bool no_change = simplify_node_preorder(tmp);
3075+
auto simplify_node_preorder_result = simplify_node_preorder(expr);
30673076

3068-
auto simplify_node_result = simplify_node(tmp);
3077+
auto simplify_node_result = simplify_node(simplify_node_preorder_result.expr);
30693078

3070-
if(simplify_node_result.has_changed())
3079+
if(
3080+
!simplify_node_result.has_changed() &&
3081+
simplify_node_preorder_result.has_changed())
30713082
{
3072-
no_change = false;
3073-
tmp = simplify_node_result.expr;
3083+
simplify_node_result.expr_changed =
3084+
simplify_node_preorder_result.expr_changed;
30743085
}
30753086

30763087
#ifdef USE_LOCAL_REPLACE_MAP
3077-
#if 1
3078-
replace_mapt::const_iterator it=local_replace_map.find(tmp);
3088+
exprt tmp = simplify_node_result.expr;
3089+
# if 1
3090+
replace_mapt::const_iterator it =
3091+
local_replace_map.find(simplify_node_result.expr);
30793092
if(it!=local_replace_map.end())
3093+
simplify_node_result = changed(it->second);
3094+
# else
3095+
if(
3096+
!local_replace_map.empty() &&
3097+
!replace_expr(local_replace_map, simplify_node_result.expr))
30803098
{
3081-
tmp=it->second;
3082-
no_change = false;
3083-
}
3084-
#else
3085-
if(!local_replace_map.empty() &&
3086-
!replace_expr(local_replace_map, tmp))
3087-
{
3088-
simplify_rec(tmp);
3089-
no_change = false;
3099+
simplify_node_result = changed(simplify_rec(simplify_node_result.expr));
30903100
}
3091-
#endif
3101+
# endif
30923102
#endif
30933103

3094-
if(no_change) // no change
3104+
if(!simplify_node_result.has_changed())
30953105
{
30963106
return unchanged(expr);
30973107
}
3098-
else // change, new expression is 'tmp'
3108+
else
30993109
{
31003110
POSTCONDITION_WITH_DIAGNOSTICS(
3101-
(as_const(tmp).type().id() == ID_array && expr.type().id() == ID_array) ||
3102-
as_const(tmp).type() == expr.type(),
3103-
tmp.pretty(),
3111+
(as_const(simplify_node_result.expr).type().id() == ID_array &&
3112+
expr.type().id() == ID_array) ||
3113+
as_const(simplify_node_result.expr).type() == expr.type(),
3114+
simplify_node_result.expr.pretty(),
31043115
expr.pretty());
31053116

31063117
#ifdef USE_CACHE
31073118
// save in cache
3108-
cache_result.first->second = tmp;
3119+
cache_result.first->second = simplify_node_result.expr;
31093120
#endif
31103121

3111-
return std::move(tmp);
3122+
return simplify_node_result;
31123123
}
31133124
}
31143125

src/util/simplify_expr_class.h

+4-4
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ class simplify_exprt
149149
// These below all return 'true' if the simplification wasn't applicable.
150150
// If false is returned, the expression has changed.
151151
NODISCARD resultt<> simplify_typecast(const typecast_exprt &);
152-
bool simplify_typecast_preorder(typecast_exprt &);
152+
NODISCARD resultt<> simplify_typecast_preorder(const typecast_exprt &);
153153
NODISCARD resultt<> simplify_extractbit(const extractbit_exprt &);
154154
NODISCARD resultt<> simplify_extractbits(const extractbits_exprt &);
155155
NODISCARD resultt<> simplify_concatenation(const concatenation_exprt &);
@@ -163,7 +163,7 @@ class simplify_exprt
163163
NODISCARD resultt<> simplify_shifts(const shift_exprt &);
164164
NODISCARD resultt<> simplify_power(const binary_exprt &);
165165
NODISCARD resultt<> simplify_bitwise(const multi_ary_exprt &);
166-
bool simplify_if_preorder(if_exprt &expr);
166+
NODISCARD resultt<> simplify_if_preorder(const if_exprt &expr);
167167
NODISCARD resultt<> simplify_if(const if_exprt &);
168168
NODISCARD resultt<> simplify_bitnot(const bitnot_exprt &);
169169
NODISCARD resultt<> simplify_not(const not_exprt &);
@@ -259,8 +259,8 @@ class simplify_exprt
259259
simplify_inequality_pointer_object(const binary_relation_exprt &);
260260

261261
// main recursion
262-
NODISCARD resultt<> simplify_node(exprt);
263-
bool simplify_node_preorder(exprt &expr);
262+
NODISCARD resultt<> simplify_node(const exprt &);
263+
NODISCARD resultt<> simplify_node_preorder(const exprt &);
264264
NODISCARD resultt<> simplify_rec(const exprt &);
265265

266266
virtual bool simplify(exprt &expr);

0 commit comments

Comments
 (0)