Skip to content

Commit bd26a59

Browse files
committed
merge_value_sets: Avoid assignment when actually values can be moved
We don't need the contents of the source anymore. Running on SV-COMP's ReachSafety-ECA, this saves 741s, which is approximately 9% of the runtime of goto_symext::merge_goto.
1 parent ad12238 commit bd26a59

File tree

5 files changed

+25
-21
lines changed

5 files changed

+25
-21
lines changed

src/goto-checker/symex_bmc.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,12 +86,12 @@ void symex_bmct::symex_step(
8686
}
8787
}
8888

89-
void symex_bmct::merge_goto(const goto_statet &goto_state, statet &state)
89+
void symex_bmct::merge_goto(goto_statet &&goto_state, statet &state)
9090
{
9191
const goto_programt::const_targett prev_pc = goto_state.source.pc;
9292
const guardt prev_guard = goto_state.guard;
9393

94-
goto_symext::merge_goto(goto_state, state);
94+
goto_symext::merge_goto(std::move(goto_state), state);
9595

9696
PRECONDITION(prev_pc->is_goto());
9797
if(

src/goto-checker/symex_bmc.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ class symex_bmct : public goto_symext
9494
void symex_step(const get_goto_functiont &get_goto_function, statet &state)
9595
override;
9696

97-
void merge_goto(const goto_statet &goto_state, statet &state) override;
97+
void merge_goto(goto_statet &&goto_state, statet &state) override;
9898

9999
bool should_stop_unwind(
100100
const symex_targett::sourcet &source,

src/goto-symex/goto_symex.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -232,12 +232,15 @@ class goto_symext
232232

233233
virtual void symex_assume(statet &, const exprt &cond);
234234

235-
// gotos
235+
/// Merge all branches joining at the current program point. Applies
236+
/// \ref merge_goto for each goto state (each of which corresponds to previous
237+
/// branch).
236238
void merge_gotos(statet &);
237239

238-
virtual void merge_goto(const goto_statet &goto_state, statet &);
239-
240-
void merge_value_sets(const goto_statet &goto_state, statet &dest);
240+
/// Merge a single branch, the symbolic state of which is held in \p
241+
/// goto_state, into the current overall symbolic state. \p goto_state is no
242+
/// longer expected to be valid afterwards.
243+
virtual void merge_goto(goto_statet &&goto_state, statet &);
241244

242245
void phi_function(const goto_statet &goto_state, statet &);
243246

src/goto-symex/symex_goto.cpp

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -312,13 +312,13 @@ void goto_symext::merge_gotos(statet &state)
312312

313313
for(auto list_it = state_list.rbegin(); list_it != state_list.rend();
314314
++list_it)
315-
merge_goto(*list_it, state);
315+
merge_goto(std::move(*list_it), state);
316316

317317
// clean up to save some memory
318318
frame.goto_state_map.erase(state_map_it);
319319
}
320320

321-
void goto_symext::merge_goto(const goto_statet &goto_state, statet &state)
321+
void goto_symext::merge_goto(goto_statet &&goto_state, statet &state)
322322
{
323323
// check atomic section
324324
if(state.atomic_section_id != goto_state.atomic_section_id)
@@ -329,7 +329,11 @@ void goto_symext::merge_goto(const goto_statet &goto_state, statet &state)
329329
// do SSA phi functions
330330
phi_function(goto_state, state);
331331

332-
merge_value_sets(goto_state, state);
332+
// merge value sets
333+
if(state.guard.is_false() && !goto_state.guard.is_false())
334+
state.value_set = std::move(goto_state.value_set);
335+
else if(!goto_state.guard.is_false())
336+
state.value_set.make_union(goto_state.value_set);
333337

334338
// adjust guard
335339
state.guard|=goto_state.guard;
@@ -338,17 +342,6 @@ void goto_symext::merge_goto(const goto_statet &goto_state, statet &state)
338342
state.depth=std::min(state.depth, goto_state.depth);
339343
}
340344

341-
void goto_symext::merge_value_sets(const goto_statet &src, statet &dest)
342-
{
343-
if(dest.guard.is_false())
344-
{
345-
dest.value_set=src.value_set;
346-
return;
347-
}
348-
349-
dest.value_set.make_union(src.value_set);
350-
}
351-
352345
/// Applies f to `(k, ssa, i, j)` if the first map maps k to (ssa, i) and
353346
/// the second to (ssa', j). If the first map has an entry for k but not the
354347
/// second one then j is 0, and when the first map has no entry for k then i = 0

src/pointer-analysis/value_set.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,14 @@ class value_sett
4747

4848
virtual ~value_sett() = default;
4949

50+
value_sett(const value_sett &other) = default;
51+
52+
value_sett &operator=(value_sett &&other)
53+
{
54+
values = std::move(other.values);
55+
return *this;
56+
}
57+
5058
static bool field_sensitive(const irep_idt &id, const typet &type);
5159

5260
/// Matches the location_number field of the instruction that corresponds

0 commit comments

Comments
 (0)