Skip to content

Commit 700c378

Browse files
committed
New implementation of (still disabled) expression replacement in simplify_if
1 parent 46c5afc commit 700c378

File tree

2 files changed

+129
-51
lines changed

2 files changed

+129
-51
lines changed

src/util/simplify_expr.cpp

Lines changed: 124 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1106,7 +1106,7 @@ bool simplify_exprt::simplify_if_cond(exprt &expr)
11061106

11071107
/*******************************************************************\
11081108
1109-
Function: simplify_exprt::simplify_if
1109+
Function: simplify_exprt::simplify_if_preorder
11101110
11111111
Inputs:
11121112
@@ -1116,25 +1116,24 @@ Function: simplify_exprt::simplify_if
11161116
11171117
\*******************************************************************/
11181118

1119-
bool simplify_exprt::simplify_if(exprt &expr)
1119+
bool simplify_exprt::simplify_if_preorder(if_exprt &expr)
11201120
{
1121-
exprt::operandst &operands=expr.operands();
1122-
if(operands.size()!=3) return true;
1121+
exprt &cond=expr.cond();
1122+
exprt &truevalue=expr.true_case();
1123+
exprt &falsevalue=expr.false_case();
11231124

1124-
exprt &cond=operands[0];
1125-
exprt &truevalue=operands[1];
1126-
exprt &falsevalue=operands[2];
1125+
// we first want to look at the condition
1126+
bool result=simplify_rec(cond);
11271127

1128-
if(truevalue==falsevalue)
1128+
// 1 ? a : b -> a and 0 ? a : b -> b
1129+
if(cond.is_constant())
11291130
{
1130-
exprt tmp;
1131-
tmp.swap(truevalue);
1131+
exprt tmp=cond.is_true()?truevalue:falsevalue;
1132+
simplify_rec(tmp);
11321133
expr.swap(tmp);
11331134
return false;
11341135
}
11351136

1136-
bool result=true;
1137-
11381137
if(do_simplify_if)
11391138
{
11401139
if(cond.id()==ID_not)
@@ -1146,6 +1145,84 @@ bool simplify_exprt::simplify_if(exprt &expr)
11461145
result=false;
11471146
}
11481147

1148+
#if 0
1149+
replace_mapt map_before(local_replace_map);
1150+
1151+
// a ? b : c --> a ? b[a/true] : c
1152+
if(cond.id()==ID_and)
1153+
{
1154+
forall_operands(it, cond)
1155+
{
1156+
if(it->id()==ID_not)
1157+
local_replace_map.insert(
1158+
std::make_pair(it->op0(), false_exprt()));
1159+
else
1160+
local_replace_map.insert(
1161+
std::make_pair(*it, true_exprt()));
1162+
}
1163+
}
1164+
else
1165+
local_replace_map.insert(std::make_pair(cond, true_exprt()));
1166+
1167+
result=simplify_rec(truevalue) && result;
1168+
1169+
local_replace_map=map_before;
1170+
1171+
// a ? b : c --> a ? b : c[a/false]
1172+
if(cond.id()==ID_or)
1173+
{
1174+
forall_operands(it, cond)
1175+
{
1176+
if(it->id()==ID_not)
1177+
local_replace_map.insert(
1178+
std::make_pair(it->op0(), true_exprt()));
1179+
else
1180+
local_replace_map.insert(
1181+
std::make_pair(*it, false_exprt()));
1182+
}
1183+
}
1184+
else
1185+
local_replace_map.insert(std::make_pair(cond, false_exprt()));
1186+
1187+
result=simplify_rec(falsevalue) && result;
1188+
1189+
local_replace_map.swap(map_before);
1190+
#else
1191+
result=simplify_rec(truevalue) && result;
1192+
result=simplify_rec(falsevalue) && result;
1193+
#endif
1194+
}
1195+
else
1196+
{
1197+
result=simplify_rec(truevalue) && result;
1198+
result=simplify_rec(falsevalue) && result;
1199+
}
1200+
1201+
return result;
1202+
}
1203+
1204+
/*******************************************************************\
1205+
1206+
Function: simplify_exprt::simplify_if
1207+
1208+
Inputs:
1209+
1210+
Outputs:
1211+
1212+
Purpose:
1213+
1214+
\*******************************************************************/
1215+
1216+
bool simplify_exprt::simplify_if(if_exprt &expr)
1217+
{
1218+
exprt &cond=expr.cond();
1219+
exprt &truevalue=expr.true_case();
1220+
exprt &falsevalue=expr.false_case();
1221+
1222+
bool result=true;
1223+
1224+
if(do_simplify_if)
1225+
{
11491226
#if 0
11501227
result = simplify_if_cond(cond) && result;
11511228
result = simplify_if_branch(truevalue, falsevalue, cond) && result;
@@ -1210,35 +1287,34 @@ bool simplify_exprt::simplify_if(exprt &expr)
12101287
return false;
12111288
}
12121289
}
1213-
1214-
#if 0
1215-
// a ? b : c --> a ? b[a/true] : c
1216-
exprt tmp_true=truevalue;
1217-
replace_expr(cond, true_exprt(), tmp_true);
1218-
if(tmp_true!=truevalue)
1219-
{ truevalue=tmp_true; simplify_rec(truevalue); result=false; }
1220-
1221-
// a ? b : c --> a ? b : c[a/false]
1222-
exprt tmp_false=falsevalue;
1223-
replace_expr(cond, false_exprt(), tmp_false);
1224-
if(tmp_false!=falsevalue)
1225-
{ falsevalue=tmp_false; simplify_rec(falsevalue); result=false; }
1226-
#endif
12271290
}
12281291

