Skip to content

Commit bbdcb8a

Browse files
committed
Refine recursive calls within the simplifier
1) When we know the id of an expression, use the corresponding simplify_* method rather than the generic simplify_node. 2) Avoid simplify_rec when all operands have been simplified already. 3) Don't call simplify_rec (or simplify_node) when there is nothing to simplify. Fixes: diffblue#4988
1 parent ca63a1d commit bbdcb8a

7 files changed

+61
-87
lines changed

src/util/simplify_expr.cpp

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -744,8 +744,8 @@ simplify_exprt::simplify_typecast(const typecast_exprt &expr)
744744
// rewrite (T)(bool) to bool?1:0
745745
auto one = from_integer(1, expr_type);
746746
auto zero = from_integer(0, expr_type);
747-
exprt new_expr = if_exprt(expr.op(), std::move(one), std::move(zero));
748-
return changed(simplify_rec(new_expr)); // recursive call
747+
return changed(simplify_if_preorder(
748+
if_exprt{expr.op(), std::move(one), std::move(zero)}));
749749
}
750750

751751
// circular casts through types shorter than `int`
@@ -834,16 +834,17 @@ simplify_exprt::simplify_typecast(const typecast_exprt &expr)
834834
if(sub_size.has_value())
835835
{
836836
auto new_expr = expr;
837+
exprt offset_expr =
838+
simplify_typecast(typecast_exprt(op_plus_expr.op1(), size_type()));
837839

838840
// void*
839841
if(*sub_size == 0 || *sub_size == 1)
840-
new_expr.op() = typecast_exprt(op_plus_expr.op1(), size_type());
842+
new_expr.op() = offset_expr;
841843
else
842-
new_expr.op() = mult_exprt(
843-
from_integer(*sub_size, size_type()),
844-
typecast_exprt(op_plus_expr.op1(), size_type()));
845-
846-
new_expr.op() = simplify_rec(new_expr.op()); // rec. call
844+
{
845+
new_expr.op() = simplify_mult(
846+
mult_exprt(from_integer(*sub_size, size_type()), offset_expr));
847+
}
847848

848849
return changed(simplify_typecast(new_expr)); // rec. call
849850
}
@@ -915,19 +916,18 @@ simplify_exprt::simplify_typecast(const typecast_exprt &expr)
915916

916917
for(auto &op : new_expr.op().operands())
917918
{
918-
if(op.type().id()==ID_pointer)
919+
exprt new_op = simplify_typecast(typecast_exprt(op, size_t_type));
920+
if(op.type().id() != ID_pointer && *step > 1)
919921
{
920-
op = typecast_exprt(op, size_t_type);
921-
}
922-
else
923-
{
924-
op = typecast_exprt(op, size_t_type);
925-
if(*step > 1)
926-
op = mult_exprt(from_integer(*step, size_t_type), op);
922+
new_op =
923+
simplify_mult(mult_exprt(from_integer(*step, size_t_type), new_op));
927924
}
925+
op = std::move(new_op);
928926
}
929927

930-
return changed(simplify_rec(new_expr)); // recursive call
928+
new_expr.op() = simplify_plus(to_plus_expr(new_expr.op()));
929+
930+
return changed(simplify_typecast(new_expr)); // recursive call
931931
}
932932
}
933933

@@ -1266,7 +1266,7 @@ simplify_exprt::simplify_typecast(const typecast_exprt &expr)
12661266
auto result =
12671267
address_of_exprt(index_exprt(o, from_integer(0, size_type())));
12681268

1269-
return changed(simplify_rec(result)); // recursive call
1269+
return changed(simplify_address_of(result)); // recursive call
12701270
}
12711271
}
12721272

@@ -1666,9 +1666,9 @@ simplify_exprt::simplify_byte_extract(const byte_extract_exprt &expr)
16661666
pointer_offset_bits(to_array_of_expr(expr.op()).what().type(), ns))
16671667
{
16681668
auto tmp = expr;
1669-
tmp.op() = index_exprt(expr.op(), expr.offset());
1669+
tmp.op() = simplify_index(index_exprt(expr.op(), expr.offset()));
16701670
tmp.offset() = from_integer(0, expr.offset().type());
1671-
return changed(simplify_rec(tmp));
1671+
return changed(simplify_byte_extract(tmp));
16721672
}
16731673

