Skip to content

Commit ec4c8ee

Browse files
committed
Do not sort operands as part of simplification
Data for ReachSafety-BitVectors, the smallest of SV-COMP's categories, running for at most 600s per benchmark: 163M sort_operands calls, contributing to 1B irept::operator< calls, resulting in 4.5B irept::compare calls. None of these calls are actually necessary. As part of this work, also clean up naming of "sort_and_join" functions (as most of them don't actually sort or join, but instead just prepare for doing so).
1 parent 610761e commit ec4c8ee

File tree

11 files changed

+52
-35
lines changed

11 files changed

+52
-35
lines changed

jbmc/regression/jbmc/throwing-function-return-value/test.desc

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ CORE
22
Test
33
--function Test.main --show-vcc
44
java::Test\.main:\(Z\)V::14::t1!0@1#\d+ = address_of\(symex_dynamic::dynamic_object\d+\)
5-
java::Test\.main:\(Z\)V::9::x!0@1#\d+ = 5 \+ java::Test\.main:\(Z\)V::9::x!0@1#\d+
5+
java::Test\.main:\(Z\)V::9::x!0@1#\d+ = java::Test\.main:\(Z\)V::9::x!0@1#\d+ \+ 5
66
java::Test\.g:\(\)I#return_value!0#[0-9]+ = 5
77
^EXIT=0$
88
^SIGNAL=0$

regression/cbmc-library/float-nan-check/test.desc

+14-13
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,21 @@ main.c
66
\[main.NaN.3\] line \d+ NaN on / in \(float\)n / myinf: FAILURE
77
\[main.NaN.4\] line \d+ NaN on \* in myinf \* myzero: FAILURE
88
\[main.NaN.5\] line \d+ NaN on \+ in -myinf \+ myinf: FAILURE
9-
\[main.NaN.6\] line \d+ NaN on - in myinf - myinf: FAILURE
10-
\[main.NaN.7\] line \d+ NaN on - in -myinf - -myinf: FAILURE
11-
\[main.NaN.8\] line \d+ NaN on \+ in byte_extract_little_endian\(c, (0|0l|0ll), float\) \+ byte_extract_little_endian\(c, (0|0l|0ll), float\): SUCCESS
12-
\[main.NaN.9\] line \d+ NaN on / in byte_extract_little_endian\(c, (0|0l|0ll), float\) / myzero: SUCCESS
13-
\[main.NaN.10\] line \d+ NaN on \* in mynan \* mynan: SUCCESS
14-
\[main.NaN.11\] line \d+ NaN on \+ in mynan \+ mynan: SUCCESS
15-
\[main.NaN.12\] line \d+ NaN on - in mynan - mynan: SUCCESS
16-
\[main.NaN.13\] line \d+ NaN on / in mynan / mynan: SUCCESS
17-
\[main.NaN.14\] line \d+ NaN on \+ in mynan \+ \(float\)n: SUCCESS
18-
\[main.NaN.15\] line \d+ NaN on - in mynan - \(float\)n: SUCCESS
19-
\[main.NaN.16\] line \d+ NaN on \* in mynan \* \(float\)n: SUCCESS
20-
\[main.NaN.17\] line \d+ NaN on / in mynan / \(float\)n: SUCCESS
9+
\[main.NaN.6\] line \d+ NaN on \+ in myinf \+ -myinf: FAILURE
10+
\[main.NaN.7\] line \d+ NaN on - in myinf - myinf: FAILURE
11+
\[main.NaN.8\] line \d+ NaN on - in -myinf - -myinf: FAILURE
12+
\[main.NaN.9\] line \d+ NaN on \+ in byte_extract_little_endian\(c, (0|0l|0ll), float\) \+ byte_extract_little_endian\(c, (0|0l|0ll), float\): SUCCESS
13+
\[main.NaN.10\] line \d+ NaN on / in byte_extract_little_endian\(c, (0|0l|0ll), float\) / myzero: SUCCESS
14+
\[main.NaN.11\] line \d+ NaN on \* in mynan \* mynan: SUCCESS
15+
\[main.NaN.12\] line \d+ NaN on \+ in mynan \+ mynan: SUCCESS
16+
\[main.NaN.13\] line \d+ NaN on - in mynan - mynan: SUCCESS
17+
\[main.NaN.14\] line \d+ NaN on / in mynan / mynan: SUCCESS
18+
\[main.NaN.15\] line \d+ NaN on \+ in mynan \+ \(float\)n: SUCCESS
19+
\[main.NaN.16\] line \d+ NaN on - in mynan - \(float\)n: SUCCESS
20+
\[main.NaN.17\] line \d+ NaN on \* in mynan \* \(float\)n: SUCCESS
21+
\[main.NaN.18\] line \d+ NaN on / in mynan / \(float\)n: SUCCESS
2122
^EXIT=10$
2223
^SIGNAL=0$
2324
^VERIFICATION FAILED$
2425
--
25-
\[main.NaN.18\]
26+
\[main.NaN.19\]

