@@ -820,9 +820,8 @@ simplify_exprt::simplify_typecast(const typecast_exprt &expr)
820
820
// rewrite (T)(bool) to bool?1:0
821
821
auto one = from_integer (1 , expr_type);
822
822
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)}));
826
825
}
827
826
828
827
// circular casts through types shorter than `int`
@@ -1340,33 +1339,33 @@ simplify_exprt::simplify_typecast(const typecast_exprt &expr)
1340
1339
return unchanged (expr);
1341
1340
}
1342
1341
1343
- bool simplify_exprt::simplify_typecast_preorder (typecast_exprt &expr)
1342
+ simplify_exprt::resultt<>
1343
+ simplify_exprt::simplify_typecast_preorder (const typecast_exprt &expr)
1344
1344
{
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 ();
1347
1347
1348
1348
// (T)(a?b:c) --> a?(T)b:(T)c; don't do this for floating-point type casts as
1349
1349
// the type cast itself may be costly
1350
1350
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 &&
1352
1352
op_type.id () != ID_floatbv)
1353
1353
{
1354
1354
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));
1358
1356
}
1359
1357
else
1360
1358
{
1361
1359
auto r_it = simplify_rec (expr.op ()); // recursive call
1362
1360
if (r_it.has_changed ())
1363
1361
{
1364
- expr.op () = r_it.expr ;
1365
- return false ;
1362
+ auto tmp = expr;
1363
+ tmp.op () = r_it.expr ;
1364
+ return tmp;
1366
1365
}
1367
- else
1368
- return true ;
1369
1366
}
1367
+
1368
+ return unchanged (expr);
1370
1369
}
1371
1370
1372
1371
simplify_exprt::resultt<>
@@ -2706,9 +2705,10 @@ simplify_exprt::simplify_overflow_result(const overflow_result_exprt &expr)
2706
2705
}
2707
2706
}
2708
2707
2709
- bool simplify_exprt::simplify_node_preorder (exprt &expr)
2708
+ simplify_exprt::resultt<>
2709
+ simplify_exprt::simplify_node_preorder (const exprt &expr)
2710
2710
{
2711
- bool result= true ;
2711
+ auto result = unchanged (expr) ;
2712
2712
2713
2713
// The ifs below could one day be replaced by a switch()
2714
2714
@@ -2717,40 +2717,50 @@ bool simplify_exprt::simplify_node_preorder(exprt &expr)
2717
2717
// the argument of this expression needs special treatment
2718
2718
}
2719
2719
else if (expr.id ()==ID_if)
2720
- result=simplify_if_preorder (to_if_expr (expr));
2720
+ {
2721
+ result = simplify_if_preorder (to_if_expr (expr));
2722
+ }
2721
2723
else if (expr.id () == ID_typecast)
2724
+ {
2722
2725
result = simplify_typecast_preorder (to_typecast_expr (expr));
2723
- else
2726
+ }
2727
+ else if (expr.has_operands ())
2724
2728
{
2725
- if (expr.has_operands ())
2729
+ optionalt<exprt::operandst> new_operands;
2730
+
2731
+ for (std::size_t i = 0 ; i < expr.operands ().size (); ++i)
2726
2732
{
2727
- Forall_operands (it, expr)
2733
+ auto r_it = simplify_rec (expr.operands ()[i]); // recursive call
2734
+ if (r_it.has_changed ())
2728
2735
{
2729
- auto r_it = simplify_rec (*it); // recursive call
2730
- if (r_it.has_changed ())
2731
- {
2732
- *it = r_it.expr ;
2733
- result=false ;
2734
- }
2736
+ if (!new_operands.has_value ())
2737
+ new_operands = expr.operands ();
2738
+ (*new_operands)[i] = std::move (r_it.expr );
2735
2739
}
2736
2740
}
2741
+
2742
+ if (new_operands.has_value ())
2743
+ {
2744
+ std::swap (result.expr .operands (), *new_operands);
2745
+ result.expr_changed = resultt<>::CHANGED;
2746
+ }
2737
2747
}
2738
2748
2739
- if (as_const (expr).type ().id () == ID_array)
2749
+ if (as_const (result. expr ).type ().id () == ID_array)
2740
2750
{
2741
- const array_typet &array_type = to_array_type (as_const (expr).type ());
2751
+ const array_typet &array_type = to_array_type (as_const (result. expr ).type ());
2742
2752
resultt<> simp_size = simplify_rec (array_type.size ());
2743
2753
if (simp_size.has_changed ())
2744
2754
{
2745
- to_array_type (expr.type ()).size () = simp_size.expr ;
2746
- result = false ;
2755
+ to_array_type (result. expr .type ()).size () = simp_size.expr ;
2756
+ result. expr_changed = resultt<>::CHANGED ;
2747
2757
}
2748
2758
}
2749
2759
2750
2760
return result;
2751
2761
}
2752
2762
2753
- simplify_exprt::resultt<> simplify_exprt::simplify_node (exprt node)
2763
+ simplify_exprt::resultt<> simplify_exprt::simplify_node (const exprt & node)
2754
2764
{
2755
2765
if (!node.has_operands ())
2756
2766
return unchanged (node); // no change
@@ -3047,53 +3057,54 @@ simplify_exprt::resultt<> simplify_exprt::simplify_rec(const exprt &expr)
3047
3057
#endif
3048
3058
3049
3059
// We work on a copy to prevent unnecessary destruction of sharing.
3050
- exprt tmp=expr;
3051
- bool no_change = simplify_node_preorder (tmp);
3060
+ auto simplify_node_preorder_result = simplify_node_preorder (expr);
3052
3061
3053
- auto simplify_node_result = simplify_node (tmp );
3062
+ auto simplify_node_result = simplify_node (simplify_node_preorder_result. expr );
3054
3063
3055
- if (simplify_node_result.has_changed ())
3064
+ if (
3065
+ !simplify_node_result.has_changed () &&
3066
+ simplify_node_preorder_result.has_changed ())
3056
3067
{
3057
- no_change = false ;
3058
- tmp = simplify_node_result. expr ;
3068
+ simplify_node_result. expr_changed =
3069
+ simplify_node_preorder_result. expr_changed ;
3059
3070
}
3060
3071
3061
3072
#ifdef USE_LOCAL_REPLACE_MAP
3062
- #if 1
3063
- replace_mapt::const_iterator it=local_replace_map.find (tmp);
3073
+ exprt tmp = simplify_node_result.expr ;
3074
+ # if 1
3075
+ replace_mapt::const_iterator it =
3076
+ local_replace_map.find (simplify_node_result.expr );
3064
3077
if (it!=local_replace_map.end ())
3078
+ simplify_node_result = changed (it->second );
3079
+ # else
3080
+ if (
3081
+ !local_replace_map.empty () &&
3082
+ !replace_expr (local_replace_map, simplify_node_result.expr ))
3065
3083
{
3066
- tmp=it->second ;
3067
- no_change = false ;
3068
- }
3069
- #else
3070
- if(!local_replace_map.empty() &&
3071
- !replace_expr(local_replace_map, tmp))
3072
- {
3073
- simplify_rec(tmp);
3074
- no_change = false;
3084
+ simplify_node_result = changed (simplify_rec (simplify_node_result.expr ));
3075
3085
}
3076
- # endif
3086
+ # endif
3077
3087
#endif
3078
3088
3079
- if (no_change) // no change
3089
+ if (!simplify_node_result. has_changed ())
3080
3090
{
3081
3091
return unchanged (expr);
3082
3092
}
3083
- else // change, new expression is 'tmp'
3093
+ else
3084
3094
{
3085
3095
POSTCONDITION_WITH_DIAGNOSTICS (
3086
- (as_const (tmp).type ().id () == ID_array && expr.type ().id () == ID_array) ||
3087
- as_const (tmp).type () == expr.type (),
3088
- tmp.pretty (),
3096
+ (as_const (simplify_node_result.expr ).type ().id () == ID_array &&
3097
+ expr.type ().id () == ID_array) ||
3098
+ as_const (simplify_node_result.expr ).type () == expr.type (),
3099
+ simplify_node_result.expr .pretty (),
3089
3100
expr.pretty ());
3090
3101
3091
3102
#ifdef USE_CACHE
3092
3103
// save in cache
3093
- cache_result.first ->second = tmp ;
3104
+ cache_result.first ->second = simplify_node_result. expr ;
3094
3105
#endif
3095
3106
3096
- return std::move (tmp) ;
3107
+ return simplify_node_result ;
3097
3108
}
3098
3109
}
3099
3110
0 commit comments