Skip to content

Commit cd70727

Browse files
author
Daniel Kroening
authored
Merge pull request #4830 from diffblue/simplify_sig
simplifier cleanup
2 parents ab071ae + 2d23e60 commit cd70727

File tree

2 files changed

+89
-72
lines changed

2 files changed

+89
-72
lines changed

src/util/simplify_expr.cpp

Lines changed: 82 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -63,21 +63,17 @@ struct simplify_expr_cachet
6363
simplify_expr_cachet simplify_expr_cache;
6464
#endif
6565

66-
bool simplify_exprt::simplify_abs(exprt &expr)
66+
simplify_exprt::resultt<> simplify_exprt::simplify_abs(const abs_exprt &expr)
6767
{
68-
if(expr.operands().size()!=1)
69-
return true;
70-
71-
if(to_unary_expr(expr).op().is_constant())
68+
if(expr.op().is_constant())
7269
{
7370
const typet &type = to_unary_expr(expr).op().type();
7471

7572
if(type.id()==ID_floatbv)
7673
{
7774
ieee_floatt value(to_constant_expr(to_unary_expr(expr).op()));
7875
value.set_sign(false);
79-
expr=value.to_expr();
80-
return false;
76+
return value.to_expr();
8177
}
8278
else if(type.id()==ID_signedbv ||
8379
type.id()==ID_unsignedbv)
@@ -87,20 +83,18 @@ bool simplify_exprt::simplify_abs(exprt &expr)
8783
{
8884
if(*value >= 0)
8985
{
90-
expr = to_unary_expr(expr).op();
91-
return false;
86+
return to_unary_expr(expr).op();
9287
}
9388
else
9489
{
9590
value->negate();
96-
expr = from_integer(*value, type);
97-
return false;
91+
return from_integer(*value, type);
9892
}
9993
}
10094
}
10195
}
10296

103-
return true;
97+
return unchanged(expr);
10498
}
10599

106100
bool simplify_exprt::simplify_sign(exprt &expr)
@@ -133,7 +127,8 @@ bool simplify_exprt::simplify_sign(exprt &expr)
133127
return true;
134128
}
135129

136-
bool simplify_exprt::simplify_popcount(popcount_exprt &expr)
130+
simplify_exprt::resultt<>
131+
simplify_exprt::simplify_popcount(const popcount_exprt &expr)
137132
{
138133
const exprt &op = expr.op();
139134

@@ -151,41 +146,35 @@ bool simplify_exprt::simplify_popcount(popcount_exprt &expr)
151146
if(get_bvrep_bit(value, width, i))
152147
result++;
153148

154-
auto result_expr = from_integer(result, expr.type());
155-
expr.swap(result_expr);
156-
157-
return false;
149+
return from_integer(result, expr.type());
158150
}
159151
}
160152

161-
return true;
153+
return unchanged(expr);
162154
}
163155

