Skip to content

Commit 152ee69

Browse files
Set a limit size for array cell propagation
The use of field_sensitivity for arrays can be expensive for big arrays so we have to set a limit on the size of constant arrays which get processed. The value 64 was determined by changing the size of the array in the test regression/cbmc/variable-access-to-constant-array and reducing it until there was no significant difference in execution time between the versions of CBMC with and without array cell propagation. For the chosen value the execution time was around 0.05 second in both cases (for comparison with size 1024 the time with propagation was 0.5 sec, against 0.1 without).
1 parent a2e2748 commit 152ee69

File tree

3 files changed

+29
-10
lines changed

3 files changed

+29
-10
lines changed

src/goto-symex/field_sensitivity.cpp

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -97,14 +97,19 @@ exprt field_sensitivityt::apply(
9797
// SSA expression
9898
ssa_exprt tmp = to_ssa_expr(index.array());
9999
bool was_l2 = !tmp.get_level_2().empty();
100-
101-
tmp.remove_level_2();
102-
index.array() = tmp.get_original_expr();
103-
tmp.set_expression(index);
104-
if(was_l2)
105-
return state.rename(std::move(tmp), ns).get();
106-
else
107-
return std::move(tmp);
100+
if(
101+
l2_size.id() == ID_constant &&
102+
numeric_cast_v<mp_integer>(to_constant_expr(l2_size)) <=
103+
MAX_FIELD_SENSITIVITY_ARRAY_SIZE)
104+
{
105+
tmp.remove_level_2();
106+
index.array() = tmp.get_original_expr();
107+
tmp.set_expression(index);
108+
if(was_l2)
109+
return state.rename(std::move(tmp), ns).get();
110+
else
111+
return std::move(tmp);
112+
}
108113
}
109114
}
110115
#endif // ENABLE_ARRAY_FIELD_SENSITIVITY
@@ -147,7 +152,10 @@ exprt field_sensitivityt::get_fields(
147152
#ifdef ENABLE_ARRAY_FIELD_SENSITIVITY
148153
else if(
149154
ssa_expr.type().id() == ID_array &&
150-
to_array_type(ssa_expr.type()).size().id() == ID_constant)
155+
to_array_type(ssa_expr.type()).size().id() == ID_constant &&
156+
numeric_cast_v<mp_integer>(
157+
to_constant_expr(to_array_type(ssa_expr.type()).size())) <=
158+
MAX_FIELD_SENSITIVITY_ARRAY_SIZE)
151159
{
152160
const array_typet &type = to_array_type(ssa_expr.type());
153161
const std::size_t array_size =
@@ -269,6 +277,9 @@ void field_sensitivityt::field_assignments_rec(
269277
numeric_cast_v<std::size_t>(to_constant_expr(type->size()));
270278
PRECONDITION(lhs_fs.operands().size() == array_size);
271279

280+
if(array_size > MAX_FIELD_SENSITIVITY_ARRAY_SIZE)
281+
return;
282+
272283
exprt::operandst::const_iterator fs_it = lhs_fs.operands().begin();
273284
for(std::size_t i = 0; i < array_size; ++i)
274285
{
@@ -308,7 +319,9 @@ bool field_sensitivityt::is_divisible(const ssa_exprt &expr)
308319
#ifdef ENABLE_ARRAY_FIELD_SENSITIVITY
309320
if(
310321
expr.type().id() == ID_array &&
311-
to_array_type(expr.type()).size().id() == ID_constant)
322+
to_array_type(expr.type()).size().id() == ID_constant &&
323+
numeric_cast_v<mp_integer>(to_constant_expr(
324+
to_array_type(expr.type()).size())) <= MAX_FIELD_SENSITIVITY_ARRAY_SIZE)
312325
{
313326
return true;
314327
}

src/goto-symex/field_sensitivity.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ Author: Michael Tautschnig
99
#ifndef CPROVER_GOTO_SYMEX_FIELD_SENSITIVITY_H
1010
#define CPROVER_GOTO_SYMEX_FIELD_SENSITIVITY_H
1111

12+
#include <util/magic.h>
13+
1214
class exprt;
1315
class ssa_exprt;
1416
class namespacet;

src/util/magic.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,8 @@ const std::size_t MAX_CONCRETE_STRING_SIZE = 1 << 26;
1616
// The top end of the range of integers for which dstrings are precomputed
1717
constexpr std::size_t DSTRING_NUMBERS_MAX = 64;
1818

19+
/// Limit the size of arrays for which field_sensitivity gets applied.
20+
/// Necessary because large constant arrays slow-down the process.
21+
constexpr std::size_t MAX_FIELD_SENSITIVITY_ARRAY_SIZE = 64;
22+
1923
#endif

0 commit comments

Comments
 (0)