Skip to content

Commit 18db8ab

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 91ea53f commit 18db8ab

File tree

3 files changed

+131
-116
lines changed

3 files changed

+131
-116
lines changed

src/util/simplify_expr.cpp

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

823822
// circular casts through types shorter than `int`
@@ -1334,33 +1333,33 @@ simplify_exprt::simplify_typecast(const typecast_exprt &expr)
13341333
return unchanged(expr);
13351334
}
13361335

1337-
bool simplify_exprt::simplify_typecast_preorder(typecast_exprt &expr)
1336+
simplify_exprt::resultt<>
1337+
simplify_exprt::simplify_typecast_preorder(const typecast_exprt &expr)
13381338
{
1339-
const typet &expr_type = as_const(expr).type();
1340-
const typet &op_type = as_const(expr).op().type();
1339+
const typet &expr_type = expr.type();
1340+
const typet &op_type = expr.op().type();
13411341

13421342
// (T)(a?b:c) --> a?(T)b:(T)c; don't do this for floating-point type casts as
13431343
// the type cast itself may be costly
13441344
if(
1345-
as_const(expr).op().id() == ID_if && expr_type.id() != ID_floatbv &&
1345+
expr.op().id() == ID_if && expr_type.id() != ID_floatbv &&
13461346
op_type.id() != ID_floatbv)
13471347
{
13481348
if_exprt if_expr = lift_if(expr, 0);
1349-
simplify_if_preorder(if_expr);
1350-
expr.swap(if_expr);
1351-
return false;
1349+
return changed(simplify_if_preorder(if_expr));
13521350
}
13531351
else
13541352
{
13551353
auto r_it = simplify_rec(expr.op()); // recursive call
13561354
if(r_it.has_changed())
13571355
{
1358-
expr.op() = r_it.expr;
1359-
return false;
1356+
auto tmp = expr;
1357+
tmp.op() = r_it.expr;
1358+
return tmp;
13601359
}
1361-
else
1362-
return true;
13631360
}
1361+
1362+
return unchanged(expr);
13641363
}
13651364

13661365
simplify_exprt::resultt<>
@@ -2618,40 +2617,50 @@ simplify_exprt::simplify_overflow_result(const overflow_result_exprt &expr)
26182617
}
26192618
}
26202619

2621-
bool simplify_exprt::simplify_node_preorder(exprt &expr)
2620+
simplify_exprt::resultt<>
2621+
simplify_exprt::simplify_node_preorder(const exprt &expr)
26222622
{
2623-
bool result=true;
2624-
26252623
// The ifs below could one day be replaced by a switch()
26262624

26272625
if(expr.id()==ID_address_of)
26282626
{
26292627
// the argument of this expression needs special treatment
26302628
}
26312629
else if(expr.id()==ID_if)
2632-
result=simplify_if_preorder(to_if_expr(expr));
2630+
{
2631+
return simplify_if_preorder(to_if_expr(expr));
2632+
}
26332633
else if(expr.id() == ID_typecast)
2634-
result = simplify_typecast_preorder(to_typecast_expr(expr));
2635-
else
26362634
{
2637-
if(expr.has_operands())
2635+
return simplify_typecast_preorder(to_typecast_expr(expr));
2636+
}
2637+
else if(expr.has_operands())
2638+
{
2639+
optionalt<exprt::operandst> new_operands;
2640+
2641+
for(std::size_t i = 0; i < expr.operands().size(); ++i)
26382642
{
2639-
Forall_operands(it, expr)
2643+
auto r_it = simplify_rec(expr.operands()[i]); // recursive call
2644+
if(r_it.has_changed())
26402645
{
2641-
auto r_it = simplify_rec(*it); // recursive call
2642-
if(r_it.has_changed())
2643-
{
2644-
*it = r_it.expr;
2645-
result=false;
2646-
}
2646+
if(!new_operands.has_value())
2647+
new_operands = expr.operands();
2648+
(*new_operands)[i] = std::move(r_it.expr);
26472649
}
26482650
}
2651+
2652+
if(new_operands.has_value())
2653+
{
2654+
exprt result = expr;
2655+
std::swap(result.operands(), *new_operands);
2656+
return result;
2657+
}
26492658
}
26502659

2651-
return result;
2660+
return unchanged(expr);
26522661
}
26532662