16741674
// extract bits of a constant
@@ -1814,19 +1814,19 @@ simplify_exprt::simplify_byte_update(const byte_update_exprt &expr)
18141814
{
18151815
const exprt &index=with.where();
18161816
exprt index_offset =
1817-
simplify_node(mult_exprt(index, from_integer(*i, index.type())));
1817+
simplify_mult(mult_exprt(index, from_integer(*i, index.type())));
18181818

18191819
// index_offset may need a typecast
18201820
if(offset.type() != index.type())
18211821
{
18221822
index_offset =
1823-
simplify_node(typecast_exprt(index_offset, offset.type()));
1823+
simplify_typecast(typecast_exprt(index_offset, offset.type()));
18241824
}
18251825

18261826
plus_exprt new_offset(offset, index_offset);
18271827
exprt new_value(with.new_value());
18281828
auto tmp = expr;
1829-
tmp.set_offset(simplify_node(std::move(new_offset)));
1829+
tmp.set_offset(simplify_plus(std::move(new_offset)));
18301830
tmp.set_value(std::move(new_value));
18311831
return changed(simplify_byte_update(tmp)); // recursive call
18321832
}

src/util/simplify_expr_array.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -184,15 +184,16 @@ simplify_exprt::simplify_index(const index_exprt &expr)
184184
return unchanged(expr);
185185

186186
// add offset to index
187-
mult_exprt offset(
188-
from_integer(*sub_size, byte_extract_expr.offset().type()), index);
187+
exprt offset = simplify_mult(mult_exprt{
188+
from_integer(*sub_size, byte_extract_expr.offset().type()), index});
189189
exprt final_offset =
190-
simplify_node(plus_exprt(byte_extract_expr.offset(), offset));
190+
simplify_plus(plus_exprt(byte_extract_expr.offset(), offset));
191191

192-
exprt result_expr(array.id(), expr.type());
193-
result_expr.add_to_operands(byte_extract_expr.op(), final_offset);
192+
auto result_expr = byte_extract_expr;
193+
result_expr.type() = expr.type();
194+
result_expr.offset() = final_offset;
194195

195-
return changed(simplify_rec(result_expr));
196+
return changed(simplify_byte_extract(result_expr));
196197
}
197198
}
198199
else if(array.id()==ID_if)

src/util/simplify_expr_boolean.cpp

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ simplify_exprt::resultt<> simplify_exprt::simplify_boolean(const exprt &expr)
4141
binary_exprt new_expr = implies_expr;
4242
new_expr.id(ID_or);
4343
new_expr.op0() = simplify_not(not_exprt(new_expr.op0()));
44-
return changed(simplify_node(new_expr));
44+
return changed(simplify_boolean(new_expr));
4545
}
4646
else if(expr.id()==ID_xor)
4747
{
@@ -207,18 +207,14 @@ simplify_exprt::resultt<> simplify_exprt::simplify_not(const not_exprt &expr)
207207
else if(op.id()==ID_exists) // !(exists: a) <-> forall: not a
208208
{
209209
auto const &op_as_exists = to_exists_expr(op);
210-
forall_exprt rewritten_op(
211-
op_as_exists.symbol(), not_exprt(op_as_exists.where()));
212-
rewritten_op.where() = simplify_node(rewritten_op.where());
213-
return std::move(rewritten_op);
210+
return forall_exprt{op_as_exists.symbol(),
211+
simplify_not(not_exprt(op_as_exists.where()))};
214212
}
215213
else if(op.id() == ID_forall) // !(forall: a) <-> exists: not a
216214
{
217215
auto const &op_as_forall = to_forall_expr(op);
218-
exists_exprt rewritten_op(
219-
op_as_forall.symbol(), not_exprt(op_as_forall.where()));
220-
rewritten_op.where() = simplify_node(rewritten_op.where());
221-
return std::move(rewritten_op);
216+
return exists_exprt{op_as_forall.symbol(),
217+
simplify_not(not_exprt(op_as_forall.where()))};
222218
}
223219

224220
return unchanged(expr);

src/util/simplify_expr_if.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -362,24 +362,24 @@ simplify_exprt::resultt<> simplify_exprt::simplify_if(const if_exprt &expr)
362362
else if(falsevalue.is_false())
363363
{
364364
// a?b:0 <-> a AND b
365-
return changed(simplify_node(and_exprt(cond, truevalue)));
365+
return changed(simplify_boolean(and_exprt(cond, truevalue)));
366366
}
367367
else if(falsevalue.is_true())
368368
{
369369
// a?b:1 <-> !a OR b
370370
return changed(
371-
simplify_node(or_exprt(simplify_not(not_exprt(cond)), truevalue)));
371+
simplify_boolean(or_exprt(simplify_not(not_exprt(cond)), truevalue)));
372372
}
373373
else if(truevalue.is_true())
374374
{
375375
// a?1:b <-> a||(!a && b) <-> a OR b
376-
return changed(simplify_node(or_exprt(cond, falsevalue)));
376+
return changed(simplify_boolean(or_exprt(cond, falsevalue)));
377377
}
378378
else if(truevalue.is_false())
379379
{
380380
// a?0:b <-> !a && b
381-
return changed(
382-
simplify_node(and_exprt(simplify_not(not_exprt(cond)), falsevalue)));
381+
return changed(simplify_boolean(
382+
and_exprt(simplify_not(not_exprt(cond)), falsevalue)));
383383
}
384384
}
385385
}