regression/cbmc/array-cell-sensitivity2/test.desc

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
CORE
22
test.c
33
--show-vcc
4-
main::1::array!0@1#2 = with\(main::1::array!0@1#1, cast\(-1 \+ main::argc!0@1#1, signedbv\[64\]\), 1\)
4+
main::1::array!0@1#2 = with\(main::1::array!0@1#1, cast\(main::argc!0@1#1 \+ -1, signedbv\[64\]\), 1\)
55
main::1::array!0@1#3 = with\(main::1::array!0@1#2, 1, main::argc!0@1#1\)
66
^EXIT=0$
77
^SIGNAL=0$

regression/cbmc/field-sensitivity1/test.desc

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ CORE
22
test.c
33
--show-vcc
44
main::1::a!0@1#2\.\.x = main::argc!0@1#1
5-
main::1::a!0@1#2\.\.y = 1 \+ main::argc!0@1#1
5+
main::1::a!0@1#2\.\.y = main::argc!0@1#1 \+ 1
66
^EXIT=0$
77
^SIGNAL=0$
88
--

regression/cbmc/field-sensitivity11/test.desc

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ CORE
22
test.c
33
--show-vcc
44
main::1::a1!0@1#2\.\.x = main::argc!0@1#1
5-
main::1::a1!0@1#2\.\.y = 1 \+ main::argc!0@1#1
5+
main::1::a1!0@1#2\.\.y = main::argc!0@1#1 \+ 1
66
main::1::a2!0@1#2\.\.x = main::1::a1!0@1#2\.\.x
77
main::1::a2!0@1#2\.\.y = main::1::a1!0@1#2\.\.y
88
^EXIT=0$

regression/cbmc/field-sensitivity12/test.desc

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ CORE
22
test.c
33
--show-vcc
44
main::1::a1!0@1#2\.\.x = main::argc!0@1#1
5-
main::1::a1!0@1#2\.\.y = 1 \+ main::argc!0@1#1
5+
main::1::a1!0@1#2\.\.y = main::argc!0@1#1 \+ 1
66
main::1::a1!0@1#3\.\.x = main::1::a1!0@1#2\.\.x
77
main::1::a1!0@1#3\.\.y = main::1::a1!0@1#2\.\.y
88
main::1::a2!0@1#2\.\.x =

regression/cbmc/field-sensitivity13/test.desc

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ CORE
22
test.c
33
--show-vcc
44
main::1::b1!0@1#2\.\.a\.\.x = main::argc!0@1#1
5-
main::1::b1!0@1#2\.\.a\.\.y = 1 \+ main::argc!0@1#1
5+
main::1::b1!0@1#2\.\.a\.\.y = main::argc!0@1#1 \+ 1
66
main::1::b1!0@1#3\.\.a\.\.x = main::1::b1!0@1#2\.\.a\.\.x
77
main::1::b1!0@1#3\.\.a\.\.y = main::1::b1!0@1#2\.\.a\.\.y
88
main::1::b2!0@1#2\.\.a\.\.x =

regression/goto-analyzer/constant_propagation_07/test.desc

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ main.c
33
--constants --simplify out.gb
44
^EXIT=0$
55
^SIGNAL=0$
6-
^Simplified: assert: 1, assume: 0, goto: 3, assigns: 13, function calls: 0$
7-
^Unmodified: assert: 0, assume: 0, goto: 1, assigns: 14, function calls: 2$
6+
^Simplified: assert: 1, assume: 0, goto: 3, assigns: 9, function calls: 0$
7+
^Unmodified: assert: 0, assume: 0, goto: 1, assigns: 18, function calls: 2$
88
--
99
^warning: ignoring

