Skip to content

Commit 2f4bff1

Browse files
committed
WIP: Use resultt for simplify_node_preorder
1 parent f84777f commit 2f4bff1

File tree

3 files changed

+112
-102
lines changed

3 files changed

+112
-102
lines changed

src/util/simplify_expr.cpp

Lines changed: 46 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -2047,38 +2047,46 @@ simplify_exprt::simplify_complex(const unary_exprt &expr)
20472047
return unchanged(expr);
20482048
}
20492049

2050-
bool simplify_exprt::simplify_node_preorder(exprt &expr)
2050+
simplify_exprt::resultt<>
2051+
simplify_exprt::simplify_node_preorder(const exprt &expr)
20512052
{
2052-
bool result=true;
2053-
20542053
// The ifs below could one day be replaced by a switch()
20552054

20562055
if(expr.id()==ID_address_of)
20572056
{
20582057
// the argument of this expression needs special treatment
20592058
}
20602059
else if(expr.id()==ID_if)
2061-
result=simplify_if_preorder(to_if_expr(expr));
2062-
else
20632060
{
2064-
if(expr.has_operands())
2061+
return simplify_if_preorder(to_if_expr(expr));
2062+
}
2063+
else if(expr.has_operands())
2064+
{
2065+
optionalt<exprt::operandst> new_operands;
2066+
2067+
for(std::size_t i = 0; i < expr.operands().size(); ++i)
20652068
{
2066-
Forall_operands(it, expr)
2069+
auto r_it = simplify_rec(expr.operands()[i]); // recursive call
2070+
if(r_it.has_changed())
20672071
{
2068-
auto r_it = simplify_rec(*it); // recursive call
2069-
if(r_it.has_changed())
2070-
{
2071-
*it = r_it.expr;
2072-
result=false;
2073-
}
2072+
if(!new_operands.has_value())
2073+
new_operands = expr.operands();
2074+
(*new_operands)[i] = std::move(r_it.expr);
20742075
}
20752076
}
2077+
2078+
if(new_operands.has_value())
2079+
{
2080+
exprt result = expr;
2081+
std::swap(result.operands(), *new_operands);
2082+
return result;
2083+
}
20762084
}
20772085

2078-
return result;
2086+
return unchanged(expr);
20792087
}
20802088

2081-
simplify_exprt::resultt<> simplify_exprt::simplify_node(exprt node)
2089+
simplify_exprt::resultt<> simplify_exprt::simplify_node(const exprt &node)
20822090
{
20832091
if(!node.has_operands())
20842092
return unchanged(node); // no change
@@ -2332,49 +2340,47 @@ simplify_exprt::resultt<> simplify_exprt::simplify_rec(const exprt &expr)
23322340
#endif
23332341

23342342
// We work on a copy to prevent unnecessary destruction of sharing.
2335-
exprt tmp=expr;
2336-
bool no_change = simplify_node_preorder(tmp);
2343+
auto simplify_node_preorder_result = simplify_node_preorder(expr);
23372344

2338-
auto simplify_node_result = simplify_node(tmp);
2345+
auto simplify_node_result = simplify_node(simplify_node_preorder_result.expr);
23392346

2340-
if(simplify_node_result.has_changed())
2341-
{
2342-
no_change = false;
2343-
tmp = simplify_node_result.expr;
2344-
}
2347+
if(
2348+
!simplify_node_result.has_changed() &&
2349+
simplify_node_preorder_result.has_changed())
2350+
simplify_node_result.expr_changed =
2351+
simplify_node_preorder_result.expr_changed;
23452352

23462353
#ifdef USE_LOCAL_REPLACE_MAP
2347-
#if 1
2348-
replace_mapt::const_iterator it=local_replace_map.find(tmp);
2354+
exprt tmp = simplify_node_result.expr;
2355+
# if 1
2356+
replace_mapt::const_iterator it =
2357+
local_replace_map.find(simplify_node_result.expr);
23492358
if(it!=local_replace_map.end())
2359+
simplify_node_result = changed(it->second);
2360+
# else
2361+
if(
2362+
!local_replace_map.empty() &&
2363+
!replace_expr(local_replace_map, simplify_node_result.expr))
23502364
{
2351-
tmp=it->second;
2352-
no_change = false;
2353-
}
2354-
#else
2355-
if(!local_replace_map.empty() &&
2356-
!replace_expr(local_replace_map, tmp))
2357-
{
2358-
simplify_rec(tmp);
2359-
no_change = false;
2365+
simplify_node_result = changed(simplify_rec(simplify_node_result.expr));
23602366
}
2361-
#endif
2367+
# endif
23622368
#endif
23632369

2364-
if(no_change) // no change
2370+
if(!simplify_node_result.has_changed())
23652371
{
23662372
return unchanged(expr);
23672373
}
2368-
else // change, new expression is 'tmp'
2374+
else
23692375
{
2370-
POSTCONDITION(as_const(tmp).type() == expr.type());
2376+
POSTCONDITION(as_const(simplify_node_result.expr).type() == expr.type());
23712377

23722378
#ifdef USE_CACHE
23732379
// save in cache
2374-
cache_result.first->second = tmp;
2380+
cache_result.first->second = simplify_node_result.expr;
23752381
#endif
23762382

2377-
return std::move(tmp);
2383+
return simplify_node_result;
23782384
}
23792385
}
23802386