2654-
simplify_exprt::resultt<> simplify_exprt::simplify_node(exprt node)
2663+
simplify_exprt::resultt<> simplify_exprt::simplify_node(const exprt &node)
26552664
{
26562665
if(!node.has_operands())
26572666
return unchanged(node); // no change
@@ -2940,49 +2949,49 @@ simplify_exprt::resultt<> simplify_exprt::simplify_rec(const exprt &expr)
29402949
#endif
29412950

29422951
// We work on a copy to prevent unnecessary destruction of sharing.
2943-
exprt tmp=expr;
2944-
bool no_change = simplify_node_preorder(tmp);
2952+
auto simplify_node_preorder_result = simplify_node_preorder(expr);
29452953

2946-
auto simplify_node_result = simplify_node(tmp);
2954+
auto simplify_node_result = simplify_node(simplify_node_preorder_result.expr);
29472955

2948-
if(simplify_node_result.has_changed())
2956+
if(
2957+
!simplify_node_result.has_changed() &&
2958+
simplify_node_preorder_result.has_changed())
29492959
{
2950-
no_change = false;
2951-
tmp = simplify_node_result.expr;
2960+
simplify_node_result.expr_changed =
2961+
simplify_node_preorder_result.expr_changed;
29522962
}
29532963

29542964
#ifdef USE_LOCAL_REPLACE_MAP
2955-
#if 1
2956-
replace_mapt::const_iterator it=local_replace_map.find(tmp);
2965+
exprt tmp = simplify_node_result.expr;
2966+
# if 1
2967+
replace_mapt::const_iterator it =
2968+
local_replace_map.find(simplify_node_result.expr);
29572969
if(it!=local_replace_map.end())
2970+
simplify_node_result = changed(it->second);
2971+
# else
2972+
if(
2973+
!local_replace_map.empty() &&
2974+
!replace_expr(local_replace_map, simplify_node_result.expr))
29582975
{
2959-
tmp=it->second;
2960-
no_change = false;
2961-
}
2962-
#else
2963-
if(!local_replace_map.empty() &&
2964-
!replace_expr(local_replace_map, tmp))
2965-
{
2966-
simplify_rec(tmp);
2967-
no_change = false;
2976+
simplify_node_result = changed(simplify_rec(simplify_node_result.expr));
29682977
}
2969-
#endif
2978+
# endif
29702979
#endif
29712980

2972-
if(no_change) // no change
2981+
if(!simplify_node_result.has_changed())
29732982
{
29742983
return unchanged(expr);
29752984
}
2976-
else // change, new expression is 'tmp'
2985+
else
29772986
{
2978-
POSTCONDITION(as_const(tmp).type() == expr.type());
2987+
POSTCONDITION(as_const(simplify_node_result.expr).type() == expr.type());
29792988

29802989
#ifdef USE_CACHE
29812990
// save in cache
2982-
cache_result.first->second = tmp;
2991+
cache_result.first->second = simplify_node_result.expr;
29832992
#endif
29842993

2985-
return std::move(tmp);
2994+
return simplify_node_result;
29862995
}
29872996
}
29882997

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 &);
@@ -250,8 +250,8 @@ class simplify_exprt
250250
simplify_inequality_pointer_object(const binary_relation_exprt &);
251251

252252
// main recursion
253-
NODISCARD resultt<> simplify_node(exprt);
254-
bool simplify_node_preorder(exprt &expr);
253+
NODISCARD resultt<> simplify_node(const exprt &);
254+
NODISCARD resultt<> simplify_node_preorder(const exprt &);
255255
NODISCARD resultt<> simplify_rec(const exprt &);
256256

257257
virtual bool simplify(exprt &expr);

0 commit comments

Comments
 (0)