Skip to content

Commit 4b31aee

Browse files
author
Enrico Steffinlongo
authored
Merge pull request #7887 from esteffin/esteffin/duplicate-per-byte-improvements
Improvements to duplicate_per_byte to simplify the input value
2 parents 1d2117b + 1756460 commit 4b31aee

File tree

3 files changed

+112
-41
lines changed

3 files changed

+112
-41
lines changed

src/util/expr_initializer.cpp

+21-11
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ Author: Daniel Kroening, [email protected]
1818
#include "config.h"
1919
#include "magic.h"
2020
#include "namespace.h" // IWYU pragma: keep
21+
#include "simplify_expr.h"
2122
#include "std_code.h"
2223
#include "symbol_table.h"
2324

@@ -68,7 +69,7 @@ optionalt<exprt> expr_initializert::expr_initializer_rec(
6869
else if(init_expr.is_zero())
6970
result = from_integer(0, type);
7071
else
71-
result = duplicate_per_byte(init_expr, type);
72+
result = duplicate_per_byte(init_expr, type, ns);
7273

7374
result.add_source_location()=source_location;
7475
return result;
@@ -82,7 +83,7 @@ optionalt<exprt> expr_initializert::expr_initializer_rec(
8283
else if(init_expr.is_zero())
8384
result = constant_exprt(ID_0, type);
8485
else
85-
result = duplicate_per_byte(init_expr, type);
86+
result = duplicate_per_byte(init_expr, type, ns);
8687

8788
result.add_source_location()=source_location;
8889
return result;
@@ -101,7 +102,7 @@ optionalt<exprt> expr_initializert::expr_initializer_rec(
101102
result = constant_exprt(value, type);
102103
}
103104
else
104-
result = duplicate_per_byte(init_expr, type);
105+
result = duplicate_per_byte(init_expr, type, ns);
105106

106107
result.add_source_location()=source_location;
107108
return result;
@@ -121,7 +122,7 @@ optionalt<exprt> expr_initializert::expr_initializer_rec(
121122
result = complex_exprt(*sub_zero, *sub_zero, to_complex_type(type));
122123
}
123124
else
124-
result = duplicate_per_byte(init_expr, type);
125+
result = duplicate_per_byte(init_expr, type, ns);
125126

126127
result.add_source_location()=source_location;
127128
return result;
@@ -289,7 +290,7 @@ optionalt<exprt> expr_initializert::expr_initializer_rec(
289290
else if(init_expr.is_zero())
290291
result = constant_exprt(irep_idt(), type);
291292
else
292-
result = duplicate_per_byte(init_expr, type);
293+
result = duplicate_per_byte(init_expr, type, ns);
293294

294295
result.add_source_location()=source_location;
295296
return result;
@@ -373,10 +374,14 @@ static exprt cast_or_reinterpret(const exprt &expr, const typet &out_type)
373374
/// output type.
374375
/// \param init_byte_expr The initialization expression
375376
/// \param output_type The output type
377+
/// \param ns Namespace to perform type symbol/tag lookups
376378
/// \return The built expression
377379
/// \note `init_byte_expr` must be a boolean or a bitvector and must be of at
378380
/// most `size <= config.ansi_c.char_width`
379-
exprt duplicate_per_byte(const exprt &init_byte_expr, const typet &output_type)
381+
exprt duplicate_per_byte(
382+
const exprt &init_byte_expr,
383+
const typet &output_type,
384+
const namespacet &ns)
380385
{
381386
const auto init_type_as_bitvector =
382387
type_try_dynamic_cast<bitvector_typet>(init_byte_expr.type());
@@ -385,20 +390,25 @@ exprt duplicate_per_byte(const exprt &init_byte_expr, const typet &output_type)
385390
(init_type_as_bitvector &&
386391
init_type_as_bitvector->get_width() <= config.ansi_c.char_width) ||
387392
init_byte_expr.type().id() == ID_bool);
393+
// Simplify init_expr to enable faster duplication when simplifiable to a
394+
// constant expr
395+
const auto simplified_init_expr = simplify_expr(init_byte_expr, ns);
388396
if(const auto output_bv = type_try_dynamic_cast<bitvector_typet>(output_type))
389397
{
390398
const auto out_width = output_bv->get_width();
391-
// Replicate `init_byte_expr` enough times until it completely fills
399+
// Replicate `simplified_init_expr` enough times until it completely fills
392400
// `output_type`.
393401

394402
// We've got a constant. So, precompute the value of the constant.
395-
if(init_byte_expr.is_constant())
403+
if(simplified_init_expr.is_constant())
396404
{
397405
const auto init_size = init_type_as_bitvector->get_width();
398-
const irep_idt init_value = to_constant_expr(init_byte_expr).get_value();
406+
const irep_idt init_value =
407+
to_constant_expr(simplified_init_expr).get_value();
399408

400409
// Create a new BV of `output_type` size with its representation being the
401-
// replication of the init_byte_expr (padded with 0) enough times to fill.
410+
// replication of the simplified_init_expr (padded with 0) enough times to
411+
// fill.
402412
const auto output_value =
403413
make_bvrep(out_width, [&init_size, &init_value](std::size_t index) {
404414
// Index modded by 8 to access the i-th bit of init_value
@@ -427,7 +437,7 @@ exprt duplicate_per_byte(const exprt &init_byte_expr, const typet &output_type)
427437
{
428438
operation_type = unsignedbv_typet{float_type->get_width()};
429439
}
430-
// Let's cast init_byte_expr to output_type.
440+
// Let's cast simplified_init_expr to output_type.
431441
const exprt casted_init_byte_expr =
432442
typecast_exprt::conditional_cast(init_byte_expr, operation_type);
433443
values.push_back(casted_init_byte_expr);

src/util/expr_initializer.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ optionalt<exprt> expr_initializer(
3333
const namespacet &ns,
3434
const exprt &init_byte_expr);
3535

36-
exprt duplicate_per_byte(const exprt &init_byte_expr, const typet &output_type);
36+
exprt duplicate_per_byte(
37+
const exprt &init_byte_expr,
38+
const typet &output_type,
39+
const namespacet &ns);
3740

3841
#endif // CPROVER_UTIL_EXPR_INITIALIZER_H

0 commit comments

Comments
 (0)