Skip to content

Commit 0592f63

Browse files
committed
WIP: Use resultt for simplify_node_preorder
1 parent 5309768 commit 0592f63

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
@@ -2013,38 +2013,46 @@ simplify_exprt::simplify_complex(const unary_exprt &expr)
20132013
return unchanged(expr);
20142014
}
20152015

2016-
bool simplify_exprt::simplify_node_preorder(exprt &expr)
2016+
simplify_exprt::resultt<>
2017+
simplify_exprt::simplify_node_preorder(const exprt &expr)
20172018
{
2018-
bool result=true;
2019-
20202019
// The ifs below could one day be replaced by a switch()
20212020

20222021
if(expr.id()==ID_address_of)
20232022
{
20242023
// the argument of this expression needs special treatment
20252024
}
20262025
else if(expr.id()==ID_if)
2027-
result=simplify_if_preorder(to_if_expr(expr));
2028-
else
20292026
{
2030-
if(expr.has_operands())
2027+
return simplify_if_preorder(to_if_expr(expr));
2028+
}
2029+
else if(expr.has_operands())
2030+
{
2031+
optionalt<exprt::operandst> new_operands;
2032+
2033+
for(std::size_t i = 0; i < expr.operands().size(); ++i)
20312034
{
2032-
Forall_operands(it, expr)
2035+
auto r_it = simplify_rec(expr.operands()[i]); // recursive call
2036+
if(r_it.has_changed())
20332037
{
2034-
auto r_it = simplify_rec(*it); // recursive call
2035-
if(r_it.has_changed())
2036-
{
2037-
*it = r_it.expr;
2038-
result=false;
2039-
}
2038+
if(!new_operands.has_value())
2039+
new_operands = expr.operands();
2040+
(*new_operands)[i] = std::move(r_it.expr);
20402041
}
20412042
}
2043+
2044+
if(new_operands.has_value())
2045+
{
2046+
exprt result = expr;
2047+
std::swap(result.operands(), *new_operands);
2048+
return result;
2049+
}
20422050
}
20432051

2044-
return result;
2052+
return unchanged(expr);
20452053
}
20462054

2047-
simplify_exprt::resultt<> simplify_exprt::simplify_node(exprt node)
2055+
simplify_exprt::resultt<> simplify_exprt::simplify_node(const exprt &node)
20482056
{
20492057
if(!node.has_operands())
20502058
return unchanged(node); // no change
@@ -2298,49 +2306,47 @@ simplify_exprt::resultt<> simplify_exprt::simplify_rec(const exprt &expr)
22982306
#endif
22992307

23002308
// We work on a copy to prevent unnecessary destruction of sharing.
2301-
exprt tmp=expr;
2302-
bool no_change = simplify_node_preorder(tmp);
2309+
auto simplify_node_preorder_result = simplify_node_preorder(expr);
23032310

2304-
auto simplify_node_result = simplify_node(tmp);
2311+
auto simplify_node_result = simplify_node(simplify_node_preorder_result.expr);
23052312

2306-
if(simplify_node_result.has_changed())
2307-
{
2308-
no_change = false;
2309-
tmp = simplify_node_result.expr;
2310-
}
2313+
if(
2314+
!simplify_node_result.has_changed() &&
2315+
simplify_node_preorder_result.has_changed())
2316+
simplify_node_result.expr_changed =
2317+
simplify_node_preorder_result.expr_changed;
23112318

23122319
#ifdef USE_LOCAL_REPLACE_MAP
2313-
#if 1
2314-
replace_mapt::const_iterator it=local_replace_map.find(tmp);
2320+
exprt tmp = simplify_node_result.expr;
2321+
# if 1
2322+
replace_mapt::const_iterator it =
2323+
local_replace_map.find(simplify_node_result.expr);
23152324
if(it!=local_replace_map.end())
2325+
simplify_node_result = changed(it->second);
2326+
# else
2327+
if(
2328+
!local_replace_map.empty() &&
2329+
!replace_expr(local_replace_map, simplify_node_result.expr))
23162330
{
2317-
tmp=it->second;
2318-
no_change = false;
2319-
}
2320-
#else
2321-
if(!local_replace_map.empty() &&
2322-
!replace_expr(local_replace_map, tmp))
2323-
{
2324-
simplify_rec(tmp);
2325-
no_change = false;
2331+
simplify_node_result = changed(simplify_rec(simplify_node_result.expr));
23262332
}
2327-
#endif
2333+
# endif
23282334
#endif
23292335

2330-
if(no_change) // no change
2336+
if(!simplify_node_result.has_changed())
23312337
{
23322338
return unchanged(expr);
23332339
}
2334-
else // change, new expression is 'tmp'
2340+
else
23352341
{
2336-
POSTCONDITION(as_const(tmp).type() == expr.type());
2342+
POSTCONDITION(as_const(simplify_node_result.expr).type() == expr.type());
23372343

23382344
#ifdef USE_CACHE
23392345
// save in cache
2340-
cache_result.first->second = tmp;
2346+
cache_result.first->second = simplify_node_result.expr;
23412347
#endif
23422348

2343-
return std::move(tmp);
2349+
return simplify_node_result;
23442350
}
23452351
}
23462352

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)