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