1229-
if(cond.is_true())
1292+
if(truevalue==falsevalue)
12301293
{
12311294
exprt tmp;
12321295
tmp.swap(truevalue);
12331296
expr.swap(tmp);
12341297
return false;
12351298
}
12361299

1237-
if(cond.is_false())
1300+
if(((truevalue.id()==ID_struct && falsevalue.id()==ID_struct) ||
1301+
(truevalue.id()==ID_array && falsevalue.id()==ID_array)) &&
1302+
truevalue.operands().size()==falsevalue.operands().size())
12381303
{
1239-
exprt tmp;
1240-
tmp.swap(falsevalue);
1241-
expr.swap(tmp);
1304+
exprt cond_copy=cond;
1305+
exprt falsevalue_copy=falsevalue;
1306+
expr.swap(truevalue);
1307+
1308+
exprt::operandst::const_iterator f_it=
1309+
falsevalue_copy.operands().begin();
1310+
Forall_operands(it, expr)
1311+
{
1312+
if_exprt if_expr(cond_copy, *it, *f_it);
1313+
it->swap(if_expr);
1314+
simplify_if(to_if_expr(*it));
1315+
++f_it;
1316+
}
1317+
12421318
return false;
12431319
}
12441320

@@ -2331,25 +2407,7 @@ bool simplify_exprt::simplify_node_preorder(exprt &expr)
23312407
// the argument of this expression needs special treatment
23322408
}
23332409
else if(expr.id()==ID_if)
2334-
{
2335-
// we first want to look at the condition
2336-
if_exprt &if_expr=to_if_expr(expr);
2337-
if(!simplify_rec(if_expr.cond())) result=false;
2338-
2339-
// 1 ? a : b -> a and 0 ? a : b -> b
2340-
if(if_expr.cond().is_constant())
2341-
{
2342-
expr=if_expr.cond().is_true()?
2343-
if_expr.true_case():if_expr.false_case();
2344-
simplify_rec(expr);
2345-
result=false;
2346-
}
2347-
else
2348-
{
2349-
if(!simplify_rec(if_expr.true_case())) result=false;
2350-
if(!simplify_rec(if_expr.false_case())) result=false;
2351-
}
2352-
}
2410+
result=simplify_if_preorder(to_if_expr(expr));
23532411
else
23542412
{
23552413
if(expr.has_operands())
@@ -2545,6 +2603,22 @@ bool simplify_exprt::simplify_rec(exprt &expr)
25452603

25462604
if(!simplify_node(tmp)) result=false;
25472605

2606+
#if 1
2607+
replace_mapt::const_iterator it=local_replace_map.find(tmp);
2608+
if(it!=local_replace_map.end())
2609+
{
2610+
tmp=it->second;
2611+
result=false;
2612+
}
2613+
#else
2614+
if(!local_replace_map.empty() &&
2615+
!replace_expr(local_replace_map, tmp))
2616+
{
2617+
simplify_rec(tmp);
2618+
result=false;
2619+
}
2620+
#endif
2621+
25482622
if(!result)
25492623
{
25502624
expr.swap(tmp);

src/util/simplify_expr_class.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,12 @@ Author: Daniel Kroening, kroening@kroening.com
1919

2020
#include "type.h"
2121
#include "mp_arith.h"
22+
#include "replace_expr.h"
2223

2324
class byte_extract_exprt;
2425
class byte_update_exprt;
2526
class exprt;
27+
class if_exprt;
2628
class index_exprt;
2729
class member_exprt;
2830
class namespacet;
@@ -70,7 +72,8 @@ class simplify_exprt
7072
bool simplify_floatbv_typecast(exprt &expr);
7173
bool simplify_shifts(exprt &expr);
7274
bool simplify_bitwise(exprt &expr);
73-
bool simplify_if(exprt &expr);
75+
bool simplify_if_preorder(if_exprt &expr);
76+
bool simplify_if(if_exprt &expr);
7477
bool simplify_bitnot(exprt &expr);
7578
bool simplify_not(exprt &expr);
7679
bool simplify_boolean(exprt &expr);
@@ -145,6 +148,7 @@ class simplify_exprt
145148
#ifdef DEBUG_ON_DEMAND
146149
bool debug_on;
147150
#endif
151+
replace_mapt local_replace_map;
148152
};
149153

150154
#endif

0 commit comments

Comments
 (0)