@@ -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
13681367simplify_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
0 commit comments