src/util/simplify_expr_class.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ class simplify_exprt
150150
NODISCARD resultt<> simplify_shifts(const shift_exprt &);
151151
NODISCARD resultt<> simplify_power(const binary_exprt &);
152152
NODISCARD resultt<> simplify_bitwise(const multi_ary_exprt &);
153-
bool simplify_if_preorder(if_exprt &expr);
153+
NODISCARD resultt<> simplify_if_preorder(const if_exprt &expr);
154154
NODISCARD resultt<> simplify_if(const if_exprt &);
155155
NODISCARD resultt<> simplify_bitnot(const bitnot_exprt &);
156156
NODISCARD resultt<> simplify_not(const not_exprt &);
@@ -211,8 +211,8 @@ class simplify_exprt
211211
simplify_inequality_pointer_object(const binary_relation_exprt &);
212212

213213
// main recursion
214-
NODISCARD resultt<> simplify_node(exprt);
215-
bool simplify_node_preorder(exprt &expr);
214+
NODISCARD resultt<> simplify_node(const exprt &);
215+
NODISCARD resultt<> simplify_node_preorder(const exprt &);
216216
NODISCARD resultt<> simplify_rec(const exprt &);
217217

218218
virtual bool simplify(exprt &expr);

src/util/simplify_expr_if.cpp

Lines changed: 63 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -212,47 +212,66 @@ bool simplify_exprt::simplify_if_cond(exprt &expr)
212212
return no_change;
213213
}
214214

215-
bool simplify_exprt::simplify_if_preorder(if_exprt &expr)
215+
static simplify_exprt::resultt<> build_if_expr(
216+
const if_exprt &expr,
217+
simplify_exprt::resultt<> cond,
218+
simplify_exprt::resultt<> truevalue,
219+
simplify_exprt::resultt<> falsevalue)
216220
{
217-
exprt &cond = expr.cond();
218-
exprt &truevalue = expr.true_case();
219-
exprt &falsevalue = expr.false_case();
221+
if(
222+
!cond.has_changed() && !truevalue.has_changed() &&
223+
!falsevalue.has_changed())
224+
{
225+
return simplify_exprt::resultt<>(
226+
simplify_exprt::resultt<>::UNCHANGED, expr);
227+
}
228+
else
229+
{
230+
if_exprt result = expr;
231+
if(cond.has_changed())
232+
result.cond() = std::move(cond.expr);
233+
if(truevalue.has_changed())
234+
result.true_case() = std::move(truevalue.expr);
235+
if(falsevalue.has_changed())
236+
result.false_case() = std::move(falsevalue.expr);
237+
return result;
238+
}
239+
}
220240