src/util/simplify_expr_int.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -569,7 +569,7 @@ simplify_exprt::simplify_minus(const minus_exprt &expr)
569569
// rewrite "a-b" to "a+(-b)"
570570
unary_minus_exprt rhs_negated(operands[1]);
571571
plus_exprt plus_expr(operands[0], simplify_unary_minus(rhs_negated));
572-
return changed(simplify_node(plus_expr));
572+
return changed(simplify_plus(plus_expr));
573573
}
574574
else if(
575575
minus_expr.type().id() == ID_pointer &&
@@ -642,10 +642,9 @@ simplify_exprt::simplify_bitwise(const multi_ary_exprt &expr)
642642
}
643643

644644
new_expr.type()=bool_typet();
645-
new_expr = simplify_node(new_expr);
645+
new_expr = simplify_boolean(new_expr);
646646

647-
new_expr = typecast_exprt(new_expr, expr.type());
648-
return changed(simplify_node(new_expr));
647+
return changed(simplify_typecast(typecast_exprt(new_expr, expr.type())));
649648
}
650649
}
651650

src/util/simplify_expr_pointer.cpp

Lines changed: 12 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ simplify_exprt::simplify_pointer_offset(const unary_exprt &expr)
280280
auto new_expr = expr;
281281
new_expr.op() = op;
282282

283-
return changed(simplify_node(new_expr)); // recursive call
283+
return changed(simplify_pointer_offset(new_expr)); // recursive call
284284
}
285285
else if(op_type.id()==ID_signedbv ||
286286
op_type.id()==ID_unsignedbv)
@@ -290,8 +290,7 @@ simplify_exprt::simplify_pointer_offset(const unary_exprt &expr)
290290
if(op.is_constant())
291291
{
292292
// (T *)0x1234 -> 0x1234
293-
exprt tmp = typecast_exprt(op, expr.type());
294-
return changed(simplify_node(tmp));
293+
return changed(simplify_typecast(typecast_exprt{op, expr.type()}));
295294
}
296295
else
297296
{
@@ -339,7 +338,7 @@ simplify_exprt::simplify_pointer_offset(const unary_exprt &expr)
339338
{
340339
exprt tmp=op;
341340
if(tmp.type()!=expr.type())
342-
tmp = simplify_node(typecast_exprt(tmp, expr.type()));
341+
tmp = simplify_typecast(typecast_exprt(tmp, expr.type()));
343342

344343
int_expr.push_back(tmp);
345344
}
@@ -358,29 +357,23 @@ simplify_exprt::simplify_pointer_offset(const unary_exprt &expr)
358357
return unchanged(expr);
359358

360359
// this might change the type of the pointer!
361-
exprt pointer_offset_expr = simplify_node(pointer_offset(ptr_expr.front()));
360+
exprt pointer_offset_expr =
361+
simplify_pointer_offset(to_unary_expr(pointer_offset(ptr_expr.front())));
362362

363363
exprt sum;
364364

365365
if(int_expr.size()==1)
366366
sum=int_expr.front();
367367
else
368-
{
369-
sum=exprt(ID_plus, expr.type());
370-
sum.operands()=int_expr;
371-
}
372-
373-
sum = simplify_node(sum);
368+
sum = simplify_plus(plus_exprt{int_expr, expr.type()});
374369

375370
exprt size_expr = from_integer(*element_size, expr.type());
376371

377-
exprt product = mult_exprt(sum, size_expr);
378-
379-
product = simplify_node(product);
372+
exprt product = simplify_mult(mult_exprt{sum, size_expr});
380373

381374
auto new_expr = plus_exprt(pointer_offset_expr, product);
382375

383-
return changed(simplify_node(new_expr));
376+
return changed(simplify_plus(new_expr));
384377
}
385378
else if(ptr.id()==ID_constant)
386379
{
@@ -389,8 +382,7 @@ simplify_exprt::simplify_pointer_offset(const unary_exprt &expr)
389382
if(c_ptr.get_value()==ID_NULL ||
390383
c_ptr.value_is_zero_string())
391384
{
392-
auto new_expr = from_integer(0, expr.type());
393-
return changed(simplify_node(new_expr));
385+
return from_integer(0, expr.type());
394386
}
395387
else
396388
{
@@ -407,9 +399,7 @@ simplify_exprt::simplify_pointer_offset(const unary_exprt &expr)
407399
*pointer_offset_bits(ptr.type(), ns) - config.bv_encoding.object_bits;
408400
number%=power(2, offset_bits);
409401

410-
auto new_expr = from_integer(number, expr.type());
411-
412-
return changed(simplify_node(new_expr));
402+
return from_integer(number, expr.type());
413403
}
414404
}
415405

