Skip to content

Commit 235310a

Browse files
Use a for_each2 function iterating over two maps
Inside phi_function we can avoid a lot of lookups if we iterate over the two maps at the same time, since they are ordered.
1 parent 7f4aded commit 235310a

File tree

1 file changed

+52
-18
lines changed

1 file changed

+52
-18
lines changed

src/goto-symex/symex_goto.cpp

Lines changed: 52 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,39 @@ void goto_symext::merge_value_sets(
354354
dest.value_set.make_union(src.value_set);
355355
}
356356

357+
/// Applies f to `(k, ssa, i, j)` if the first map maps k to (ssa, i) and
358+
/// the second to (ssa', j). If the first map has an entry for k but not the
359+
/// second one then j is 0, and when the first map has no entry for k then i = 0
360+
static void for_each2(
361+
const std::map<irep_idt, std::pair<ssa_exprt, unsigned>> &first_map,
362+
const std::map<irep_idt, std::pair<ssa_exprt, unsigned>> &second_map,
363+
const std::function<void(const ssa_exprt &, unsigned, unsigned)> &f)
364+
{
365+
auto second_it = second_map.begin();
366+
for(const auto &first_pair : first_map)
367+
{
368+
while(second_it != second_map.end() && second_it->first < first_pair.first)
369+
{
370+
f(second_it->second.first, 0, second_it->second.second);
371+
++second_it;
372+
}
373+
const ssa_exprt &ssa = first_pair.second.first;
374+
const unsigned count = first_pair.second.second;
375+
if(second_it != second_map.end() && second_it->first == first_pair.first)
376+
{
377+
f(ssa, count, second_it->second.second);
378+
++second_it;
379+
}
380+
else
381+
f(ssa, count, 0);
382+
}
383+
while(second_it != second_map.end())
384+
{
385+
f(second_it->second.first, 0, second_it->second.second);
386+
++second_it;
387+
}
388+
}
389+
357390
/// Helper function for \c phi_function which merges the names of an identifier
358391
/// for two different states.
359392
/// \param goto_state: first state
@@ -366,7 +399,8 @@ void goto_symext::merge_value_sets(
366399
/// added to the target be simplified
367400
/// \param[out] target: equation that will receive the resulting assignment
368401
/// \param ssa: SSA expression to merge
369-
/// \param goto_count: current level 2 count in \p goto_state of \p l1_identifier
402+
/// \param goto_count: current level 2 count in \p goto_state of
403+
/// \p l1_identifier
370404
/// \param dest_count: level 2 count in \p dest_state of \p l1_identifier
371405
static void merge_names(
372406
const goto_symext::statet::goto_statet &goto_state,
@@ -509,23 +543,23 @@ void goto_symext::phi_function(
509543
// this gets the diff between the guards
510544
diff_guard -= dest_state.guard;
511545

512-
for(const auto &ssa : all_current_names_range)
513-
{
514-
const unsigned goto_count = goto_state.level2_current_count(l1_identifier);
515-
const unsigned dest_count = dest_state.level2.current_count(l1_identifier);
516-
merge_names(
517-
goto_state,
518-
dest_state,
519-
ns,
520-
diff_guard,
521-
guard_identifier,
522-
log,
523-
symex_config.simplify_opt,
524-
target,
525-
ssa,
526-
goto_count,
527-
dest_count);
528-
}
546+
for_each2(
547+
goto_state.level2_current_names,
548+
dest_state.level2.current_names,
549+
[&](const ssa_exprt &ssa, unsigned goto_count, unsigned dest_count) {
550+
merge_names(
551+
goto_state,
552+
dest_state,
553+
ns,
554+
diff_guard,
555+
guard_identifier,
556+
log,
557+
symex_config.simplify_opt,
558+
target,
559+
ssa,
560+
goto_count,
561+
dest_count);
562+
});
529563
}
530564

531565
void goto_symext::loop_bound_exceeded(

0 commit comments

Comments
 (0)