Skip to content

Commit 2d88418

Browse files
committed
bv_pointerst: make all members return (optional) bvt
Instead of having in-out non-const bvt references, return bvt by value and rely on copy elision for performance. This simplifies the code in that it avoids creating (and sometimes unnecessarily resizing) objects that are then to be populated by a function. For convert_address_of_rec use optionalt<bvt> to remove the true/false error reporting.
1 parent 2006bef commit 2d88418

File tree

2 files changed

+90
-85
lines changed

2 files changed

+90
-85
lines changed

src/solvers/flattening/bv_pointers.cpp

Lines changed: 72 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,7 @@ literalt bv_pointerst::convert_rest(const exprt &expr)
129129
{
130130
const pointer_typet &type = to_pointer_type(operands[0].type());
131131

132-
bvt invalid_bv;
133-
encode(pointer_logic.get_invalid_object(), type, invalid_bv);
132+
bvt invalid_bv = encode(pointer_logic.get_invalid_object(), type);
134133

135134
const std::size_t object_bits =
136135
bv_pointers_width.get_object_width(type);
@@ -195,25 +194,20 @@ bv_pointerst::bv_pointerst(
195194
{
196195
}
197196

198-
bool bv_pointerst::convert_address_of_rec(
199-
const exprt &expr,
200-
bvt &bv)
197+
optionalt<bvt> bv_pointerst::convert_address_of_rec(const exprt &expr)
201198
{
202199
if(expr.id()==ID_symbol)
203200
{
204-
add_addr(expr, bv);
205-
return false;
201+
return add_addr(expr);
206202
}
207203
else if(expr.id()==ID_label)
208204
{
209-
add_addr(expr, bv);
210-
return false;
205+
return add_addr(expr);
211206
}
212207
else if(expr.id() == ID_null_object)
213208
{
214209
pointer_typet pt = pointer_type(expr.type());
215-
encode(pointer_logic.get_null_object(), pt, bv);
216-
return false;
210+
return encode(pointer_logic.get_null_object(), pt);
217211
}
218212
else if(expr.id()==ID_index)
219213
{
@@ -225,6 +219,8 @@ bool bv_pointerst::convert_address_of_rec(
225219
pointer_typet type = pointer_type(expr.type());
226220
const std::size_t bits = boolbv_width(type);
227221

222+
bvt bv;
223+
228224
// recursive call
229225
if(array_type.id()==ID_pointer)
230226
{
@@ -235,8 +231,10 @@ bool bv_pointerst::convert_address_of_rec(
235231
else if(array_type.id()==ID_array ||
236232
array_type.id()==ID_string_constant)
237233
{
238-
if(convert_address_of_rec(array, bv))
239-
return true;
234+
auto bv_opt = convert_address_of_rec(array);
235+
if(!bv_opt.has_value())
236+
return {};
237+
bv = std::move(*bv_opt);
240238
CHECK_RETURN(bv.size()==bits);
241239
}
242240
else
@@ -246,26 +244,28 @@ bool bv_pointerst::convert_address_of_rec(
246244
auto size = pointer_offset_size(array_type.subtype(), ns);
247245
CHECK_RETURN(size.has_value() && *size >= 0);
248246

249-
offset_arithmetic(type, bv, *size, index);
247+
bv = offset_arithmetic(type, bv, *size, index);
250248
CHECK_RETURN(bv.size()==bits);
251-
return false;
249+
250+
return std::move(bv);
252251
}
253252
else if(expr.id()==ID_byte_extract_little_endian ||
254253
expr.id()==ID_byte_extract_big_endian)
255254
{
256255
const auto &byte_extract_expr=to_byte_extract_expr(expr);
257256

258257
// recursive call
259-
if(convert_address_of_rec(byte_extract_expr.op(), bv))
260-
return true;
258+
auto bv_opt = convert_address_of_rec(byte_extract_expr.op());
259+
if(!bv_opt.has_value())
260+
return {};
261261

262262
pointer_typet type = pointer_type(expr.type());
263263
const std::size_t bits = boolbv_width(type);
264-
CHECK_RETURN(bv.size()==bits);
264+
CHECK_RETURN(bv_opt->size() == bits);
265265

266-
offset_arithmetic(type, bv, 1, byte_extract_expr.offset());
266+
bvt bv = offset_arithmetic(type, *bv_opt, 1, byte_extract_expr.offset());
267267
CHECK_RETURN(bv.size()==bits);
268-
return false;
268+
return std::move(bv);
269269
}
270270
else if(expr.id()==ID_member)
271271
{
@@ -274,9 +274,11 @@ bool bv_pointerst::convert_address_of_rec(
274274
const typet &struct_op_type=ns.follow(struct_op.type());
275275

276276
// recursive call
277-
if(convert_address_of_rec(struct_op, bv))
278-
return true;
277+
auto bv_opt = convert_address_of_rec(struct_op);
278+
if(!bv_opt.has_value())
279+
return {};
279280

281+
bvt bv = std::move(*bv_opt);
280282
if(struct_op_type.id()==ID_struct)
281283
{
282284
auto offset = member_offset(
@@ -285,7 +287,7 @@ bool bv_pointerst::convert_address_of_rec(
285287

286288
// add offset
287289
pointer_typet type = pointer_type(expr.type());
288-
offset_arithmetic(type, bv, *offset);
290+
bv = offset_arithmetic(type, bv, *offset);
289291
}
290292
else
291293
{
@@ -295,14 +297,13 @@ bool bv_pointerst::convert_address_of_rec(
295297
// nothing to do, all members have offset 0
296298
}
297299

298-
return false;
300+
return std::move(bv);
299301
}
300302
else if(expr.id()==ID_constant ||
301303
expr.id()==ID_string_constant ||
302304
expr.id()==ID_array)
303305
{ // constant
304-
add_addr(expr, bv);
305-
return false;
306+
return add_addr(expr);
306307
}
307308
else if(expr.id()==ID_if)
308309
{
@@ -312,18 +313,18 @@ bool bv_pointerst::convert_address_of_rec(
312313

313314
bvt bv1, bv2;
314315

315-
if(convert_address_of_rec(ifex.true_case(), bv1))
316-
return true;
317-
318-
if(convert_address_of_rec(ifex.false_case(), bv2))
319-
return true;
316+
auto bv1_opt = convert_address_of_rec(ifex.true_case());
317+
if(!bv1_opt.has_value())
318+
return {};
320319

321-
bv=bv_utils.select(cond, bv1, bv2);
320+
auto bv2_opt = convert_address_of_rec(ifex.false_case());
321+
if(!bv2_opt.has_value())
322+
return {};
322323

323-
return false;
324+
return bv_utils.select(cond, *bv1_opt, *bv2_opt);
324325
}
325326

326-
return true;
327+
return {};
327328
}
328329

329330
bvt bv_pointerst::convert_pointer_type(const exprt &expr)
@@ -385,34 +386,29 @@ bvt bv_pointerst::convert_pointer_type(const exprt &expr)
385386
{
386387
const address_of_exprt &address_of_expr = to_address_of_expr(expr);
387388

388-
bvt bv;
389-
bv.resize(bits);
390-
391-
if(convert_address_of_rec(address_of_expr.op(), bv))
389+
auto bv_opt = convert_address_of_rec(address_of_expr.op());
390+
if(!bv_opt.has_value())
392391
{
392+
bvt bv;
393+
bv.resize(bits);
393394
conversion_failed(address_of_expr, bv);
394395
return bv;
395396
}
396397

397-
CHECK_RETURN(bv.size()==bits);
398-
return bv;
398+
CHECK_RETURN(bv_opt->size() == bits);
399+
return *bv_opt;
399400
}
400401
else if(expr.id()==ID_constant)
401402
{
402403
irep_idt value=to_constant_expr(expr).get_value();
403404

404-
bvt bv;
405-
bv.resize(bits);
406-
407405
if(value==ID_NULL)
408-
encode(pointer_logic.get_null_object(), type, bv);
406+
return encode(pointer_logic.get_null_object(), type);
409407
else
410408
{
411409
mp_integer i = bvrep2integer(value, bits, false);
412-
bv=bv_utils.build_constant(i, bits);
410+
return bv_utils.build_constant(i, bits);
413411
}
414-
415-
return bv;
416412
}
417413
else if(expr.id()==ID_plus)
418414
{
@@ -486,9 +482,7 @@ bvt bv_pointerst::convert_pointer_type(const exprt &expr)
486482
sum=bv_utils.add(sum, op);
487483
}
488484

489-
offset_arithmetic(type, bv, size, sum);
490-
491-
return bv;
485+
return offset_arithmetic(type, bv, size, sum);
492486
}
493487
else if(expr.id()==ID_minus)
494488
{
@@ -511,7 +505,7 @@ bvt bv_pointerst::convert_pointer_type(const exprt &expr)
511505

512506
const unary_minus_exprt neg_op1(minus_expr.rhs());
513507

514-
bvt bv = convert_bv(minus_expr.lhs());
508+
const bvt &bv = convert_bv(minus_expr.lhs());
515509

516510
typet pointer_sub_type = minus_expr.rhs().type().subtype();
517511
mp_integer element_size;
@@ -529,9 +523,7 @@ bvt bv_pointerst::convert_pointer_type(const exprt &expr)
529523
element_size = *element_size_opt;
530524
}
531525

532-
offset_arithmetic(type, bv, element_size, neg_op1);
533-
534-
return bv;
526+
return offset_arithmetic(type, bv, element_size, neg_op1);
535527
}
536528
else if(expr.id()==ID_byte_extract_little_endian ||
537529
expr.id()==ID_byte_extract_big_endian)
@@ -743,26 +735,28 @@ exprt bv_pointerst::bv_get_rec(
743735
return std::move(result);
744736
}
745737

746-
void bv_pointerst::encode(std::size_t addr, const pointer_typet &type, bvt &bv)
747-
const
738+
bvt bv_pointerst::encode(std::size_t addr, const pointer_typet &type) const
748739
{
749740
const std::size_t offset_bits = bv_pointers_width.get_offset_width(type);
750741
const std::size_t object_bits = bv_pointers_width.get_object_width(type);
751742

752-
bv.resize(boolbv_width(type));
743+
bvt bv;
744+
bv.reserve(boolbv_width(type));
753745

754746
// set offset to zero
755747
for(std::size_t i=0; i<offset_bits; i++)
756-
bv[i]=const_literal(false);
748+
bv.push_back(const_literal(false));
757749

758750
// set variable part
759751
for(std::size_t i=0; i<object_bits; i++)
760-
bv[offset_bits+i]=const_literal((addr&(std::size_t(1)<<i))!=0);
752+
bv.push_back(const_literal((addr & (std::size_t(1) << i)) != 0));
753+
754+
return bv;
761755
}
762756

763-
void bv_pointerst::offset_arithmetic(
757+
bvt bv_pointerst::offset_arithmetic(
764758
const pointer_typet &type,
765-
bvt &bv,
759+
const bvt &bv,
766760
const mp_integer &x)
767761
{
768762
const std::size_t offset_bits = bv_pointers_width.get_offset_width(type);
@@ -775,13 +769,16 @@ void bv_pointerst::offset_arithmetic(
775769
bvt tmp=bv_utils.add(bv1, bv2);
776770

777771
// copy offset bits
772+
bvt result = bv;
778773
for(std::size_t i=0; i<offset_bits; i++)
779-
bv[i]=tmp[i];
774+
result[i] = tmp[i];
775+
776+
return result;
780777
}
781778

782-
void bv_pointerst::offset_arithmetic(
779+
bvt bv_pointerst::offset_arithmetic(
783780
const pointer_typet &type,
784-
bvt &bv,
781+
const bvt &bv,
785782
const mp_integer &factor,
786783
const exprt &index)
787784
{
@@ -794,12 +791,12 @@ void bv_pointerst::offset_arithmetic(
794791
const std::size_t offset_bits = bv_pointers_width.get_offset_width(type);
795792
bv_index=bv_utils.extension(bv_index, offset_bits, rep);
796793

797-
offset_arithmetic(type, bv, factor, bv_index);
794+
return offset_arithmetic(type, bv, factor, bv_index);
798795
}
799796

800-
void bv_pointerst::offset_arithmetic(
797+
bvt bv_pointerst::offset_arithmetic(
801798
const pointer_typet &type,
802-
bvt &bv,
799+
const bvt &bv,
803800
const mp_integer &factor,
804801
const bvt &index)
805802
{
@@ -818,12 +815,15 @@ void bv_pointerst::offset_arithmetic(
818815
bvt bv_tmp=bv_utils.add(bv, bv_index);
819816

820817
// copy lower parts of result
818+
bvt result = bv;
821819
const std::size_t offset_bits = bv_pointers_width.get_offset_width(type);
822820
for(std::size_t i=0; i<offset_bits; i++)
823-
bv[i]=bv_tmp[i];
821+
result[i] = bv_tmp[i];
822+
823+
return result;
824824
}
825825

826-
void bv_pointerst::add_addr(const exprt &expr, bvt &bv)
826+
bvt bv_pointerst::add_addr(const exprt &expr)
827827
{
828828
std::size_t a=pointer_logic.add_object(expr);
829829

@@ -838,7 +838,7 @@ void bv_pointerst::add_addr(const exprt &expr, bvt &bv)
838838
"); " +
839839
"use the `--object-bits n` option to increase the maximum number");
840840

841-
encode(a, type, bv);
841+
return encode(a, type);
842842
}
843843

844844
void bv_pointerst::do_postponed(
@@ -859,9 +859,8 @@ void bv_pointerst::do_postponed(
859859
bool is_dynamic=pointer_logic.is_dynamic_object(expr);
860860

861861
// only compare object part
862-
bvt bv;
863862
pointer_typet pt = pointer_type(expr.type());
864-
encode(number, pt, bv);
863+
bvt bv = encode(number, pt);
865864

866865
bv.erase(bv.begin(), bv.begin()+offset_bits);
867866

@@ -904,9 +903,8 @@ void bv_pointerst::do_postponed(
904903
size_expr.value(), postponed.expr.type());
905904

906905
// only compare object part
907-
bvt bv;
908906
pointer_typet pt = pointer_type(expr.type());
909-
encode(number, pt, bv);
907+
bvt bv = encode(number, pt);
910908

911909
bv.erase(bv.begin(), bv.begin()+offset_bits);
912910

0 commit comments

Comments
 (0)