221-
bool no_change = true;
241+
simplify_exprt::resultt<>
242+
simplify_exprt::simplify_if_preorder(const if_exprt &expr)
243+
{
244+
const exprt &cond = expr.cond();
245+
const exprt &truevalue = expr.true_case();
246+
const exprt &falsevalue = expr.false_case();
222247

223248
// we first want to look at the condition
224249
auto r_cond = simplify_rec(cond);
225-
if(r_cond.has_changed())
226-
{
227-
cond = r_cond.expr;
228-
no_change = false;
229-
}
230250

231251
// 1 ? a : b -> a and 0 ? a : b -> b
232-
if(cond.is_constant())
252+
if(r_cond.expr.is_constant())
233253
{
234-
exprt tmp = cond.is_true() ? truevalue : falsevalue;
235-
tmp = simplify_rec(tmp);
236-
expr.swap(tmp);
237-
return false;
254+
return changed(
255+
simplify_rec(r_cond.expr.is_true() ? truevalue : falsevalue));
238256
}
239257

240258
if(do_simplify_if)
241259
{
242-
if(cond.id() == ID_not)
260+
bool swap_branches = false;
261+
262+
if(r_cond.expr.id() == ID_not)
243263
{
244-
cond = to_not_expr(cond).op();
245-
truevalue.swap(falsevalue);
246-
no_change = false;
264+
r_cond = changed(to_not_expr(r_cond.expr).op());
265+
swap_branches = true;
247266
}
248267

249268
#ifdef USE_LOCAL_REPLACE_MAP
250269
replace_mapt map_before(local_replace_map);
251270

252271
// a ? b : c --> a ? b[a/true] : c
253-
if(cond.id() == ID_and)
272+
if(r_cond.expr.id() == ID_and)
254273
{
255-
forall_operands(it, cond)
274+
forall_operands(it, r_cond.expr)
256275
{
257276
if(it->id() == ID_not)
258277
local_replace_map.insert(std::make_pair(it->op0(), false_exprt()));
@@ -261,21 +280,18 @@ bool simplify_exprt::simplify_if_preorder(if_exprt &expr)
261280
}
262281
}
263282
else
264-
local_replace_map.insert(std::make_pair(cond, true_exprt()));
283+
local_replace_map.insert(std::make_pair(r_cond.expr, true_exprt()));
265284

266-
auto r_truevalue = simplify_rec(truevalue);
267-
if(r_truevalue.has_changed())
268-
{
269-
truevalue = r_truevalue.expr;
270-
no_change = false;
271-
}
285+
auto r_truevalue = simplify_rec(swap_branches ? falsevalue : truevalue);
286+
if(swap_branches)
287+
r_truevalue.expr_changed = CHANGED;
272288

273289
local_replace_map = map_before;
274290

275291
// a ? b : c --> a ? b : c[a/false]
276-
if(cond.id() == ID_or)
292+
if(r_cond.expr.id() == ID_or)
277293
{
278-
forall_operands(it, cond)
294+
forall_operands(it, r_cond.expr)
279295
{
280296
if(it->id() == ID_not)
281297
local_replace_map.insert(std::make_pair(it->op0(), true_exprt()));
@@ -284,48 +300,36 @@ bool simplify_exprt::simplify_if_preorder(if_exprt &expr)
284300
}
285301
}
286302
else
287-
local_replace_map.insert(std::make_pair(cond, false_exprt()));
303+
local_replace_map.insert(std::make_pair(r_cond.expr, false_exprt()));
288304

289-
auto r_falsevalue = simplify_rec(falsevalue);
290-
if(r_falsevalue.has_changed())
291-
{
292-
falsevalue = r_falsevalue.expr;
293-
no_change = false;
294-
}
305+
auto falsevalue = simplify_rec(swap_branches ? falsevalue : truevalue);
306+
if(swap_branches)
307+
r_falsevalue.expr_changed = CHANGED;
295308

296309
local_replace_map.swap(map_before);
310+
311+
return build_if_expr(expr, r_cond, r_truevalue, r_falsevalue);
297312
#else
298-
auto r_truevalue = simplify_rec(truevalue);
299-
if(r_truevalue.has_changed())
313+
if(!swap_branches)
300314
{
301-
truevalue = r_truevalue.expr;
302-
no_change = false;
315+
return build_if_expr(
316+
expr, r_cond, simplify_rec(truevalue), simplify_rec(falsevalue));
303317
}
304-
auto r_falsevalue = simplify_rec(falsevalue);
305-
if(r_falsevalue.has_changed())
318+
else
306319
{
307-
falsevalue = r_falsevalue.expr;
308-
no_change = false;
320+
return build_if_expr(
321+
expr,
322+
r_cond,
323+
changed(simplify_rec(falsevalue)),
324+
changed(simplify_rec(truevalue)));
309325
}
310326
#endif
311327
}
312328
else
313329
{
314-
auto r_truevalue = simplify_rec(truevalue);
315-
if(r_truevalue.has_changed())
316-
{
317-
truevalue = r_truevalue.expr;
318-
no_change = false;
319-
}
320-
auto r_falsevalue = simplify_rec(falsevalue);
321-
if(r_falsevalue.has_changed())
322-
{
323-
falsevalue = r_falsevalue.expr;
324-
no_change = false;
325-
}
330+
return build_if_expr(
331+
expr, r_cond, simplify_rec(truevalue), simplify_rec(falsevalue));
326332
}
327-
328-
return no_change;
329333
}
330334

331335
simplify_exprt::resultt<> simplify_exprt::simplify_if(const if_exprt &expr)

0 commit comments

Comments
 (0)