@@ -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<>
@@ -2700,9 +2699,10 @@ simplify_exprt::simplify_overflow_result(const overflow_result_exprt &expr)
2700
2699
}
2701
2700
}
2702
2701
2703
- bool simplify_exprt::simplify_node_preorder (exprt &expr)
2702
+ simplify_exprt::resultt<>
2703
+ simplify_exprt::simplify_node_preorder (const exprt &expr)
2704
2704
{
2705
- bool result= true ;
2705
+ auto result = unchanged (expr) ;
2706
2706
2707
2707
// The ifs below could one day be replaced by a switch()
2708
2708
@@ -2711,40 +2711,50 @@ bool simplify_exprt::simplify_node_preorder(exprt &expr)
2711
2711
// the argument of this expression needs special treatment
2712
2712
}
2713
2713
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
+ }
2715
2717
else if (expr.id () == ID_typecast)
2718
+ {
2716
2719
result = simplify_typecast_preorder (to_typecast_expr (expr));
2717
- else
2720
+ }
2721
+ else if (expr.has_operands ())
2718
2722
{
2719
- if (expr.has_operands ())
2723
+ optionalt<exprt::operandst> new_operands;
2724
+
2725
+ for (std::size_t i = 0 ; i < expr.operands ().size (); ++i)
2720
2726
{
2721
- Forall_operands (it, expr)
2727
+ auto r_it = simplify_rec (expr.operands ()[i]); // recursive call
2728
+ if (r_it.has_changed ())
2722
2729
{
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 );
2729
2733
}
2730
2734
}
2735
+
2736
+ if (new_operands.has_value ())
2737
+ {
2738
+ std::swap (result.expr .operands (), *new_operands);
2739
+ result.expr_changed = resultt<>::CHANGED;
2740
+ }
2731
2741
}
2732
2742
2733
- if (as_const (expr).type ().id () == ID_array)
2743
+ if (as_const (result. expr ).type ().id () == ID_array)
2734
2744
{
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 ());
2736
2746
resultt<> simp_size = simplify_rec (array_type.size ());
2737
2747
if (simp_size.has_changed ())
2738
2748
{
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 ;
2741
2751
}
2742
2752
}
2743
2753
2744
2754
return result;
2745
2755
}
2746
2756
2747
- simplify_exprt::resultt<> simplify_exprt::simplify_node (exprt node)
2757
+ simplify_exprt::resultt<> simplify_exprt::simplify_node (const exprt & node)
2748
2758
{
2749
2759
if (!node.has_operands ())
2750
2760
return unchanged (node); // no change
@@ -3029,53 +3039,54 @@ simplify_exprt::resultt<> simplify_exprt::simplify_rec(const exprt &expr)
3029
3039
#endif
3030
3040
3031
3041
// 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);
3034
3043
3035
- auto simplify_node_result = simplify_node (tmp );
3044
+ auto simplify_node_result = simplify_node (simplify_node_preorder_result. expr );
3036
3045
3037
- if (simplify_node_result.has_changed ())
3046
+ if (
3047
+ !simplify_node_result.has_changed () &&
3048
+ simplify_node_preorder_result.has_changed ())
3038
3049
{
3039
- no_change = false ;
3040
- tmp = simplify_node_result. expr ;
3050
+ simplify_node_result. expr_changed =
3051
+ simplify_node_preorder_result. expr_changed ;
3041
3052
}
3042
3053
3043
3054
#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 );
3046
3059
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 ))
3047
3065
{
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 ));
3057
3067
}
3058
- # endif
3068
+ # endif
3059
3069
#endif
3060
3070
3061
- if (no_change) // no change
3071
+ if (!simplify_node_result. has_changed ())
3062
3072
{
3063
3073
return unchanged (expr);
3064
3074
}
3065
- else // change, new expression is 'tmp'
3075
+ else
3066
3076
{
3067
3077
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 (),
3071
3082
expr.pretty ());
3072
3083
3073
3084
#ifdef USE_CACHE
3074
3085
// save in cache
3075
- cache_result.first ->second = tmp ;
3086
+ cache_result.first ->second = simplify_node_result. expr ;
3076
3087
#endif
3077
3088
3078
- return std::move (tmp) ;
3089
+ return simplify_node_result ;
3079
3090
}
3080
3091
}
3081
3092
0 commit comments