@@ -22,6 +22,7 @@ Author: Daniel Kroening, kroening@kroening.com
22
22
#include " namespace.h"
23
23
#include " pointer_offset_size.h"
24
24
#include " pointer_offset_sum.h"
25
+ #include " range.h"
25
26
#include " rational.h"
26
27
#include " rational_tools.h"
27
28
#include " simplify_utils.h"
@@ -990,9 +991,7 @@ simplify_exprt::simplify_dereference(const dereference_exprt &expr)
990
991
991
992
if_exprt tmp{if_expr.cond (), tmp_op1_result, tmp_op2_result};
992
993
993
- simplify_if (tmp);
994
-
995
- return tmp;
994
+ return changed (simplify_if (tmp));
996
995
}
997
996
998
997
if (pointer.id ()==ID_address_of)
@@ -1310,13 +1309,12 @@ bool simplify_exprt::simplify_if_preorder(if_exprt &expr)
1310
1309
return result;
1311
1310
}
1312
1311
1313
- bool simplify_exprt::simplify_if (if_exprt &expr)
1312
+ NODISCARD simplify_exprt::resultt<>
1313
+ simplify_exprt::simplify_if (const if_exprt &expr)
1314
1314
{
1315
- exprt &cond=expr.cond ();
1316
- exprt &truevalue=expr.true_case ();
1317
- exprt &falsevalue=expr.false_case ();
1318
-
1319
- bool result=true ;
1315
+ const exprt &cond = expr.cond ();
1316
+ const exprt &truevalue = expr.true_case ();
1317
+ const exprt &falsevalue = expr.false_case ();
1320
1318
1321
1319
if (do_simplify_if)
1322
1320
{
@@ -1332,26 +1330,21 @@ bool simplify_exprt::simplify_if(if_exprt &expr)
1332
1330
if (truevalue.is_true () && falsevalue.is_false ())
1333
1331
{
1334
1332
// a?1:0 <-> a
1335
- exprt tmp;
1336
- tmp.swap (cond);
1337
- expr.swap (tmp);
1338
- return false ;
1333
+ return cond;
1339
1334
}
1340
1335
else if (truevalue.is_false () && falsevalue.is_true ())
1341
1336
{
1342
1337
// a?0:1 <-> !a
1343
1338
exprt tmp = boolean_negate (cond);
1344
1339
simplify_node (tmp);
1345
- expr.swap (tmp);
1346
- return false ;
1340
+ return std::move (tmp);
1347
1341
}
1348
1342
else if (falsevalue.is_false ())
1349
1343
{
1350
1344
// a?b:0 <-> a AND b
1351
1345
and_exprt tmp (cond, truevalue);
1352
1346
simplify_node (tmp);
1353
- expr.swap (tmp);
1354
- return false ;
1347
+ return std::move (tmp);
1355
1348
}
1356
1349
else if (falsevalue.is_true ())
1357
1350
{
@@ -1360,16 +1353,14 @@ bool simplify_exprt::simplify_if(if_exprt &expr)
1360
1353
simplify_node (tmp_not_cond);
1361
1354
or_exprt tmp (tmp_not_cond, truevalue);
1362
1355
simplify_node (tmp);
1363
- expr.swap (tmp);
1364
- return false ;
1356
+ return std::move (tmp);
1365
1357
}
1366
1358
else if (truevalue.is_true ())
1367
1359
{
1368
1360
// a?1:b <-> a||(!a && b) <-> a OR b
1369
1361
or_exprt tmp (cond, falsevalue);
1370
1362
simplify_node (tmp);
1371
- expr.swap (tmp);
1372
- return false ;
1363
+ return std::move (tmp);
1373
1364
}
1374
1365
else if (truevalue.is_false ())
1375
1366
{
@@ -1378,42 +1369,38 @@ bool simplify_exprt::simplify_if(if_exprt &expr)
1378
1369
simplify_node (tmp_not_cond);
1379
1370
and_exprt tmp (tmp_not_cond, falsevalue);
1380
1371
simplify_node (tmp);
1381
- expr.swap (tmp);
1382
- return false ;
1372
+ return std::move (tmp);
1383
1373
}
1384
1374
}
1385
1375
}
1386
1376
1387
1377
if (truevalue==falsevalue)
1388
- {
1389
- exprt tmp;
1390
- tmp.swap (truevalue);
1391
- expr.swap (tmp);
1392
- return false ;
1393
- }
1378
+ return truevalue;
1394
1379
1380
+ // this pushes the if-then-else into struct and array constructors
1395
1381
if (((truevalue.id ()==ID_struct && falsevalue.id ()==ID_struct) ||
1396
1382
(truevalue.id ()==ID_array && falsevalue.id ()==ID_array)) &&
1397
1383
truevalue.operands ().size ()==falsevalue.operands ().size ())
1398
1384
{
1399
1385
exprt cond_copy=cond;
1400
1386
exprt falsevalue_copy=falsevalue;
1401
- expr.swap (truevalue);
1387
+ exprt truevalue_copy = truevalue;
1388
+
1389
+ auto range_false = make_range (falsevalue_copy.operands ());
1390
+ auto range_true = make_range (truevalue_copy.operands ());
1391
+ auto new_expr = truevalue;
1392
+ new_expr.operands ().clear ();
1402
1393
1403
- exprt::operandst::const_iterator f_it=
1404
- falsevalue_copy.operands ().begin ();
1405
- Forall_operands (it, expr)
1394
+ for (const auto &pair : range_true.zip (range_false))
1406
1395
{
1407
- if_exprt if_expr (cond_copy, *it, *f_it);
1408
- it->swap (if_expr);
1409
- simplify_if (to_if_expr (*it));
1410
- ++f_it;
1396
+ new_expr.operands ().push_back (
1397
+ simplify_if (if_exprt (cond_copy, pair.first , pair.second )));
1411
1398
}
1412
1399
1413
- return false ;
1400
+ return std::move (new_expr) ;
1414
1401
}
1415
1402
1416
- return result ;
1403
+ return unchanged (expr) ;
1417
1404
}
1418
1405
1419
1406
bool simplify_exprt::get_values (
@@ -1988,8 +1975,7 @@ simplify_exprt::simplify_byte_extract(const byte_extract_exprt &expr)
1988
1975
simplify_byte_extract (to_byte_extract_expr (if_expr.true_case ()));
1989
1976
if_expr.false_case () =
1990
1977
simplify_byte_extract (to_byte_extract_expr (if_expr.false_case ()));
1991
- simplify_if (if_expr);
1992
- return std::move (if_expr);
1978
+ return simplify_if (if_expr);
1993
1979
}
1994
1980
1995
1981
const auto el_size = pointer_offset_bits (expr.type (), ns);
@@ -2517,7 +2503,14 @@ bool simplify_exprt::simplify_node(exprt &expr)
2517
2503
expr.id ()==ID_ge || expr.id ()==ID_le)
2518
2504
no_change = simplify_inequality (expr) && no_change;
2519
2505
else if (expr.id ()==ID_if)
2520
- no_change = simplify_if (to_if_expr (expr)) && no_change;
2506
+ {
2507
+ auto r = simplify_if (to_if_expr (expr));
2508
+ if (r.has_changed ())
2509
+ {
2510
+ no_change = false ;
2511
+ expr = r.expr ;
2512
+ }
2513
+ }
2521
2514
else if (expr.id ()==ID_lambda)
2522
2515
no_change = simplify_lambda (expr) && no_change;
2523
2516
else if (expr.id ()==ID_with)
0 commit comments