@@ -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<>
@@ -2721,9 +2720,10 @@ simplify_exprt::simplify_overflow_result(const overflow_result_exprt &expr)
2721
2720
}
2722
2721
}
2723
2722
2724
- bool simplify_exprt::simplify_node_preorder (exprt &expr)
2723
+ simplify_exprt::resultt<>
2724
+ simplify_exprt::simplify_node_preorder (const exprt &expr)
2725
2725
{
2726
- bool result= true ;
2726
+ auto result = unchanged (expr) ;
2727
2727
2728
2728
// The ifs below could one day be replaced by a switch()
2729
2729
@@ -2732,40 +2732,50 @@ bool simplify_exprt::simplify_node_preorder(exprt &expr)
2732
2732
// the argument of this expression needs special treatment
2733
2733
}
2734
2734
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
+ }
2736
2738
else if (expr.id () == ID_typecast)
2739
+ {
2737
2740
result = simplify_typecast_preorder (to_typecast_expr (expr));
2738
- else
2741
+ }
2742
+ else if (expr.has_operands ())
2739
2743
{
2740
- if (expr.has_operands ())
2744
+ optionalt<exprt::operandst> new_operands;
2745
+
2746
+ for (std::size_t i = 0 ; i < expr.operands ().size (); ++i)
2741
2747
{
2742
- Forall_operands (it, expr)
2748
+ auto r_it = simplify_rec (expr.operands ()[i]); // recursive call
2749
+ if (r_it.has_changed ())
2743
2750
{
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 );
2750
2754
}
2751
2755
}
2756
+
2757
+ if (new_operands.has_value ())
2758
+ {
2759
+ std::swap (result.expr .operands (), *new_operands);
2760
+ result.expr_changed = resultt<>::CHANGED;
2761
+ }
2752
2762
}
2753
2763
2754
- if (as_const (expr).type ().id () == ID_array)
2764
+ if (as_const (result. expr ).type ().id () == ID_array)
2755
2765
{
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 ());
2757
2767
resultt<> simp_size = simplify_rec (array_type.size ());
2758
2768
if (simp_size.has_changed ())
2759
2769
{
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 ;
2762
2772
}
2763
2773
}
2764
2774
2765
2775
return result;
2766
2776
}
2767
2777
2768
- simplify_exprt::resultt<> simplify_exprt::simplify_node (exprt node)
2778
+ simplify_exprt::resultt<> simplify_exprt::simplify_node (const exprt & node)
2769
2779
{
2770
2780
if (!node.has_operands ())
2771
2781
return unchanged (node); // no change
@@ -3062,53 +3072,54 @@ simplify_exprt::resultt<> simplify_exprt::simplify_rec(const exprt &expr)
3062
3072
#endif
3063
3073
3064
3074
// 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);
3067
3076
3068
- auto simplify_node_result = simplify_node (tmp );
3077
+ auto simplify_node_result = simplify_node (simplify_node_preorder_result. expr );
3069
3078
3070
- if (simplify_node_result.has_changed ())
3079
+ if (
3080
+ !simplify_node_result.has_changed () &&
3081
+ simplify_node_preorder_result.has_changed ())
3071
3082
{
3072
- no_change = false ;
3073
- tmp = simplify_node_result. expr ;
3083
+ simplify_node_result. expr_changed =
3084
+ simplify_node_preorder_result. expr_changed ;
3074
3085
}
3075
3086
3076
3087
#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 );
3079
3092
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 ))
3080
3098
{
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 ));
3090
3100
}
3091
- # endif
3101
+ # endif
3092
3102
#endif
3093
3103
3094
- if (no_change) // no change
3104
+ if (!simplify_node_result. has_changed ())
3095
3105
{
3096
3106
return unchanged (expr);
3097
3107
}
3098
- else // change, new expression is 'tmp'
3108
+ else
3099
3109
{
3100
3110
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 (),
3104
3115
expr.pretty ());
3105
3116
3106
3117
#ifdef USE_CACHE
3107
3118
// save in cache
3108
- cache_result.first ->second = tmp ;
3119
+ cache_result.first ->second = simplify_node_result. expr ;
3109
3120
#endif
3110
3121
3111
- return std::move (tmp) ;
3122
+ return simplify_node_result ;
3112
3123
}
3113
3124
}
3114
3125
0 commit comments