@@ -686,10 +676,7 @@ simplify_exprt::simplify_object_size(const unary_exprt &expr)
686676
exprt size = size_opt.value();
687677

688678
if(size.type() != expr_type)
689-
{
690-
size = typecast_exprt(size, expr_type);
691-
size = simplify_node(size);
692-
}
679+
size = simplify_typecast(typecast_exprt(size, expr_type));
693680

694681
return size;
695682
}
@@ -715,5 +702,5 @@ simplify_exprt::simplify_good_pointer(const unary_exprt &expr)
715702
exprt def = good_pointer_def(expr.op(), ns);
716703

717704
// recursive call
718-
return changed(simplify_node(def));
705+
return changed(simplify_rec(def));
719706
}

src/util/simplify_expr_struct.cpp

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,8 @@ simplify_exprt::simplify_member(const member_exprt &expr)
4747
DATA_INVARIANT(
4848
op2.type() == expr.type(),
4949
"member expression type must match component type");
50-
exprt tmp;
51-
tmp.swap(op2);
5250

53-
// do this recursively
54-
return changed(simplify_rec(tmp));
51+
return op2;
5552
}
5653
else // something else, get rid of it
5754
new_operands.resize(new_operands.size() - 2);
@@ -71,10 +68,7 @@ simplify_exprt::simplify_member(const member_exprt &expr)
7168
if(with_expr.where().get(ID_component_name)==component_name)
7269
{
7370
// WITH(s, .m, v).m -> v
74-
auto tmp = with_expr.new_value();
75-
76-
// do this recursively
77-
return changed(simplify_rec(tmp));
71+
return with_expr.new_value();
7872
}
7973
}
8074
}
@@ -93,10 +87,7 @@ simplify_exprt::simplify_member(const member_exprt &expr)
9387
if(designator.front().get(ID_component_name)==component_name)
9488
{
9589
// UPDATE(s, .m, v).m -> v
96-
exprt tmp=update_expr.new_value();
97-
98-
// do this recursively
99-
return changed(simplify_rec(tmp));
90+
return update_expr.new_value();
10091
}
10192
// the following optimization only works on structs,
10293
// and not on unions
@@ -107,7 +98,7 @@ simplify_exprt::simplify_member(const member_exprt &expr)
10798
new_expr.struct_op() = update_expr.old();
10899

109100
// do this recursively
110-
return changed(simplify_rec(new_expr));
101+
return changed(simplify_member(new_expr));
111102
}
112103
}
113104
}
@@ -158,12 +149,12 @@ simplify_exprt::simplify_member(const member_exprt &expr)
158149
const exprt &struct_offset = byte_extract_expr.offset();
159150
exprt member_offset = from_integer(*offset_int, struct_offset.type());
160151
exprt final_offset =
161-
simplify_node(plus_exprt(struct_offset, member_offset));
152+
simplify_plus(plus_exprt(struct_offset, member_offset));
162153

163154
byte_extract_exprt result(
164155
op.id(), byte_extract_expr.op(), final_offset, expr.type());
165156

166-
return changed(simplify_rec(result)); // recursive call
157+
return changed(simplify_byte_extract(result)); // recursive call
167158
}
168159
else if(op_type.id() == ID_union)
169160
{

0 commit comments

Comments
 (0)