164-
bool simplify_exprt::simplify_function_application(exprt &expr)
156+
simplify_exprt::resultt<> simplify_exprt::simplify_function_application(
157+
const function_application_exprt &expr)
165158
{
166-
const function_application_exprt &function_app =
167-
to_function_application_expr(expr);
168-
169-
if(function_app.function().id() != ID_symbol)
170-
return true;
159+
if(expr.function().id() != ID_symbol)
160+
return unchanged(expr);
171161

172-
const irep_idt func_id =
173-
to_symbol_expr(function_app.function()).get_identifier();
162+
const irep_idt &func_id = to_symbol_expr(expr.function()).get_identifier();
174163

175164
// Starts-with is used for .equals.
176165
if(func_id == ID_cprover_string_startswith_func)
177166
{
178167
// We want to get both arguments of any starts-with comparison, and
179168
// trace them back to the actual string instance. All variables on the
180169
// way must be constant for us to be sure this will work.
181-
auto &first_argument = to_string_expr(function_app.arguments().at(0));
182-
auto &second_argument = to_string_expr(function_app.arguments().at(1));
170+
auto &first_argument = to_string_expr(expr.arguments().at(0));
171+
auto &second_argument = to_string_expr(expr.arguments().at(1));
183172

184173
const auto first_value_opt = try_get_string_data_array(first_argument, ns);
185174

186175
if(!first_value_opt)
187176
{
188-
return true;
177+
return unchanged(expr);
189178
}
190179

191180
const array_exprt &first_value = first_value_opt->get();
@@ -195,17 +184,17 @@ bool simplify_exprt::simplify_function_application(exprt &expr)
195184

196185
if(!second_value_opt)
197186
{
198-
return true;
187+
return unchanged(expr);
199188
}
200189

201190
const array_exprt &second_value = second_value_opt->get();
202191

203192
mp_integer offset_int = 0;
204-
if(function_app.arguments().size() == 3)
193+
if(expr.arguments().size() == 3)
205194
{
206-
auto &offset = function_app.arguments()[2];
195+
auto &offset = expr.arguments()[2];
207196
if(offset.id() != ID_constant)
208-
return true;
197+
return unchanged(expr);
209198
offset_int = numeric_cast_v<mp_integer>(to_constant_expr(offset));
210199
}
211200

@@ -232,26 +221,25 @@ bool simplify_exprt::simplify_function_application(exprt &expr)
232221
++second_it;
233222
}
234223
}
235-
expr = from_integer(is_prefix ? 1 : 0, expr.type());
236-
return false;
224+
225+
return from_integer(is_prefix ? 1 : 0, expr.type());
237226
}
238227
else if(func_id == ID_cprover_string_char_at_func)
239228
{
240-
if(function_app.arguments().at(1).id() != ID_constant)
229+
if(expr.arguments().at(1).id() != ID_constant)
241230
{
242-
return true;
231+
return unchanged(expr);
243232
}
244233

245-
const auto &index = to_constant_expr(function_app.arguments().at(1));
234+
const auto &index = to_constant_expr(expr.arguments().at(1));
246235

247-
const refined_string_exprt &s =
248-
to_string_expr(function_app.arguments().at(0));
236+
const refined_string_exprt &s = to_string_expr(expr.arguments().at(0));
249237

250238
const auto char_seq_opt = try_get_string_data_array(s, ns);
251239

252240
if(!char_seq_opt)
253241
{
254-
return true;
242+
return unchanged(expr);
255243
}
256244

257245
const array_exprt &char_seq = char_seq_opt->get();
@@ -260,22 +248,20 @@ bool simplify_exprt::simplify_function_application(exprt &expr)
260248

261249
if(!i_opt || *i_opt >= char_seq.operands().size())
262250
{
263-
return true;
251+
return unchanged(expr);
264252
}
265253

266254
const auto &c = to_constant_expr(char_seq.operands().at(*i_opt));
267255

268256
if(c.type() != expr.type())
269257
{
270-
return true;
258+
return unchanged(expr);
271259
}
272260

273-
expr = c;
274-
275-
return false;
261+
return c;
276262
}
277263

278-
return true;
264+
return unchanged(expr);
279265
}
280266

281267
simplify_exprt::resultt<>
@@ -862,38 +848,39 @@ simplify_exprt::simplify_typecast(const typecast_exprt &expr)
862848
return unchanged(expr);
863849
}
864850

865-
bool simplify_exprt::simplify_dereference(exprt &expr)
851+
simplify_exprt::resultt<>
852+
simplify_exprt::simplify_dereference(const dereference_exprt &expr)
866853
{
867-
const exprt &pointer=to_dereference_expr(expr).pointer();
854+
const exprt &pointer = expr.pointer();
868855

869856
if(pointer.type().id()!=ID_pointer)
870-
return true;
857+
return unchanged(expr);
871858

872859
if(pointer.id()==ID_if && pointer.operands().size()==3)
873860
{
874861
const if_exprt &if_expr=to_if_expr(pointer);
875862

876-
exprt tmp_op1=expr;
877-
tmp_op1.op0()=if_expr.true_case();
878-
simplify_dereference(tmp_op1);
879-
exprt tmp_op2=expr;
880-
tmp_op2.op0()=if_expr.false_case();
881-
simplify_dereference(tmp_op2);
863+
auto tmp_op1 = expr;
864+
tmp_op1.op() = if_expr.true_case();
865+
exprt tmp_op1_result = simplify_dereference(tmp_op1);
882866

883-
expr=if_exprt(if_expr.cond(), tmp_op1, tmp_op2);
867+
auto tmp_op2 = expr;
868+
tmp_op2.op() = if_expr.false_case();
869+
exprt tmp_op2_result = simplify_dereference(tmp_op2);
884870

885-
simplify_if(to_if_expr(expr));
871+
if_exprt tmp{if_expr.cond(), tmp_op1_result, tmp_op2_result};
886872

887-
return false;
873+
simplify_if(tmp);
874+
875+
return tmp;
888876
}
889877

890878
if(pointer.id()==ID_address_of)
891879
{
892880
exprt tmp=to_address_of_expr(pointer).object();
893881
// one address_of is gone, try again
894882
simplify_rec(tmp);
895-
expr.swap(tmp);
896-
return false;
883+
return tmp;
897884
}
898885
// rewrite *(&a[0] + x) to a[x]
899886
else if(pointer.id()==ID_plus &&
@@ -912,13 +899,12 @@ bool simplify_exprt::simplify_dereference(exprt &expr)
912899
pointer_offset_sum(old.index(), pointer.op1()),
913900
old.array().type().subtype());
914901
simplify_rec(idx);
915-
expr.swap(idx);
916-
return false;
902+
return idx;
917903
}
918904
}
919905
}
920906

