Skip to content

Commit cd57249

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 02b6834 commit cd57249

File tree

2 files changed

+28
-10
lines changed

2 files changed

+28
-10
lines changed

src/goto-symex/field_sensitivity.cpp

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -97,14 +97,21 @@ 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+
to_array_type(index.array().type()).size().id() == ID_constant &&
102+
numeric_cast_v<mp_integer>(
103+
to_constant_expr(to_array_type(index.array().type()).size())) <=
104+
max_field_sensitive_array_size &&
105+
index.id() == ID_constant)
106+
{
107+
tmp.remove_level_2();
108+
index.array() = tmp.get_original_expr();
109+
tmp.set_expression(index);
110+
if(was_l2)
111+
return state.rename(std::move(tmp), ns).get();
112+
else
113+
return std::move(tmp);
114+
}
108115
}
109116
}
110117
#endif // ENABLE_ARRAY_FIELD_SENSITIVITY
@@ -147,7 +154,9 @@ exprt field_sensitivityt::get_fields(
147154
#ifdef ENABLE_ARRAY_FIELD_SENSITIVITY
148155
else if(
149156
ssa_expr.type().id() == ID_array &&
150-
to_array_type(ssa_expr.type()).size().id() == ID_constant)
157+
to_array_type(ssa_expr.type()).size().id() == ID_constant &&
158+
numeric_cast_v<mp_integer>(to_constant_expr(
159+
to_array_type(ssa_expr.type()).size())) <= max_field_sensitive_array_size)
151160
{
152161
const array_typet &type = to_array_type(ssa_expr.type());
153162
const std::size_t array_size =
@@ -269,6 +278,9 @@ void field_sensitivityt::field_assignments_rec(
269278
numeric_cast_v<std::size_t>(to_constant_expr(type->size()));
270279
PRECONDITION(lhs_fs.operands().size() == array_size);
271280

281+
if(array_size > max_field_sensitive_array_size)
282+
return;
283+
272284
exprt::operandst::const_iterator fs_it = lhs_fs.operands().begin();
273285
for(std::size_t i = 0; i < array_size; ++i)
274286
{
@@ -308,7 +320,9 @@ bool field_sensitivityt::is_divisible(const ssa_exprt &expr)
308320
#ifdef ENABLE_ARRAY_FIELD_SENSITIVITY
309321
if(
310322
expr.type().id() == ID_array &&
311-
to_array_type(expr.type()).size().id() == ID_constant)
323+
to_array_type(expr.type()).size().id() == ID_constant &&
324+
numeric_cast_v<mp_integer>(to_constant_expr(
325+
to_array_type(expr.type()).size())) <= max_field_sensitive_array_size)
312326
{
313327
return true;
314328
}

src/goto-symex/field_sensitivity.h

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

12+
/// Limit the size of arrays for which field_sensitivity gets applied.
13+
/// Necessary because large constant arrays slow-down the process.
14+
static constexpr unsigned max_field_sensitive_array_size = 64;
15+
1216
class exprt;
1317
class ssa_exprt;
1418
class namespacet;

0 commit comments

Comments
 (0)