src/util/simplify_expr.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -2380,7 +2380,7 @@ simplify_exprt::resultt<> simplify_exprt::simplify_node(exprt node)
23802380
#endif
23812381

23822382
exprt expr = node;
2383-
bool no_change_sort_and_join = sort_and_join(expr);
2383+
bool no_change_join_operands = join_operands(expr);
23842384

23852385
resultt<> r = unchanged(expr);
23862386

@@ -2581,7 +2581,7 @@ simplify_exprt::resultt<> simplify_exprt::simplify_node(exprt node)
25812581
r = simplify_complex(to_unary_expr(expr));
25822582
}
25832583

2584-
if(!no_change_sort_and_join)
2584+
if(!no_change_join_operands)
25852585
r = changed(r);
25862586

25872587
#ifdef DEBUGX

src/util/simplify_utils.cpp

+26-12
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ struct saj_tablet
9595
{ irep_idt(), { irep_idt() }}
9696
};
9797

98-
static bool sort_and_join(
98+
static bool is_associative_and_commutative_for_type(
9999
const struct saj_tablet &saj_entry,
100100
const irep_idt &type_id)
101101
{
@@ -106,42 +106,44 @@ static bool sort_and_join(
106106
return false;
107107
}
108108

109-
static const struct saj_tablet &sort_and_join(
110-
const irep_idt &id,
111-
const irep_idt &type_id)
109+
static const struct saj_tablet &
110+
get_sort_and_join_table_entry(const irep_idt &id, const irep_idt &type_id)
112111
{
113112
unsigned i=0;
114113

115114
for( ; !saj_table[i].id.empty(); i++)
116-
if(id==saj_table[i].id &&
117-
sort_and_join(saj_table[i], type_id))
115+
{
116+
if(
117+
id == saj_table[i].id &&
118+
is_associative_and_commutative_for_type(saj_table[i], type_id))
118119
return saj_table[i];
120+
}
119121

120122
return saj_table[i];
121123
}
122124

123-
bool sort_and_join(exprt &expr)
125+
static bool sort_and_join(exprt &expr, bool do_sort)
124126
{
125127
bool no_change = true;
126128

127129
if(!expr.has_operands())
128130
return true;
129131

130132
const struct saj_tablet &saj_entry =
131-
sort_and_join(expr.id(), as_const(expr).type().id());
133+
get_sort_and_join_table_entry(expr.id(), as_const(expr).type().id());
132134
if(saj_entry.id.empty())
133135
return true;
134136

135137
// check operand types
136138

137139
forall_operands(it, expr)
138-
if(!sort_and_join(saj_entry, it->type().id()))
140+
if(!is_associative_and_commutative_for_type(saj_entry, it->type().id()))
139141
return true;
140142

141143
// join expressions
142144

143145
exprt::operandst new_ops;
144-
new_ops.reserve(expr.operands().size());
146+
new_ops.reserve(as_const(expr).operands().size());
145147

146148
forall_operands(it, expr)
147149
{
@@ -159,9 +161,21 @@ bool sort_and_join(exprt &expr)
159161
}
160162

161163
// sort it
164+
if(do_sort)
165+
no_change = sort_operands(new_ops) && no_change;
162166

163-
no_change = sort_operands(new_ops) && no_change;
164-
expr.operands().swap(new_ops);
167+
if(!no_change)
168+
expr.operands().swap(new_ops);
165169

166170
return no_change;
167171
}
172+
173+
bool sort_and_join(exprt &expr)
174+
{
175+
return sort_and_join(expr, true);
176+
}
177+
178+
bool join_operands(exprt &expr)
179+
{
180+
return sort_and_join(expr, false);
181+
}

src/util/simplify_utils.h

+2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ Author: Daniel Kroening, [email protected]
1414

1515
bool sort_operands(exprt::operandst &operands);
1616

17+
bool join_operands(exprt &expr);
18+
1719
bool sort_and_join(exprt &expr);
1820

1921
#endif // CPROVER_UTIL_SIMPLIFY_UTILS_H

0 commit comments

Comments
 (0)