921-
return true;
907+
return unchanged(expr);
922908
}
923909

924910
bool simplify_exprt::simplify_if_implies(
@@ -2505,7 +2491,14 @@ bool simplify_exprt::simplify_node(exprt &expr)
25052491
expr.id()==ID_and)
25062492
no_change = simplify_boolean(expr) && no_change;
25072493
else if(expr.id()==ID_dereference)
2508-
no_change = simplify_dereference(expr) && no_change;
2494+
{
2495+
auto r = simplify_dereference(to_dereference_expr(expr));
2496+
if(r.has_changed())
2497+
{
2498+
no_change = false;
2499+
expr = r.expr;
2500+
}
2501+
}
25092502
else if(expr.id()==ID_address_of)
25102503
no_change = simplify_address_of(expr) && no_change;
25112504
else if(expr.id()==ID_pointer_offset)
@@ -2528,13 +2521,34 @@ bool simplify_exprt::simplify_node(exprt &expr)
25282521
else if(expr.id()==ID_isnormal)
25292522
no_change = simplify_isnormal(expr) && no_change;
25302523
else if(expr.id()==ID_abs)
2531-
no_change = simplify_abs(expr) && no_change;
2524+
{
2525+
auto r = simplify_abs(to_abs_expr(expr));
2526+
if(r.has_changed())
2527+
{
2528+
no_change = false;
2529+
expr = r.expr;
2530+
}
2531+
}
25322532
else if(expr.id()==ID_sign)
25332533
no_change = simplify_sign(expr) && no_change;
25342534
else if(expr.id() == ID_popcount)
2535-
no_change = simplify_popcount(to_popcount_expr(expr)) && no_change;
2535+
{
2536+
auto r = simplify_popcount(to_popcount_expr(expr));
2537+
if(r.has_changed())
2538+
{
2539+
no_change = false;
2540+
expr = r.expr;
2541+
}
2542+
}
25362543
else if(expr.id() == ID_function_application)
2537-
no_change = simplify_function_application(expr) && no_change;
2544+
{
2545+
auto r = simplify_function_application(to_function_application_expr(expr));
2546+
if(r.has_changed())
2547+
{
2548+
no_change = false;
2549+
expr = r.expr;
2550+
}
2551+
}
25382552
else if(expr.id() == ID_complex_real || expr.id() == ID_complex_imag)
25392553
no_change = simplify_complex(expr) && no_change;
25402554

src/util/simplify_expr_class.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,15 @@ Author: Daniel Kroening, [email protected]
2525
#include "replace_expr.h"
2626
#endif
2727

28+
class abs_exprt;
2829
class array_exprt;
2930
class bswap_exprt;
3031
class byte_extract_exprt;
3132
class byte_update_exprt;
33+
class dereference_exprt;
3234
class exprt;
3335
class extractbits_exprt;
36+
class function_application_exprt;
3437
class if_exprt;
3538
class index_exprt;
3639
class member_exprt;
@@ -152,21 +155,21 @@ class simplify_exprt
152155
bool simplify_object(exprt &expr);
153156
bool simplify_unary_minus(exprt &expr);
154157
bool simplify_unary_plus(exprt &expr);
155-
bool simplify_dereference(exprt &expr);
158+
resultt<> simplify_dereference(const dereference_exprt &);
156159
bool simplify_address_of(exprt &expr);
157160
bool simplify_pointer_offset(exprt &expr);
158161
bool simplify_bswap(bswap_exprt &expr);
159162
bool simplify_isinf(exprt &expr);
160163
bool simplify_isnan(exprt &expr);
161164
bool simplify_isnormal(exprt &expr);
162-
bool simplify_abs(exprt &expr);
165+
resultt<> simplify_abs(const abs_exprt &);
163166
bool simplify_sign(exprt &expr);
164-
bool simplify_popcount(popcount_exprt &expr);
167+
resultt<> simplify_popcount(const popcount_exprt &);
165168
bool simplify_complex(exprt &expr);
166169

167170
/// Attempt to simplify mathematical function applications if we have
168171
/// enough information to do so. Currently focused on constant comparisons.
169-
bool simplify_function_application(exprt &expr);
172+
resultt<> simplify_function_application(const function_application_exprt &);
170173

171174
// auxiliary
172175
bool simplify_if_implies(

0 commit comments

Comments
 (0)