18
18
#include " config.h"
19
19
#include " magic.h"
20
20
#include " namespace.h" // IWYU pragma: keep
21
+ #include " simplify_expr.h"
21
22
#include " std_code.h"
22
23
#include " symbol_table.h"
23
24
@@ -68,7 +69,7 @@ optionalt<exprt> expr_initializert::expr_initializer_rec(
68
69
else if (init_expr.is_zero ())
69
70
result = from_integer (0 , type);
70
71
else
71
- result = duplicate_per_byte (init_expr, type);
72
+ result = duplicate_per_byte (init_expr, type, ns );
72
73
73
74
result.add_source_location ()=source_location;
74
75
return result;
@@ -82,7 +83,7 @@ optionalt<exprt> expr_initializert::expr_initializer_rec(
82
83
else if (init_expr.is_zero ())
83
84
result = constant_exprt (ID_0, type);
84
85
else
85
- result = duplicate_per_byte (init_expr, type);
86
+ result = duplicate_per_byte (init_expr, type, ns );
86
87
87
88
result.add_source_location ()=source_location;
88
89
return result;
@@ -101,7 +102,7 @@ optionalt<exprt> expr_initializert::expr_initializer_rec(
101
102
result = constant_exprt (value, type);
102
103
}
103
104
else
104
- result = duplicate_per_byte (init_expr, type);
105
+ result = duplicate_per_byte (init_expr, type, ns );
105
106
106
107
result.add_source_location ()=source_location;
107
108
return result;
@@ -121,7 +122,7 @@ optionalt<exprt> expr_initializert::expr_initializer_rec(
121
122
result = complex_exprt (*sub_zero, *sub_zero, to_complex_type (type));
122
123
}
123
124
else
124
- result = duplicate_per_byte (init_expr, type);
125
+ result = duplicate_per_byte (init_expr, type, ns );
125
126
126
127
result.add_source_location ()=source_location;
127
128
return result;
@@ -289,7 +290,7 @@ optionalt<exprt> expr_initializert::expr_initializer_rec(
289
290
else if (init_expr.is_zero ())
290
291
result = constant_exprt (irep_idt (), type);
291
292
else
292
- result = duplicate_per_byte (init_expr, type);
293
+ result = duplicate_per_byte (init_expr, type, ns );
293
294
294
295
result.add_source_location ()=source_location;
295
296
return result;
@@ -373,10 +374,14 @@ static exprt cast_or_reinterpret(const exprt &expr, const typet &out_type)
373
374
// / output type.
374
375
// / \param init_byte_expr The initialization expression
375
376
// / \param output_type The output type
377
+ // / \param ns Namespace to perform type symbol/tag lookups
376
378
// / \return The built expression
377
379
// / \note `init_byte_expr` must be a boolean or a bitvector and must be of at
378
380
// / 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)
380
385
{
381
386
const auto init_type_as_bitvector =
382
387
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)
385
390
(init_type_as_bitvector &&
386
391
init_type_as_bitvector->get_width () <= config.ansi_c .char_width ) ||
387
392
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);
388
396
if (const auto output_bv = type_try_dynamic_cast<bitvector_typet>(output_type))
389
397
{
390
398
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
392
400
// `output_type`.
393
401
394
402
// 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 ())
396
404
{
397
405
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 ();
399
408
400
409
// 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.
402
412
const auto output_value =
403
413
make_bvrep (out_width, [&init_size, &init_value](std::size_t index ) {
404
414
// 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)
427
437
{
428
438
operation_type = unsignedbv_typet{float_type->get_width ()};
429
439
}
430
- // Let's cast init_byte_expr to output_type.
440
+ // Let's cast simplified_init_expr to output_type.
431
441
const exprt casted_init_byte_expr =
432
442
typecast_exprt::conditional_cast (init_byte_expr, operation_type);
433
443
values.push_back (casted_init_byte_expr);
0 commit comments