Skip to content

Commit 28d8e8f

Browse files
Use array comprehension for large byte_extract lowering
lower_byte_extract_array_vector expands byte_extract of an array type into an element-by-element array_exprt. For large arrays (e.g., char[100000] in a union), this creates N sub-expressions that are each recursively lowered and simplified, resulting in O(N^2) behavior. When the array size exceeds MAX_FLATTENED_ARRAY_SIZE (1000), use array_comprehension_exprt instead. This path already exists for arrays with non-constant size; now it is also used for large constant-size arrays. This reduces the lowering from O(N) expressions to O(1). Performance on union_large_array (char[100000] in a union): Before: >120s with --arrays-uf-always After: 2.3s with --arrays-uf-always Remove thorough-arrays-uf-always tag from union_large_array.desc since the test now completes in 2 seconds. Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
1 parent 7ff43f7 commit 28d8e8f

1 file changed

Lines changed: 8 additions & 1 deletion

File tree

src/util/lower_byte_operators.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ Author: Daniel Kroening, kroening@kroening.com
1212
#include "c_types.h"
1313
#include "endianness_map.h"
1414
#include "expr_util.h"
15+
#include "magic.h"
1516
#include "namespace.h"
1617
#include "narrow.h"
1718
#include "pointer_offset_size.h"
@@ -1112,7 +1113,13 @@ static exprt lower_byte_extract_array_vector(
11121113
else
11131114
num_elements = numeric_cast<std::size_t>(to_vector_type(src.type()).size());
11141115

1115-
if(num_elements.has_value())
1116+
// For large arrays, element-by-element expansion creates N expressions
1117+
// that are each recursively lowered and simplified, resulting in O(N^2)
1118+
// behaviour. Use array_comprehension_exprt (below) instead, which
1119+
// represents the same semantics with a single symbolic expression.
1120+
if(
1121+
num_elements.has_value() &&
1122+
(src.type().id() != ID_array || *num_elements <= MAX_FLATTENED_ARRAY_SIZE))
11161123
{
11171124
exprt::operandst operands;
11181125
operands.reserve(*num_elements);

0 commit comments

Comments
 (0)