@@ -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<>
@@ -1377,23 +1376,6 @@ simplify_exprt::simplify_dereference(const dereference_exprt &expr)
1377
1376
if (pointer.type ().id ()!=ID_pointer)
1378
1377
return unchanged (expr);
1379
1378
1380
- if (pointer.id ()==ID_if && pointer.operands ().size ()==3 )
1381
- {
1382
- const if_exprt &if_expr=to_if_expr (pointer);
1383
-
1384
- auto tmp_op1 = expr;
1385
- tmp_op1.op () = if_expr.true_case ();
1386
- exprt tmp_op1_result = simplify_dereference (tmp_op1);
1387
-
1388
- auto tmp_op2 = expr;
1389
- tmp_op2.op () = if_expr.false_case ();
1390
- exprt tmp_op2_result = simplify_dereference (tmp_op2);
1391
-
1392
- if_exprt tmp{if_expr.cond (), tmp_op1_result, tmp_op2_result};
1393
-
1394
- return changed (simplify_if (tmp));
1395
- }
1396
-
1397
1379
if (pointer.id ()==ID_address_of)
1398
1380
{
1399
1381
exprt tmp=to_address_of_expr (pointer).object ();
@@ -1427,6 +1409,30 @@ simplify_exprt::simplify_dereference(const dereference_exprt &expr)
1427
1409
return unchanged (expr);
1428
1410
}
1429
1411
1412
+ simplify_exprt::resultt<>
1413
+ simplify_exprt::simplify_dereference_preorder (const dereference_exprt &expr)
1414
+ {
1415
+ const exprt &pointer = expr.pointer ();
1416
+
1417
+ if (pointer.id () == ID_if)
1418
+ {
1419
+ if_exprt if_expr = lift_if (expr, 0 );
1420
+ return changed (simplify_if_preorder (if_expr));
1421
+ }
1422
+ else
1423
+ {
1424
+ auto r_it = simplify_rec (pointer); // recursive call
1425
+ if (r_it.has_changed ())
1426
+ {
1427
+ auto tmp = expr;
1428
+ tmp.pointer () = r_it.expr ;
1429
+ return tmp;
1430
+ }
1431
+ }
1432
+
1433
+ return unchanged (expr);
1434
+ }
1435
+
1430
1436
simplify_exprt::resultt<>
1431
1437
simplify_exprt::simplify_lambda (const lambda_exprt &expr)
1432
1438
{
@@ -1643,17 +1649,6 @@ simplify_exprt::resultt<> simplify_exprt::simplify_object(const exprt &expr)
1643
1649
simplify_exprt::resultt<>
1644
1650
simplify_exprt::simplify_byte_extract (const byte_extract_exprt &expr)
1645
1651
{
1646
- // lift up any ID_if on the object
1647
- if (expr.op ().id ()==ID_if)
1648
- {
1649
- if_exprt if_expr=lift_if (expr, 0 );
1650
- if_expr.true_case () =
1651
- simplify_byte_extract (to_byte_extract_expr (if_expr.true_case ()));
1652
- if_expr.false_case () =
1653
- simplify_byte_extract (to_byte_extract_expr (if_expr.false_case ()));
1654
- return changed (simplify_if (if_expr));
1655
- }
1656
-
1657
1652
const auto el_size = pointer_offset_bits (expr.type (), ns);
1658
1653
if (el_size.has_value () && *el_size < 0 )
1659
1654
return unchanged (expr);
@@ -2011,6 +2006,41 @@ simplify_exprt::simplify_byte_extract(const byte_extract_exprt &expr)
2011
2006
return unchanged (expr);
2012
2007
}
2013
2008
2009
+ simplify_exprt::resultt<>
2010
+ simplify_exprt::simplify_byte_extract_preorder (const byte_extract_exprt &expr)
2011
+ {
2012
+ // lift up any ID_if on the object
2013
+ if (expr.op ().id () == ID_if)
2014
+ {
2015
+ if_exprt if_expr = lift_if (expr, 0 );
2016
+ return changed (simplify_if_preorder (if_expr));
2017
+ }
2018
+ else
2019
+ {
2020
+ optionalt<exprt::operandst> new_operands;
2021
+
2022
+ for (std::size_t i = 0 ; i < expr.operands ().size (); ++i)
2023
+ {
2024
+ auto r_it = simplify_rec (expr.operands ()[i]); // recursive call
2025
+ if (r_it.has_changed ())
2026
+ {
2027
+ if (!new_operands.has_value ())
2028
+ new_operands = expr.operands ();
2029
+ (*new_operands)[i] = std::move (r_it.expr );
2030
+ }
2031
+ }
2032
+
2033
+ if (new_operands.has_value ())
2034
+ {
2035
+ exprt result = expr;
2036
+ std::swap (result.operands (), *new_operands);
2037
+ return result;
2038
+ }
2039
+ }
2040
+
2041
+ return unchanged (expr);
2042
+ }
2043
+
2014
2044
simplify_exprt::resultt<>
2015
2045
simplify_exprt::simplify_byte_update (const byte_update_exprt &expr)
2016
2046
{
@@ -2721,9 +2751,10 @@ simplify_exprt::simplify_overflow_result(const overflow_result_exprt &expr)
2721
2751
}
2722
2752
}
2723
2753
2724
- bool simplify_exprt::simplify_node_preorder (exprt &expr)
2754
+ simplify_exprt::resultt<>
2755
+ simplify_exprt::simplify_node_preorder (const exprt &expr)
2725
2756
{
2726
- bool result= true ;
2757
+ auto result = unchanged (expr) ;
2727
2758
2728
2759
// The ifs below could one day be replaced by a switch()
2729
2760
@@ -2732,40 +2763,75 @@ bool simplify_exprt::simplify_node_preorder(exprt &expr)
2732
2763
// the argument of this expression needs special treatment
2733
2764
}
2734
2765
else if (expr.id ()==ID_if)
2735
- result=simplify_if_preorder (to_if_expr (expr));
2766
+ {
2767
+ result = simplify_if_preorder (to_if_expr (expr));
2768
+ }
2736
2769
else if (expr.id () == ID_typecast)
2770
+ {
2737
2771
result = simplify_typecast_preorder (to_typecast_expr (expr));
2738
- else
2772
+ }
2773
+ else if (
2774
+ expr.id () == ID_byte_extract_little_endian ||
2775
+ expr.id () == ID_byte_extract_big_endian)
2776
+ {
2777
+ result = simplify_byte_extract_preorder (to_byte_extract_expr (expr));
2778
+ }
2779
+ else if (expr.id () == ID_dereference)
2780
+ {
2781
+ result = simplify_dereference_preorder (to_dereference_expr (expr));
2782
+ }
2783
+ else if (expr.id () == ID_index)
2739
2784
{
2740
- if (expr.has_operands ())
2785
+ result = simplify_index_preorder (to_index_expr (expr));
2786
+ }
2787
+ else if (expr.id () == ID_member)
2788
+ {
2789
+ result = simplify_member_preorder (to_member_expr (expr));
2790
+ }
2791
+ else if (
2792
+ expr.id () == ID_is_dynamic_object || expr.id () == ID_is_invalid_pointer ||
2793
+ expr.id () == ID_object_size || expr.id () == ID_pointer_object ||
2794
+ expr.id () == ID_pointer_offset)
2795
+ {
2796
+ result = simplify_unary_pointer_predicate_preorder (to_unary_expr (expr));
2797
+ }
2798
+ else if (expr.has_operands ())
2799
+ {
2800
+ optionalt<exprt::operandst> new_operands;
2801
+
2802
+ for (std::size_t i = 0 ; i < expr.operands ().size (); ++i)
2741
2803
{
2742
- Forall_operands (it, expr)
2804
+ auto r_it = simplify_rec (expr.operands ()[i]); // recursive call
2805
+ if (r_it.has_changed ())
2743
2806
{
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
- }
2807
+ if (!new_operands.has_value ())
2808
+ new_operands = expr.operands ();
2809
+ (*new_operands)[i] = std::move (r_it.expr );
2750
2810
}
2751
2811
}
2812
+
2813
+ if (new_operands.has_value ())
2814
+ {
2815
+ std::swap (result.expr .operands (), *new_operands);
2816
+ result.expr_changed = resultt<>::CHANGED;
2817
+ }
2752
2818
}
2753
2819
2754
- if (as_const (expr).type ().id () == ID_array)
2820
+ if (as_const (result. expr ).type ().id () == ID_array)
2755
2821
{
2756
- const array_typet &array_type = to_array_type (as_const (expr).type ());
2822
+ const array_typet &array_type = to_array_type (as_const (result. expr ).type ());
2757
2823
resultt<> simp_size = simplify_rec (array_type.size ());
2758
2824
if (simp_size.has_changed ())
2759
2825
{
2760
- to_array_type (expr.type ()).size () = simp_size.expr ;
2761
- result = false ;
2826
+ to_array_type (result. expr .type ()).size () = simp_size.expr ;
2827
+ result. expr_changed = resultt<>::CHANGED ;
2762
2828
}
2763
2829
}
2764
2830
2765
2831
return result;
2766
2832
}
2767
2833
2768
- simplify_exprt::resultt<> simplify_exprt::simplify_node (exprt node)
2834
+ simplify_exprt::resultt<> simplify_exprt::simplify_node (const exprt & node)
2769
2835
{
2770
2836
if (!node.has_operands ())
2771
2837
return unchanged (node); // no change
@@ -3062,53 +3128,54 @@ simplify_exprt::resultt<> simplify_exprt::simplify_rec(const exprt &expr)
3062
3128
#endif
3063
3129
3064
3130
// We work on a copy to prevent unnecessary destruction of sharing.
3065
- exprt tmp=expr;
3066
- bool no_change = simplify_node_preorder (tmp);
3131
+ auto simplify_node_preorder_result = simplify_node_preorder (expr);
3067
3132
3068
- auto simplify_node_result = simplify_node (tmp );
3133
+ auto simplify_node_result = simplify_node (simplify_node_preorder_result. expr );
3069
3134
3070
- if (simplify_node_result.has_changed ())
3135
+ if (
3136
+ !simplify_node_result.has_changed () &&
3137
+ simplify_node_preorder_result.has_changed ())
3071
3138
{
3072
- no_change = false ;
3073
- tmp = simplify_node_result. expr ;
3139
+ simplify_node_result. expr_changed =
3140
+ simplify_node_preorder_result. expr_changed ;
3074
3141
}
3075
3142
3076
3143
#ifdef USE_LOCAL_REPLACE_MAP
3077
- #if 1
3078
- replace_mapt::const_iterator it=local_replace_map.find (tmp);
3144
+ exprt tmp = simplify_node_result.expr ;
3145
+ # if 1
3146
+ replace_mapt::const_iterator it =
3147
+ local_replace_map.find (simplify_node_result.expr );
3079
3148
if (it!=local_replace_map.end ())
3149
+ simplify_node_result = changed (it->second );
3150
+ # else
3151
+ if (
3152
+ !local_replace_map.empty () &&
3153
+ !replace_expr (local_replace_map, simplify_node_result.expr ))
3080
3154
{
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;
3155
+ simplify_node_result = changed (simplify_rec (simplify_node_result.expr ));
3090
3156
}
3091
- # endif
3157
+ # endif
3092
3158
#endif
3093
3159
3094
- if (no_change) // no change
3160
+ if (!simplify_node_result. has_changed ())
3095
3161
{
3096
3162
return unchanged (expr);
3097
3163
}
3098
- else // change, new expression is 'tmp'
3164
+ else
3099
3165
{
3100
3166
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 (),
3167
+ (as_const (simplify_node_result.expr ).type ().id () == ID_array &&
3168
+ expr.type ().id () == ID_array) ||
3169
+ as_const (simplify_node_result.expr ).type () == expr.type (),
3170
+ simplify_node_result.expr .pretty (),
3104
3171
expr.pretty ());
3105
3172
3106
3173
#ifdef USE_CACHE
3107
3174
// save in cache
3108
- cache_result.first ->second = tmp ;
3175
+ cache_result.first ->second = simplify_node_result. expr ;
3109
3176
#endif
3110
3177
3111
- return std::move (tmp) ;
3178
+ return simplify_node_result ;
3112
3179
}
3113
3180
}
3114
3181
0 commit comments