@@ -18,6 +18,7 @@ Author: Daniel Kroening, kroening@kroening.com
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);
0 commit comments