@@ -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<>
@@ -2627,40 +2626,50 @@ simplify_exprt::simplify_overflow_result(const overflow_result_exprt &expr)
26272626 }
26282627}
26292628
2630- bool simplify_exprt::simplify_node_preorder (exprt &expr)
2629+ simplify_exprt::resultt<>
2630+ simplify_exprt::simplify_node_preorder (const exprt &expr)
26312631{
2632- bool result=true ;
2633-
26342632 // The ifs below could one day be replaced by a switch()
26352633
26362634 if (expr.id ()==ID_address_of)
26372635 {
26382636 // the argument of this expression needs special treatment
26392637 }
26402638 else if (expr.id ()==ID_if)
2641- result=simplify_if_preorder (to_if_expr (expr));
2639+ {
2640+ return simplify_if_preorder (to_if_expr (expr));
2641+ }
26422642 else if (expr.id () == ID_typecast)
2643- result = simplify_typecast_preorder (to_typecast_expr (expr));
2644- else
26452643 {
2646- if (expr.has_operands ())
2644+ return simplify_typecast_preorder (to_typecast_expr (expr));
2645+ }
2646+ else if (expr.has_operands ())
2647+ {
2648+ optionalt<exprt::operandst> new_operands;
2649+
2650+ for (std::size_t i = 0 ; i < expr.operands ().size (); ++i)
26472651 {
2648- Forall_operands (it, expr)
2652+ auto r_it = simplify_rec (expr.operands ()[i]); // recursive call
2653+ if (r_it.has_changed ())
26492654 {
2650- auto r_it = simplify_rec (*it); // recursive call
2651- if (r_it.has_changed ())
2652- {
2653- *it = r_it.expr ;
2654- result=false ;
2655- }
2655+ if (!new_operands.has_value ())
2656+ new_operands = expr.operands ();
2657+ (*new_operands)[i] = std::move (r_it.expr );
26562658 }
26572659 }
2660+
2661+ if (new_operands.has_value ())
2662+ {
2663+ exprt result = expr;
2664+ std::swap (result.operands (), *new_operands);
2665+ return result;
2666+ }
26582667 }
26592668
2660- return result ;
2669+ return unchanged (expr) ;
26612670}
26622671
2663- simplify_exprt::resultt<> simplify_exprt::simplify_node (exprt node)
2672+ simplify_exprt::resultt<> simplify_exprt::simplify_node (const exprt & node)
26642673{
26652674 if (!node.has_operands ())
26662675 return unchanged (node); // no change
@@ -2945,50 +2954,52 @@ simplify_exprt::resultt<> simplify_exprt::simplify_rec(const exprt &expr)
29452954 #endif
29462955
29472956 // We work on a copy to prevent unnecessary destruction of sharing.
2948- exprt tmp=expr;
2949- bool no_change = simplify_node_preorder (tmp);
2957+ auto simplify_node_preorder_result = simplify_node_preorder (expr);
29502958
2951- auto simplify_node_result = simplify_node (tmp );
2959+ auto simplify_node_result = simplify_node (simplify_node_preorder_result. expr );
29522960
2953- if (simplify_node_result.has_changed ())
2961+ if (
2962+ !simplify_node_result.has_changed () &&
2963+ simplify_node_preorder_result.has_changed ())
29542964 {
2955- no_change = false ;
2956- tmp = simplify_node_result. expr ;
2965+ simplify_node_result. expr_changed =
2966+ simplify_node_preorder_result. expr_changed ;
29572967 }
29582968
29592969#ifdef USE_LOCAL_REPLACE_MAP
2960- #if 1
2961- replace_mapt::const_iterator it=local_replace_map.find (tmp);
2970+ exprt tmp = simplify_node_result.expr ;
2971+ # if 1
2972+ replace_mapt::const_iterator it =
2973+ local_replace_map.find (simplify_node_result.expr );
29622974 if (it!=local_replace_map.end ())
2975+ simplify_node_result = changed (it->second );
2976+ # else
2977+ if (
2978+ !local_replace_map.empty () &&
2979+ !replace_expr (local_replace_map, simplify_node_result.expr ))
29632980 {
2964- tmp=it->second ;
2965- no_change = false ;
2966- }
2967- #else
2968- if(!local_replace_map.empty() &&
2969- !replace_expr(local_replace_map, tmp))
2970- {
2971- simplify_rec(tmp);
2972- no_change = false;
2981+ simplify_node_result = changed (simplify_rec (simplify_node_result.expr ));
29732982 }
2974- # endif
2983+ # endif
29752984#endif
29762985
2977- if (no_change) // no change
2986+ if (!simplify_node_result. has_changed ())
29782987 {
29792988 return unchanged (expr);
29802989 }
2981- else // change, new expression is 'tmp'
2990+ else
29822991 {
29832992 POSTCONDITION_WITH_DIAGNOSTICS (
2984- as_const (tmp).type () == expr.type (), tmp.pretty (), expr.pretty ());
2993+ as_const (simplify_node_result.expr ).type () == expr.type (),
2994+ simplify_node_result.expr .pretty (),
2995+ expr.pretty ());
29852996
29862997#ifdef USE_CACHE
29872998 // save in cache
2988- cache_result.first ->second = tmp ;
2999+ cache_result.first ->second = simplify_node_result. expr ;
29893000#endif
29903001
2991- return std::move (tmp) ;
3002+ return simplify_node_result ;
29923003 }
29933004}
29943005
0 commit comments