@@ -816,9 +816,8 @@ simplify_exprt::simplify_typecast(const typecast_exprt &expr)
816
816
// rewrite (T)(bool) to bool?1:0
817
817
auto one = from_integer (1 , expr_type);
818
818
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)}));
822
821
}
823
822
824
823
// circular casts through types shorter than `int`
@@ -1336,33 +1335,33 @@ simplify_exprt::simplify_typecast(const typecast_exprt &expr)
1336
1335
return unchanged (expr);
1337
1336
}
1338
1337
1339
- bool simplify_exprt::simplify_typecast_preorder (typecast_exprt &expr)
1338
+ simplify_exprt::resultt<>
1339
+ simplify_exprt::simplify_typecast_preorder (const typecast_exprt &expr)
1340
1340
{
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 ();
1343
1343
1344
1344
// (T)(a?b:c) --> a?(T)b:(T)c; don't do this for floating-point type casts as
1345
1345
// the type cast itself may be costly
1346
1346
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 &&
1348
1348
op_type.id () != ID_floatbv)
1349
1349
{
1350
1350
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));
1354
1352
}
1355
1353
else
1356
1354
{
1357
1355
auto r_it = simplify_rec (expr.op ()); // recursive call
1358
1356
if (r_it.has_changed ())
1359
1357
{
1360
- expr.op () = r_it.expr ;
1361
- return false ;
1358
+ auto tmp = expr;
1359
+ tmp.op () = r_it.expr ;
1360
+ return tmp;
1362
1361
}
1363
- else
1364
- return true ;
1365
1362
}
1363
+
1364
+ return unchanged (expr);
1366
1365
}
1367
1366
1368
1367
simplify_exprt::resultt<>
@@ -2697,9 +2696,10 @@ simplify_exprt::simplify_overflow_result(const overflow_result_exprt &expr)
2697
2696
}
2698
2697
}
2699
2698
2700
- bool simplify_exprt::simplify_node_preorder (exprt &expr)
2699
+ simplify_exprt::resultt<>
2700
+ simplify_exprt::simplify_node_preorder (const exprt &expr)
2701
2701
{
2702
- bool result= true ;
2702
+ auto result = unchanged (expr) ;
2703
2703
2704
2704
// The ifs below could one day be replaced by a switch()
2705
2705
@@ -2708,40 +2708,50 @@ bool simplify_exprt::simplify_node_preorder(exprt &expr)
2708
2708
// the argument of this expression needs special treatment
2709
2709
}
2710
2710
else if (expr.id ()==ID_if)
2711
- result=simplify_if_preorder (to_if_expr (expr));
2711
+ {
2712
+ result = simplify_if_preorder (to_if_expr (expr));
2713
+ }
2712
2714
else if (expr.id () == ID_typecast)
2715
+ {
2713
2716
result = simplify_typecast_preorder (to_typecast_expr (expr));
2714
- else
2717
+ }
2718
+ else if (expr.has_operands ())
2715
2719
{
2716
- if (expr.has_operands ())
2720
+ optionalt<exprt::operandst> new_operands;
2721
+
2722
+ for (std::size_t i = 0 ; i < expr.operands ().size (); ++i)
2717
2723
{
2718
- Forall_operands (it, expr)
2724
+ auto r_it = simplify_rec (expr.operands ()[i]); // recursive call
2725
+ if (r_it.has_changed ())
2719
2726
{
2720
- auto r_it = simplify_rec (*it); // recursive call
2721
- if (r_it.has_changed ())
2722
- {
2723
- *it = r_it.expr ;
2724
- result=false ;
2725
- }
2727
+ if (!new_operands.has_value ())
2728
+ new_operands = expr.operands ();
2729
+ (*new_operands)[i] = std::move (r_it.expr );
2726
2730
}
2727
2731
}
2732
+
2733
+ if (new_operands.has_value ())
2734
+ {
2735
+ std::swap (result.expr .operands (), *new_operands);
2736
+ result.expr_changed = resultt<>::CHANGED;
2737
+ }
2728
2738
}
2729
2739
2730
- if (as_const (expr).type ().id () == ID_array)
2740
+ if (as_const (result. expr ).type ().id () == ID_array)
2731
2741
{
2732
- const array_typet &array_type = to_array_type (as_const (expr).type ());
2742
+ const array_typet &array_type = to_array_type (as_const (result. expr ).type ());
2733
2743
resultt<> simp_size = simplify_rec (array_type.size ());
2734
2744
if (simp_size.has_changed ())
2735
2745
{
2736
- to_array_type (expr.type ()).size () = simp_size.expr ;
2737
- result = false ;
2746
+ to_array_type (result. expr .type ()).size () = simp_size.expr ;
2747
+ result. expr_changed = resultt<>::CHANGED ;
2738
2748
}
2739
2749
}
2740
2750
2741
2751
return result;
2742
2752
}
2743
2753
2744
- simplify_exprt::resultt<> simplify_exprt::simplify_node (exprt node)
2754
+ simplify_exprt::resultt<> simplify_exprt::simplify_node (const exprt & node)
2745
2755
{
2746
2756
if (!node.has_operands ())
2747
2757
return unchanged (node); // no change
@@ -3026,53 +3036,54 @@ simplify_exprt::resultt<> simplify_exprt::simplify_rec(const exprt &expr)
3026
3036
#endif
3027
3037
3028
3038
// We work on a copy to prevent unnecessary destruction of sharing.
3029
- exprt tmp=expr;
3030
- bool no_change = simplify_node_preorder (tmp);
3039
+ auto simplify_node_preorder_result = simplify_node_preorder (expr);
3031
3040
3032
- auto simplify_node_result = simplify_node (tmp );
3041
+ auto simplify_node_result = simplify_node (simplify_node_preorder_result. expr );
3033
3042
3034
- if (simplify_node_result.has_changed ())
3043
+ if (
3044
+ !simplify_node_result.has_changed () &&
3045
+ simplify_node_preorder_result.has_changed ())
3035
3046
{
3036
- no_change = false ;
3037
- tmp = simplify_node_result. expr ;
3047
+ simplify_node_result. expr_changed =
3048
+ simplify_node_preorder_result. expr_changed ;
3038
3049
}
3039
3050
3040
3051
#ifdef USE_LOCAL_REPLACE_MAP
3041
- #if 1
3042
- replace_mapt::const_iterator it=local_replace_map.find (tmp);
3052
+ exprt tmp = simplify_node_result.expr ;
3053
+ # if 1
3054
+ replace_mapt::const_iterator it =
3055
+ local_replace_map.find (simplify_node_result.expr );
3043
3056
if (it!=local_replace_map.end ())
3057
+ simplify_node_result = changed (it->second );
3058
+ # else
3059
+ if (
3060
+ !local_replace_map.empty () &&
3061
+ !replace_expr (local_replace_map, simplify_node_result.expr ))
3044
3062
{
3045
- tmp=it->second ;
3046
- no_change = false ;
3047
- }
3048
- #else
3049
- if(!local_replace_map.empty() &&
3050
- !replace_expr(local_replace_map, tmp))
3051
- {
3052
- simplify_rec(tmp);
3053
- no_change = false;
3063
+ simplify_node_result = changed (simplify_rec (simplify_node_result.expr ));
3054
3064
}
3055
- # endif
3065
+ # endif
3056
3066
#endif
3057
3067
3058
- if (no_change) // no change
3068
+ if (!simplify_node_result. has_changed ())
3059
3069
{
3060
3070
return unchanged (expr);
3061
3071
}
3062
- else // change, new expression is 'tmp'
3072
+ else
3063
3073
{
3064
3074
POSTCONDITION_WITH_DIAGNOSTICS (
3065
- (as_const (tmp).type ().id () == ID_array && expr.type ().id () == ID_array) ||
3066
- as_const (tmp).type () == expr.type (),
3067
- tmp.pretty (),
3075
+ (as_const (simplify_node_result.expr ).type ().id () == ID_array &&
3076
+ expr.type ().id () == ID_array) ||
3077
+ as_const (simplify_node_result.expr ).type () == expr.type (),
3078
+ simplify_node_result.expr .pretty (),
3068
3079
expr.pretty ());
3069
3080
3070
3081
#ifdef USE_CACHE
3071
3082
// save in cache
3072
- cache_result.first ->second = tmp ;
3083
+ cache_result.first ->second = simplify_node_result. expr ;
3073
3084
#endif
3074
3085
3075
- return std::move (tmp) ;
3086
+ return simplify_node_result ;
3076
3087
}
3077
3088
}
3078
3089
0 commit comments